From 3c503d6a4814061c4dea9e4439878bbf6ef18246 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Isabel=20Sch=C3=B6ps=20Thiel=20=40IsabelSchoepd?=
<155141998+IST-Github@users.noreply.github.com>
Date: Thu, 4 Jan 2024 04:33:29 +0100
Subject: [PATCH] Delete eth directory
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Isabel Schöps Thiel @IsabelSchoepd <155141998+IST-Github@users.noreply.github.com>
---
eth/api.go | 52 -
eth/api_admin.go | 143 -
eth/api_backend.go | 417 ---
eth/api_debug.go | 445 ---
eth/api_debug_test.go | 222 --
eth/api_miner.go | 85 -
eth/backend.go | 552 ---
eth/bloombits.go | 74 -
eth/catalyst/api.go | 837 -----
eth/catalyst/api_test.go | 1644 ---------
eth/catalyst/queue.go | 158 -
eth/catalyst/simulated_beacon.go | 272 --
eth/catalyst/simulated_beacon_api.go | 36 -
eth/catalyst/simulated_beacon_test.go | 141 -
eth/catalyst/tester.go | 97 -
eth/downloader/api.go | 166 -
eth/downloader/beacondevsync.go | 81 -
eth/downloader/beaconsync.go | 389 --
eth/downloader/downloader.go | 1844 ----------
eth/downloader/downloader_test.go | 1379 -------
eth/downloader/events.go | 25 -
eth/downloader/fetchers.go | 115 -
eth/downloader/fetchers_concurrent.go | 380 --
eth/downloader/fetchers_concurrent_bodies.go | 105 -
eth/downloader/fetchers_concurrent_headers.go | 97 -
.../fetchers_concurrent_receipts.go | 104 -
eth/downloader/metrics.go | 42 -
eth/downloader/modes.go | 74 -
eth/downloader/peer.go | 290 --
eth/downloader/queue.go | 956 -----
eth/downloader/queue_test.go | 474 ---
eth/downloader/resultstore.go | 195 -
eth/downloader/skeleton.go | 1232 -------
eth/downloader/skeleton_test.go | 975 -----
eth/downloader/statesync.go | 123 -
eth/downloader/testchain_test.go | 231 --
eth/ethconfig/config.go | 179 -
eth/ethconfig/gen_config.go | 268 --
eth/fetcher/block_fetcher.go | 939 -----
eth/fetcher/block_fetcher_test.go | 948 -----
eth/fetcher/tx_fetcher.go | 1003 -----
eth/fetcher/tx_fetcher_test.go | 2030 -----------
eth/filters/api.go | 609 ----
eth/filters/api_test.go | 185 -
eth/filters/bench_test.go | 189 -
eth/filters/filter.go | 422 ---
eth/filters/filter_system.go | 606 ----
eth/filters/filter_system_test.go | 977 -----
eth/filters/filter_test.go | 389 --
eth/gasestimator/gasestimator.go | 235 --
eth/gasprice/feehistory.go | 328 --
eth/gasprice/feehistory_test.go | 91 -
eth/gasprice/gasprice.go | 276 --
eth/gasprice/gasprice_test.go | 215 --
eth/handler.go | 692 ----
eth/handler_eth.go | 142 -
eth/handler_eth_test.go | 608 ----
eth/handler_snap.go | 50 -
eth/handler_test.go | 185 -
eth/peer.go | 59 -
eth/peerset.go | 260 --
eth/protocols/eth/broadcast.go | 206 --
eth/protocols/eth/discovery.go | 66 -
eth/protocols/eth/dispatcher.go | 253 --
eth/protocols/eth/handler.go | 232 --
eth/protocols/eth/handler_test.go | 504 ---
eth/protocols/eth/handlers.go | 501 ---
eth/protocols/eth/handshake.go | 133 -
eth/protocols/eth/handshake_test.go | 91 -
eth/protocols/eth/metrics.go | 81 -
eth/protocols/eth/peer.go | 505 ---
eth/protocols/eth/peer_test.go | 90 -
eth/protocols/eth/protocol.go | 364 --
eth/protocols/eth/protocol_test.go | 248 --
eth/protocols/eth/tracker.go | 26 -
eth/protocols/snap/discovery.go | 32 -
eth/protocols/snap/handler.go | 577 ---
eth/protocols/snap/handler_fuzzing_test.go | 162 -
eth/protocols/snap/metrics.go | 57 -
eth/protocols/snap/peer.go | 133 -
eth/protocols/snap/protocol.go | 218 --
eth/protocols/snap/range.go | 81 -
eth/protocols/snap/range_test.go | 143 -
eth/protocols/snap/sort_test.go | 101 -
eth/protocols/snap/sync.go | 3210 -----------------
eth/protocols/snap/sync_test.go | 1974 ----------
eth/protocols/snap/tracker.go | 26 -
eth/state_accessor.go | 259 --
eth/sync.go | 269 --
eth/sync_test.go | 96 -
eth/tracers/api.go | 1040 ------
eth/tracers/api_test.go | 997 -----
.../internal/tracetest/calltrace_test.go | 406 ---
.../internal/tracetest/flat_calltrace_test.go | 214 --
.../internal/tracetest/prestate_test.go | 151 -
.../testdata/call_tracer/create.json | 58 -
.../testdata/call_tracer/deep_calls.json | 409 ---
.../testdata/call_tracer/delegatecall.json | 97 -
.../inner_create_oog_outer_throw.json | 77 -
.../testdata/call_tracer/inner_instafail.json | 61 -
.../call_tracer/inner_revert_reason.json | 85 -
.../call_tracer/inner_throw_outer_revert.json | 81 -
.../call_tracer/inner_throw_outer_revert.md | 19 -
.../tracetest/testdata/call_tracer/oog.json | 60 -
.../testdata/call_tracer/revert.json | 58 -
.../testdata/call_tracer/revert_reason.json | 65 -
.../testdata/call_tracer/selfdestruct.json | 74 -
.../testdata/call_tracer/simple.json | 80 -
.../testdata/call_tracer/simple_onlytop.json | 72 -
.../tracetest/testdata/call_tracer/throw.json | 62 -
.../testdata/call_tracer_flat/big_slow.json | 64 -
.../callcode_precompiled_fail_hide.json | 74 -
.../callcode_precompiled_oog.json | 94 -
.../callcode_precompiled_throw.json | 90 -
.../testdata/call_tracer_flat/create.json | 67 -
.../testdata/call_tracer_flat/deep_calls.json | 635 ----
.../call_tracer_flat/delegatecall.json | 120 -
.../delegatecall_parent_value.json | 103 -
.../testdata/call_tracer_flat/gas.json | 95 -
.../call_tracer_flat/include_precompiled.json | 832 -----
.../inner_create_oog_outer_throw.json | 88 -
.../call_tracer_flat/inner_instafail.json | 72 -
.../inner_precompiled_wrong_gas.json | 219 --
.../inner_throw_outer_revert.json | 95 -
.../call_tracer_flat/nested_create.json | 94 -
.../nested_create2_action_gas.json | 94 -
.../nested_create_action_gas.json | 90 -
.../nested_create_inerror.json | 81 -
.../nested_pointer_issue.json | 189 -
.../testdata/call_tracer_flat/oog.json | 68 -
.../option_convert_parity_errors.json | 71 -
.../call_tracer_flat/result_output.json | 111 -
.../testdata/call_tracer_flat/revert.json | 68 -
.../call_tracer_flat/revert_reason.json | 74 -
.../call_tracer_flat/selfdestruct.json | 91 -
.../testdata/call_tracer_flat/simple.json | 97 -
.../call_tracer_flat/simple_onlytop.json | 100 -
.../skip_no_balance_error.json | 70 -
.../staticcall_precompiled.json | 83 -
.../testdata/call_tracer_flat/suicide.json | 92 -
.../testdata/call_tracer_flat/throw.json | 70 -
.../testdata/call_tracer_legacy/create.json | 58 -
.../call_tracer_legacy/deep_calls.json | 415 ---
.../call_tracer_legacy/delegatecall.json | 97 -
.../inner_create_oog_outer_throw.json | 77 -
.../call_tracer_legacy/inner_instafail.json | 72 -
.../inner_throw_outer_revert.json | 81 -
.../testdata/call_tracer_legacy/oog.json | 60 -
.../testdata/call_tracer_legacy/revert.json | 58 -
.../call_tracer_legacy/revert_reason.json | 64 -
.../call_tracer_legacy/selfdestruct.json | 73 -
.../testdata/call_tracer_legacy/simple.json | 78 -
.../testdata/call_tracer_legacy/throw.json | 62 -
.../call_tracer_withLog/calldata.json | 117 -
.../call_tracer_withLog/delegatecall.json | 413 ---
.../call_tracer_withLog/multi_contracts.json | 2327 ------------
.../call_tracer_withLog/multilogs.json | 580 ---
.../testdata/call_tracer_withLog/notopic.json | 288 --
.../testdata/call_tracer_withLog/simple.json | 85 -
.../call_tracer_withLog/tx_failed.json | 244 --
.../tx_partial_failed.json | 108 -
.../call_tracer_withLog/with_onlyTopCall.json | 89 -
.../create_existing_contract.json | 85 -
.../testdata/prestate_tracer/simple.json | 83 -
.../prestate_tracer_legacy/simple.json | 84 -
.../create.json | 102 -
.../create_failed.json | 94 -
.../create_suicide.json | 104 -
.../inner_create.json | 312 --
.../simple.json | 103 -
.../suicide.json | 107 -
eth/tracers/internal/tracetest/util.go | 72 -
eth/tracers/js/bigint.go | 20 -
eth/tracers/js/goja.go | 992 -----
.../internal/tracers/4byte_tracer_legacy.js | 86 -
.../js/internal/tracers/bigram_tracer.js | 47 -
.../js/internal/tracers/call_tracer_legacy.js | 250 --
.../js/internal/tracers/evmdis_tracer.js | 93 -
.../js/internal/tracers/noop_tracer_legacy.js | 29 -
.../js/internal/tracers/opcount_tracer.js | 32 -
.../tracers/prestate_tracer_legacy.js | 115 -
eth/tracers/js/internal/tracers/tracers.go | 59 -
.../js/internal/tracers/trigram_tracer.js | 49 -
.../js/internal/tracers/unigram_tracer.js | 41 -
eth/tracers/js/tracer_test.go | 319 --
eth/tracers/logger/access_list_tracer.go | 183 -
eth/tracers/logger/gen_structlog.go | 118 -
eth/tracers/logger/logger.go | 467 ---
eth/tracers/logger/logger_json.go | 102 -
eth/tracers/logger/logger_test.go | 107 -
eth/tracers/native/4byte.go | 132 -
eth/tracers/native/call.go | 289 --
eth/tracers/native/call_flat.go | 381 --
eth/tracers/native/gen_account_json.go | 56 -
eth/tracers/native/gen_callframe_json.go | 107 -
eth/tracers/native/gen_flatcallaction_json.go | 110 -
eth/tracers/native/gen_flatcallresult_json.go | 55 -
eth/tracers/native/mux.go | 138 -
eth/tracers/native/noop.go | 77 -
eth/tracers/native/prestate.go | 297 --
eth/tracers/tracers.go | 123 -
eth/tracers/tracers_test.go | 151 -
eth/tracers/tracker.go | 109 -
eth/tracers/tracker_test.go | 171 -
204 files changed, 57229 deletions(-)
delete mode 100644 eth/api.go
delete mode 100644 eth/api_admin.go
delete mode 100644 eth/api_backend.go
delete mode 100644 eth/api_debug.go
delete mode 100644 eth/api_debug_test.go
delete mode 100644 eth/api_miner.go
delete mode 100644 eth/backend.go
delete mode 100644 eth/bloombits.go
delete mode 100644 eth/catalyst/api.go
delete mode 100644 eth/catalyst/api_test.go
delete mode 100644 eth/catalyst/queue.go
delete mode 100644 eth/catalyst/simulated_beacon.go
delete mode 100644 eth/catalyst/simulated_beacon_api.go
delete mode 100644 eth/catalyst/simulated_beacon_test.go
delete mode 100644 eth/catalyst/tester.go
delete mode 100644 eth/downloader/api.go
delete mode 100644 eth/downloader/beacondevsync.go
delete mode 100644 eth/downloader/beaconsync.go
delete mode 100644 eth/downloader/downloader.go
delete mode 100644 eth/downloader/downloader_test.go
delete mode 100644 eth/downloader/events.go
delete mode 100644 eth/downloader/fetchers.go
delete mode 100644 eth/downloader/fetchers_concurrent.go
delete mode 100644 eth/downloader/fetchers_concurrent_bodies.go
delete mode 100644 eth/downloader/fetchers_concurrent_headers.go
delete mode 100644 eth/downloader/fetchers_concurrent_receipts.go
delete mode 100644 eth/downloader/metrics.go
delete mode 100644 eth/downloader/modes.go
delete mode 100644 eth/downloader/peer.go
delete mode 100644 eth/downloader/queue.go
delete mode 100644 eth/downloader/queue_test.go
delete mode 100644 eth/downloader/resultstore.go
delete mode 100644 eth/downloader/skeleton.go
delete mode 100644 eth/downloader/skeleton_test.go
delete mode 100644 eth/downloader/statesync.go
delete mode 100644 eth/downloader/testchain_test.go
delete mode 100644 eth/ethconfig/config.go
delete mode 100644 eth/ethconfig/gen_config.go
delete mode 100644 eth/fetcher/block_fetcher.go
delete mode 100644 eth/fetcher/block_fetcher_test.go
delete mode 100644 eth/fetcher/tx_fetcher.go
delete mode 100644 eth/fetcher/tx_fetcher_test.go
delete mode 100644 eth/filters/api.go
delete mode 100644 eth/filters/api_test.go
delete mode 100644 eth/filters/bench_test.go
delete mode 100644 eth/filters/filter.go
delete mode 100644 eth/filters/filter_system.go
delete mode 100644 eth/filters/filter_system_test.go
delete mode 100644 eth/filters/filter_test.go
delete mode 100644 eth/gasestimator/gasestimator.go
delete mode 100644 eth/gasprice/feehistory.go
delete mode 100644 eth/gasprice/feehistory_test.go
delete mode 100644 eth/gasprice/gasprice.go
delete mode 100644 eth/gasprice/gasprice_test.go
delete mode 100644 eth/handler.go
delete mode 100644 eth/handler_eth.go
delete mode 100644 eth/handler_eth_test.go
delete mode 100644 eth/handler_snap.go
delete mode 100644 eth/handler_test.go
delete mode 100644 eth/peer.go
delete mode 100644 eth/peerset.go
delete mode 100644 eth/protocols/eth/broadcast.go
delete mode 100644 eth/protocols/eth/discovery.go
delete mode 100644 eth/protocols/eth/dispatcher.go
delete mode 100644 eth/protocols/eth/handler.go
delete mode 100644 eth/protocols/eth/handler_test.go
delete mode 100644 eth/protocols/eth/handlers.go
delete mode 100644 eth/protocols/eth/handshake.go
delete mode 100644 eth/protocols/eth/handshake_test.go
delete mode 100644 eth/protocols/eth/metrics.go
delete mode 100644 eth/protocols/eth/peer.go
delete mode 100644 eth/protocols/eth/peer_test.go
delete mode 100644 eth/protocols/eth/protocol.go
delete mode 100644 eth/protocols/eth/protocol_test.go
delete mode 100644 eth/protocols/eth/tracker.go
delete mode 100644 eth/protocols/snap/discovery.go
delete mode 100644 eth/protocols/snap/handler.go
delete mode 100644 eth/protocols/snap/handler_fuzzing_test.go
delete mode 100644 eth/protocols/snap/metrics.go
delete mode 100644 eth/protocols/snap/peer.go
delete mode 100644 eth/protocols/snap/protocol.go
delete mode 100644 eth/protocols/snap/range.go
delete mode 100644 eth/protocols/snap/range_test.go
delete mode 100644 eth/protocols/snap/sort_test.go
delete mode 100644 eth/protocols/snap/sync.go
delete mode 100644 eth/protocols/snap/sync_test.go
delete mode 100644 eth/protocols/snap/tracker.go
delete mode 100644 eth/state_accessor.go
delete mode 100644 eth/sync.go
delete mode 100644 eth/sync_test.go
delete mode 100644 eth/tracers/api.go
delete mode 100644 eth/tracers/api_test.go
delete mode 100644 eth/tracers/internal/tracetest/calltrace_test.go
delete mode 100644 eth/tracers/internal/tracetest/flat_calltrace_test.go
delete mode 100644 eth/tracers/internal/tracetest/prestate_test.go
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/create.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.md
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/oog.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/revert.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/simple.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer/throw.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json
delete mode 100644 eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json
delete mode 100644 eth/tracers/internal/tracetest/util.go
delete mode 100644 eth/tracers/js/bigint.go
delete mode 100644 eth/tracers/js/goja.go
delete mode 100644 eth/tracers/js/internal/tracers/4byte_tracer_legacy.js
delete mode 100644 eth/tracers/js/internal/tracers/bigram_tracer.js
delete mode 100644 eth/tracers/js/internal/tracers/call_tracer_legacy.js
delete mode 100644 eth/tracers/js/internal/tracers/evmdis_tracer.js
delete mode 100644 eth/tracers/js/internal/tracers/noop_tracer_legacy.js
delete mode 100644 eth/tracers/js/internal/tracers/opcount_tracer.js
delete mode 100644 eth/tracers/js/internal/tracers/prestate_tracer_legacy.js
delete mode 100644 eth/tracers/js/internal/tracers/tracers.go
delete mode 100644 eth/tracers/js/internal/tracers/trigram_tracer.js
delete mode 100644 eth/tracers/js/internal/tracers/unigram_tracer.js
delete mode 100644 eth/tracers/js/tracer_test.go
delete mode 100644 eth/tracers/logger/access_list_tracer.go
delete mode 100644 eth/tracers/logger/gen_structlog.go
delete mode 100644 eth/tracers/logger/logger.go
delete mode 100644 eth/tracers/logger/logger_json.go
delete mode 100644 eth/tracers/logger/logger_test.go
delete mode 100644 eth/tracers/native/4byte.go
delete mode 100644 eth/tracers/native/call.go
delete mode 100644 eth/tracers/native/call_flat.go
delete mode 100644 eth/tracers/native/gen_account_json.go
delete mode 100644 eth/tracers/native/gen_callframe_json.go
delete mode 100644 eth/tracers/native/gen_flatcallaction_json.go
delete mode 100644 eth/tracers/native/gen_flatcallresult_json.go
delete mode 100644 eth/tracers/native/mux.go
delete mode 100644 eth/tracers/native/noop.go
delete mode 100644 eth/tracers/native/prestate.go
delete mode 100644 eth/tracers/tracers.go
delete mode 100644 eth/tracers/tracers_test.go
delete mode 100644 eth/tracers/tracker.go
delete mode 100644 eth/tracers/tracker_test.go
diff --git a/eth/api.go b/eth/api.go
deleted file mode 100644
index 44e934fd04..0000000000
--- a/eth/api.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2015 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 eth
-
-import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-// EthereumAPI provides an API to access Ethereum full node-related information.
-type EthereumAPI struct {
- e *Ethereum
-}
-
-// NewEthereumAPI creates a new Ethereum protocol API for full nodes.
-func NewEthereumAPI(e *Ethereum) *EthereumAPI {
- return &EthereumAPI{e}
-}
-
-// Etherbase is the address that mining rewards will be sent to.
-func (api *EthereumAPI) Etherbase() (common.Address, error) {
- return api.e.Etherbase()
-}
-
-// Coinbase is the address that mining rewards will be sent to (alias for Etherbase).
-func (api *EthereumAPI) Coinbase() (common.Address, error) {
- return api.Etherbase()
-}
-
-// Hashrate returns the POW hashrate.
-func (api *EthereumAPI) Hashrate() hexutil.Uint64 {
- return hexutil.Uint64(api.e.Miner().Hashrate())
-}
-
-// Mining returns an indication if this node is currently mining.
-func (api *EthereumAPI) Mining() bool {
- return api.e.IsMining()
-}
diff --git a/eth/api_admin.go b/eth/api_admin.go
deleted file mode 100644
index 4a3ccb84e8..0000000000
--- a/eth/api_admin.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2023 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 eth
-
-import (
- "compress/gzip"
- "errors"
- "fmt"
- "io"
- "os"
- "strings"
-
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// AdminAPI is the collection of Ethereum full node related APIs for node
-// administration.
-type AdminAPI struct {
- eth *Ethereum
-}
-
-// NewAdminAPI creates a new instance of AdminAPI.
-func NewAdminAPI(eth *Ethereum) *AdminAPI {
- return &AdminAPI{eth: eth}
-}
-
-// ExportChain exports the current blockchain into a local file,
-// or a range of blocks if first and last are non-nil.
-func (api *AdminAPI) ExportChain(file string, first *uint64, last *uint64) (bool, error) {
- if first == nil && last != nil {
- return false, errors.New("last cannot be specified without first")
- }
- if first != nil && last == nil {
- head := api.eth.BlockChain().CurrentHeader().Number.Uint64()
- last = &head
- }
- if _, err := os.Stat(file); err == nil {
- // File already exists. Allowing overwrite could be a DoS vector,
- // since the 'file' may point to arbitrary paths on the drive.
- return false, errors.New("location would overwrite an existing file")
- }
- // Make sure we can create the file to export into
- out, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
- if err != nil {
- return false, err
- }
- defer out.Close()
-
- var writer io.Writer = out
- if strings.HasSuffix(file, ".gz") {
- writer = gzip.NewWriter(writer)
- defer writer.(*gzip.Writer).Close()
- }
-
- // Export the blockchain
- if first != nil {
- if err := api.eth.BlockChain().ExportN(writer, *first, *last); err != nil {
- return false, err
- }
- } else if err := api.eth.BlockChain().Export(writer); err != nil {
- return false, err
- }
- return true, nil
-}
-
-func hasAllBlocks(chain *core.BlockChain, bs []*types.Block) bool {
- for _, b := range bs {
- if !chain.HasBlock(b.Hash(), b.NumberU64()) {
- return false
- }
- }
-
- return true
-}
-
-// ImportChain imports a blockchain from a local file.
-func (api *AdminAPI) ImportChain(file string) (bool, error) {
- // Make sure the can access the file to import
- in, err := os.Open(file)
- if err != nil {
- return false, err
- }
- defer in.Close()
-
- var reader io.Reader = in
- if strings.HasSuffix(file, ".gz") {
- if reader, err = gzip.NewReader(reader); err != nil {
- return false, err
- }
- }
-
- // Run actual the import in pre-configured batches
- stream := rlp.NewStream(reader, 0)
-
- blocks, index := make([]*types.Block, 0, 2500), 0
- for batch := 0; ; batch++ {
- // Load a batch of blocks from the input file
- for len(blocks) < cap(blocks) {
- block := new(types.Block)
- if err := stream.Decode(block); err == io.EOF {
- break
- } else if err != nil {
- return false, fmt.Errorf("block %d: failed to parse: %v", index, err)
- }
- // ignore the genesis block when importing blocks
- if block.NumberU64() == 0 {
- continue
- }
- blocks = append(blocks, block)
- index++
- }
- if len(blocks) == 0 {
- break
- }
-
- if hasAllBlocks(api.eth.BlockChain(), blocks) {
- blocks = blocks[:0]
- continue
- }
- // Import the batch and reset the buffer
- if _, err := api.eth.BlockChain().InsertChain(blocks); err != nil {
- return false, fmt.Errorf("batch %d: failed to insert: %v", batch, err)
- }
- blocks = blocks[:0]
- }
- return true, nil
-}
diff --git a/eth/api_backend.go b/eth/api_backend.go
deleted file mode 100644
index 84eb200095..0000000000
--- a/eth/api_backend.go
+++ /dev/null
@@ -1,417 +0,0 @@
-// Copyright 2015 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 eth
-
-import (
- "context"
- "errors"
- "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/rawdb"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/txpool"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/eth/tracers"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-// EthAPIBackend implements ethapi.Backend and tracers.Backend for full nodes
-type EthAPIBackend struct {
- extRPCEnabled bool
- allowUnprotectedTxs bool
- eth *Ethereum
- gpo *gasprice.Oracle
-}
-
-// ChainConfig returns the active chain configuration.
-func (b *EthAPIBackend) ChainConfig() *params.ChainConfig {
- return b.eth.blockchain.Config()
-}
-
-func (b *EthAPIBackend) CurrentBlock() *types.Header {
- return b.eth.blockchain.CurrentBlock()
-}
-
-func (b *EthAPIBackend) SetHead(number uint64) {
- b.eth.handler.downloader.Cancel()
- b.eth.blockchain.SetHead(number)
-}
-
-func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
- // Pending block is only known by the miner
- if number == rpc.PendingBlockNumber {
- block := b.eth.miner.PendingBlock()
- if block == nil {
- return nil, errors.New("pending block is not available")
- }
- return block.Header(), nil
- }
- // Otherwise resolve and return the block
- if number == rpc.LatestBlockNumber {
- return b.eth.blockchain.CurrentBlock(), nil
- }
- if number == rpc.FinalizedBlockNumber {
- block := b.eth.blockchain.CurrentFinalBlock()
- if block == nil {
- return nil, errors.New("finalized block not found")
- }
- return block, nil
- }
- if number == rpc.SafeBlockNumber {
- block := b.eth.blockchain.CurrentSafeBlock()
- if block == nil {
- return nil, errors.New("safe block not found")
- }
- return block, nil
- }
- return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil
-}
-
-func (b *EthAPIBackend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) {
- if blockNr, ok := blockNrOrHash.Number(); ok {
- return b.HeaderByNumber(ctx, blockNr)
- }
- if hash, ok := blockNrOrHash.Hash(); ok {
- header := b.eth.blockchain.GetHeaderByHash(hash)
- if header == nil {
- return nil, errors.New("header for hash not found")
- }
- if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash {
- return nil, errors.New("hash is not currently canonical")
- }
- return header, nil
- }
- return nil, errors.New("invalid arguments; neither block nor hash specified")
-}
-
-func (b *EthAPIBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
- return b.eth.blockchain.GetHeaderByHash(hash), nil
-}
-
-func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
- // Pending block is only known by the miner
- if number == rpc.PendingBlockNumber {
- block := b.eth.miner.PendingBlock()
- if block == nil {
- return nil, errors.New("pending block is not available")
- }
- return block, nil
- }
- // Otherwise resolve and return the block
- if number == rpc.LatestBlockNumber {
- header := b.eth.blockchain.CurrentBlock()
- return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
- }
- if number == rpc.FinalizedBlockNumber {
- header := b.eth.blockchain.CurrentFinalBlock()
- if header == nil {
- return nil, errors.New("finalized block not found")
- }
- return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
- }
- if number == rpc.SafeBlockNumber {
- header := b.eth.blockchain.CurrentSafeBlock()
- if header == nil {
- return nil, errors.New("safe block not found")
- }
- return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil
- }
- return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil
-}
-
-func (b *EthAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
- return b.eth.blockchain.GetBlockByHash(hash), nil
-}
-
-// GetBody returns body of a block. It does not resolve special block numbers.
-func (b *EthAPIBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
- if number < 0 || hash == (common.Hash{}) {
- return nil, errors.New("invalid arguments; expect hash and no special block numbers")
- }
- if body := b.eth.blockchain.GetBody(hash); body != nil {
- return body, nil
- }
- return nil, errors.New("block body not found")
-}
-
-func (b *EthAPIBackend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) {
- if blockNr, ok := blockNrOrHash.Number(); ok {
- return b.BlockByNumber(ctx, blockNr)
- }
- if hash, ok := blockNrOrHash.Hash(); ok {
- header := b.eth.blockchain.GetHeaderByHash(hash)
- if header == nil {
- return nil, errors.New("header for hash not found")
- }
- if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash {
- return nil, errors.New("hash is not currently canonical")
- }
- block := b.eth.blockchain.GetBlock(hash, header.Number.Uint64())
- if block == nil {
- return nil, errors.New("header found, but block body is missing")
- }
- return block, nil
- }
- return nil, errors.New("invalid arguments; neither block nor hash specified")
-}
-
-func (b *EthAPIBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
- return b.eth.miner.PendingBlockAndReceipts()
-}
-
-func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
- // Pending state is only known by the miner
- if number == rpc.PendingBlockNumber {
- block, state := b.eth.miner.Pending()
- if block == nil || state == nil {
- return nil, nil, errors.New("pending state is not available")
- }
- return state, block.Header(), nil
- }
- // Otherwise resolve the block number and return its state
- header, err := b.HeaderByNumber(ctx, number)
- if err != nil {
- return nil, nil, err
- }
- if header == nil {
- return nil, nil, errors.New("header not found")
- }
- stateDb, err := b.eth.BlockChain().StateAt(header.Root)
- if err != nil {
- return nil, nil, err
- }
- return stateDb, header, nil
-}
-
-func (b *EthAPIBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) {
- if blockNr, ok := blockNrOrHash.Number(); ok {
- return b.StateAndHeaderByNumber(ctx, blockNr)
- }
- if hash, ok := blockNrOrHash.Hash(); ok {
- header, err := b.HeaderByHash(ctx, hash)
- if err != nil {
- return nil, nil, err
- }
- if header == nil {
- return nil, nil, errors.New("header for hash not found")
- }
- if blockNrOrHash.RequireCanonical && b.eth.blockchain.GetCanonicalHash(header.Number.Uint64()) != hash {
- return nil, nil, errors.New("hash is not currently canonical")
- }
- stateDb, err := b.eth.BlockChain().StateAt(header.Root)
- if err != nil {
- return nil, nil, err
- }
- return stateDb, header, nil
- }
- return nil, nil, errors.New("invalid arguments; neither block nor hash specified")
-}
-
-func (b *EthAPIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
- return b.eth.blockchain.GetReceiptsByHash(hash), nil
-}
-
-func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
- return rawdb.ReadLogs(b.eth.chainDb, hash, number), nil
-}
-
-func (b *EthAPIBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {
- if header := b.eth.blockchain.GetHeaderByHash(hash); header != nil {
- return b.eth.blockchain.GetTd(hash, header.Number.Uint64())
- }
- return nil
-}
-
-func (b *EthAPIBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config, blockCtx *vm.BlockContext) *vm.EVM {
- if vmConfig == nil {
- vmConfig = b.eth.blockchain.GetVMConfig()
- }
- txContext := core.NewEVMTxContext(msg)
- var context vm.BlockContext
- if blockCtx != nil {
- context = *blockCtx
- } else {
- context = core.NewEVMBlockContext(header, b.eth.BlockChain(), nil)
- }
- return vm.NewEVM(context, txContext, state, b.eth.blockchain.Config(), *vmConfig)
-}
-
-func (b *EthAPIBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
- return b.eth.BlockChain().SubscribeRemovedLogsEvent(ch)
-}
-
-func (b *EthAPIBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
- return b.eth.miner.SubscribePendingLogs(ch)
-}
-
-func (b *EthAPIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
- return b.eth.BlockChain().SubscribeChainEvent(ch)
-}
-
-func (b *EthAPIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
- return b.eth.BlockChain().SubscribeChainHeadEvent(ch)
-}
-
-func (b *EthAPIBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription {
- return b.eth.BlockChain().SubscribeChainSideEvent(ch)
-}
-
-func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
- return b.eth.BlockChain().SubscribeLogsEvent(ch)
-}
-
-func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
- return b.eth.txPool.Add([]*types.Transaction{signedTx}, true, false)[0]
-}
-
-func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) {
- pending := b.eth.txPool.Pending(false)
- var txs types.Transactions
- for _, batch := range pending {
- for _, lazy := range batch {
- if tx := lazy.Resolve(); tx != nil {
- txs = append(txs, tx)
- }
- }
- }
- return txs, nil
-}
-
-func (b *EthAPIBackend) GetPoolTransaction(hash common.Hash) *types.Transaction {
- return b.eth.txPool.Get(hash)
-}
-
-func (b *EthAPIBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
- tx, blockHash, blockNumber, index := rawdb.ReadTransaction(b.eth.ChainDb(), txHash)
- return tx, blockHash, blockNumber, index, nil
-}
-
-func (b *EthAPIBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
- return b.eth.txPool.Nonce(addr), nil
-}
-
-func (b *EthAPIBackend) Stats() (runnable int, blocked int) {
- return b.eth.txPool.Stats()
-}
-
-func (b *EthAPIBackend) TxPoolContent() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) {
- return b.eth.txPool.Content()
-}
-
-func (b *EthAPIBackend) TxPoolContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) {
- return b.eth.txPool.ContentFrom(addr)
-}
-
-func (b *EthAPIBackend) TxPool() *txpool.TxPool {
- return b.eth.txPool
-}
-
-func (b *EthAPIBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
- return b.eth.txPool.SubscribeTransactions(ch, true)
-}
-
-func (b *EthAPIBackend) SyncProgress() ethereum.SyncProgress {
- return b.eth.Downloader().Progress()
-}
-
-func (b *EthAPIBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
- return b.gpo.SuggestTipCap(ctx)
-}
-
-func (b *EthAPIBackend) FeeHistory(ctx context.Context, blockCount uint64, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (firstBlock *big.Int, reward [][]*big.Int, baseFee []*big.Int, gasUsedRatio []float64, err error) {
- return b.gpo.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles)
-}
-
-func (b *EthAPIBackend) ChainDb() ethdb.Database {
- return b.eth.ChainDb()
-}
-
-func (b *EthAPIBackend) EventMux() *event.TypeMux {
- return b.eth.EventMux()
-}
-
-func (b *EthAPIBackend) AccountManager() *accounts.Manager {
- return b.eth.AccountManager()
-}
-
-func (b *EthAPIBackend) ExtRPCEnabled() bool {
- return b.extRPCEnabled
-}
-
-func (b *EthAPIBackend) UnprotectedAllowed() bool {
- return b.allowUnprotectedTxs
-}
-
-func (b *EthAPIBackend) RPCGasCap() uint64 {
- return b.eth.config.RPCGasCap
-}
-
-func (b *EthAPIBackend) RPCEVMTimeout() time.Duration {
- return b.eth.config.RPCEVMTimeout
-}
-
-func (b *EthAPIBackend) RPCTxFeeCap() float64 {
- return b.eth.config.RPCTxFeeCap
-}
-
-func (b *EthAPIBackend) BloomStatus() (uint64, uint64) {
- sections, _, _ := b.eth.bloomIndexer.Sections()
- return params.BloomBitsBlocks, sections
-}
-
-func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
- for i := 0; i < bloomFilterThreads; i++ {
- go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
- }
-}
-
-func (b *EthAPIBackend) Engine() consensus.Engine {
- return b.eth.engine
-}
-
-func (b *EthAPIBackend) CurrentHeader() *types.Header {
- return b.eth.blockchain.CurrentHeader()
-}
-
-func (b *EthAPIBackend) Miner() *miner.Miner {
- return b.eth.Miner()
-}
-
-func (b *EthAPIBackend) StartMining() error {
- return b.eth.StartMining()
-}
-
-func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, tracers.StateReleaseFunc, error) {
- return b.eth.stateAtBlock(ctx, block, reexec, base, readOnly, preferDisk)
-}
-
-func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
- return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
-}
diff --git a/eth/api_debug.go b/eth/api_debug.go
deleted file mode 100644
index 05010a3969..0000000000
--- a/eth/api_debug.go
+++ /dev/null
@@ -1,445 +0,0 @@
-// Copyright 2023 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 eth
-
-import (
- "context"
- "errors"
- "fmt"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "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/internal/ethapi"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-// DebugAPI is the collection of Ethereum full node APIs for debugging the
-// protocol.
-type DebugAPI struct {
- eth *Ethereum
-}
-
-// NewDebugAPI creates a new DebugAPI instance.
-func NewDebugAPI(eth *Ethereum) *DebugAPI {
- return &DebugAPI{eth: eth}
-}
-
-// DumpBlock retrieves the entire state of the database at a given block.
-func (api *DebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error) {
- opts := &state.DumpConfig{
- OnlyWithAddresses: true,
- Max: AccountRangeMaxResults, // Sanity limit over RPC
- }
- if blockNr == rpc.PendingBlockNumber {
- // If we're dumping the pending state, we need to request
- // both the pending block as well as the pending state from
- // the miner and operate on those
- _, stateDb := api.eth.miner.Pending()
- if stateDb == nil {
- return state.Dump{}, errors.New("pending state is not available")
- }
- return stateDb.RawDump(opts), nil
- }
- var header *types.Header
- switch blockNr {
- case rpc.LatestBlockNumber:
- header = api.eth.blockchain.CurrentBlock()
- case rpc.FinalizedBlockNumber:
- header = api.eth.blockchain.CurrentFinalBlock()
- case rpc.SafeBlockNumber:
- header = api.eth.blockchain.CurrentSafeBlock()
- default:
- block := api.eth.blockchain.GetBlockByNumber(uint64(blockNr))
- if block == nil {
- return state.Dump{}, fmt.Errorf("block #%d not found", blockNr)
- }
- header = block.Header()
- }
- if header == nil {
- return state.Dump{}, fmt.Errorf("block #%d not found", blockNr)
- }
- stateDb, err := api.eth.BlockChain().StateAt(header.Root)
- if err != nil {
- return state.Dump{}, err
- }
- return stateDb.RawDump(opts), nil
-}
-
-// Preimage is a debug API function that returns the preimage for a sha3 hash, if known.
-func (api *DebugAPI) Preimage(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
- if preimage := rawdb.ReadPreimage(api.eth.ChainDb(), hash); preimage != nil {
- return preimage, nil
- }
- return nil, errors.New("unknown preimage")
-}
-
-// BadBlockArgs represents the entries in the list returned when bad blocks are queried.
-type BadBlockArgs struct {
- Hash common.Hash `json:"hash"`
- Block map[string]interface{} `json:"block"`
- RLP string `json:"rlp"`
-}
-
-// GetBadBlocks returns a list of the last 'bad blocks' that the client has seen on the network
-// and returns them as a JSON list of block hashes.
-func (api *DebugAPI) GetBadBlocks(ctx context.Context) ([]*BadBlockArgs, error) {
- var (
- blocks = rawdb.ReadAllBadBlocks(api.eth.chainDb)
- results = make([]*BadBlockArgs, 0, len(blocks))
- )
- for _, block := range blocks {
- var (
- blockRlp string
- blockJSON map[string]interface{}
- )
- if rlpBytes, err := rlp.EncodeToBytes(block); err != nil {
- blockRlp = err.Error() // Hacky, but hey, it works
- } else {
- blockRlp = fmt.Sprintf("%#x", rlpBytes)
- }
- blockJSON = ethapi.RPCMarshalBlock(block, true, true, api.eth.APIBackend.ChainConfig())
- results = append(results, &BadBlockArgs{
- Hash: block.Hash(),
- RLP: blockRlp,
- Block: blockJSON,
- })
- }
- return results, nil
-}
-
-// AccountRangeMaxResults is the maximum number of results to be returned per call
-const AccountRangeMaxResults = 256
-
-// AccountRange enumerates all accounts in the given block and start point in paging request
-func (api *DebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, start hexutil.Bytes, maxResults int, nocode, nostorage, incompletes bool) (state.Dump, error) {
- var stateDb *state.StateDB
- var err error
-
- if number, ok := blockNrOrHash.Number(); ok {
- if number == rpc.PendingBlockNumber {
- // If we're dumping the pending state, we need to request
- // both the pending block as well as the pending state from
- // the miner and operate on those
- _, stateDb = api.eth.miner.Pending()
- if stateDb == nil {
- return state.Dump{}, errors.New("pending state is not available")
- }
- } else {
- var header *types.Header
- switch number {
- case rpc.LatestBlockNumber:
- header = api.eth.blockchain.CurrentBlock()
- case rpc.FinalizedBlockNumber:
- header = api.eth.blockchain.CurrentFinalBlock()
- case rpc.SafeBlockNumber:
- header = api.eth.blockchain.CurrentSafeBlock()
- default:
- block := api.eth.blockchain.GetBlockByNumber(uint64(number))
- if block == nil {
- return state.Dump{}, fmt.Errorf("block #%d not found", number)
- }
- header = block.Header()
- }
- if header == nil {
- return state.Dump{}, fmt.Errorf("block #%d not found", number)
- }
- stateDb, err = api.eth.BlockChain().StateAt(header.Root)
- if err != nil {
- return state.Dump{}, err
- }
- }
- } else if hash, ok := blockNrOrHash.Hash(); ok {
- block := api.eth.blockchain.GetBlockByHash(hash)
- if block == nil {
- return state.Dump{}, fmt.Errorf("block %s not found", hash.Hex())
- }
- stateDb, err = api.eth.BlockChain().StateAt(block.Root())
- if err != nil {
- return state.Dump{}, err
- }
- } else {
- return state.Dump{}, errors.New("either block number or block hash must be specified")
- }
-
- opts := &state.DumpConfig{
- SkipCode: nocode,
- SkipStorage: nostorage,
- OnlyWithAddresses: !incompletes,
- Start: start,
- Max: uint64(maxResults),
- }
- if maxResults > AccountRangeMaxResults || maxResults <= 0 {
- opts.Max = AccountRangeMaxResults
- }
- return stateDb.RawDump(opts), nil
-}
-
-// StorageRangeResult is the result of a debug_storageRangeAt API call.
-type StorageRangeResult struct {
- Storage storageMap `json:"storage"`
- NextKey *common.Hash `json:"nextKey"` // nil if Storage includes the last key in the trie.
-}
-
-type storageMap map[common.Hash]storageEntry
-
-type storageEntry struct {
- Key *common.Hash `json:"key"`
- Value common.Hash `json:"value"`
-}
-
-// StorageRangeAt returns the storage at the given block height and transaction index.
-func (api *DebugAPI) StorageRangeAt(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, txIndex int, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) {
- var block *types.Block
-
- block, err := api.eth.APIBackend.BlockByNumberOrHash(ctx, blockNrOrHash)
- if err != nil {
- return StorageRangeResult{}, err
- }
- if block == nil {
- return StorageRangeResult{}, fmt.Errorf("block %v not found", blockNrOrHash)
- }
- _, _, statedb, release, err := api.eth.stateAtTransaction(ctx, block, txIndex, 0)
- if err != nil {
- return StorageRangeResult{}, err
- }
- defer release()
-
- return storageRangeAt(statedb, block.Root(), contractAddress, keyStart, maxResult)
-}
-
-func storageRangeAt(statedb *state.StateDB, root common.Hash, address common.Address, start []byte, maxResult int) (StorageRangeResult, error) {
- storageRoot := statedb.GetStorageRoot(address)
- if storageRoot == types.EmptyRootHash || storageRoot == (common.Hash{}) {
- return StorageRangeResult{}, nil // empty storage
- }
- id := trie.StorageTrieID(root, crypto.Keccak256Hash(address.Bytes()), storageRoot)
- tr, err := trie.NewStateTrie(id, statedb.Database().TrieDB())
- if err != nil {
- return StorageRangeResult{}, err
- }
- trieIt, err := tr.NodeIterator(start)
- if err != nil {
- return StorageRangeResult{}, err
- }
- it := trie.NewIterator(trieIt)
- result := StorageRangeResult{Storage: storageMap{}}
- for i := 0; i < maxResult && it.Next(); i++ {
- _, content, _, err := rlp.Split(it.Value)
- if err != nil {
- return StorageRangeResult{}, err
- }
- e := storageEntry{Value: common.BytesToHash(content)}
- if preimage := tr.GetKey(it.Key); preimage != nil {
- preimage := common.BytesToHash(preimage)
- e.Key = &preimage
- }
- result.Storage[common.BytesToHash(it.Key)] = e
- }
- // Add the 'next key' so clients can continue downloading.
- if it.Next() {
- next := common.BytesToHash(it.Key)
- result.NextKey = &next
- }
- return result, nil
-}
-
-// GetModifiedAccountsByNumber returns all accounts that have changed between the
-// two blocks specified. A change is defined as a difference in nonce, balance,
-// code hash, or storage hash.
-//
-// With one parameter, returns the list of accounts modified in the specified block.
-func (api *DebugAPI) GetModifiedAccountsByNumber(startNum uint64, endNum *uint64) ([]common.Address, error) {
- var startBlock, endBlock *types.Block
-
- startBlock = api.eth.blockchain.GetBlockByNumber(startNum)
- if startBlock == nil {
- return nil, fmt.Errorf("start block %x not found", startNum)
- }
-
- if endNum == nil {
- endBlock = startBlock
- startBlock = api.eth.blockchain.GetBlockByHash(startBlock.ParentHash())
- if startBlock == nil {
- return nil, fmt.Errorf("block %x has no parent", endBlock.Number())
- }
- } else {
- endBlock = api.eth.blockchain.GetBlockByNumber(*endNum)
- if endBlock == nil {
- return nil, fmt.Errorf("end block %d not found", *endNum)
- }
- }
- return api.getModifiedAccounts(startBlock, endBlock)
-}
-
-// GetModifiedAccountsByHash returns all accounts that have changed between the
-// two blocks specified. A change is defined as a difference in nonce, balance,
-// code hash, or storage hash.
-//
-// With one parameter, returns the list of accounts modified in the specified block.
-func (api *DebugAPI) GetModifiedAccountsByHash(startHash common.Hash, endHash *common.Hash) ([]common.Address, error) {
- var startBlock, endBlock *types.Block
- startBlock = api.eth.blockchain.GetBlockByHash(startHash)
- if startBlock == nil {
- return nil, fmt.Errorf("start block %x not found", startHash)
- }
-
- if endHash == nil {
- endBlock = startBlock
- startBlock = api.eth.blockchain.GetBlockByHash(startBlock.ParentHash())
- if startBlock == nil {
- return nil, fmt.Errorf("block %x has no parent", endBlock.Number())
- }
- } else {
- endBlock = api.eth.blockchain.GetBlockByHash(*endHash)
- if endBlock == nil {
- return nil, fmt.Errorf("end block %x not found", *endHash)
- }
- }
- return api.getModifiedAccounts(startBlock, endBlock)
-}
-
-func (api *DebugAPI) getModifiedAccounts(startBlock, endBlock *types.Block) ([]common.Address, error) {
- if startBlock.Number().Uint64() >= endBlock.Number().Uint64() {
- return nil, fmt.Errorf("start block height (%d) must be less than end block height (%d)", startBlock.Number().Uint64(), endBlock.Number().Uint64())
- }
- triedb := api.eth.BlockChain().TrieDB()
-
- oldTrie, err := trie.NewStateTrie(trie.StateTrieID(startBlock.Root()), triedb)
- if err != nil {
- return nil, err
- }
- newTrie, err := trie.NewStateTrie(trie.StateTrieID(endBlock.Root()), triedb)
- if err != nil {
- return nil, err
- }
- oldIt, err := oldTrie.NodeIterator([]byte{})
- if err != nil {
- return nil, err
- }
- newIt, err := newTrie.NodeIterator([]byte{})
- if err != nil {
- return nil, err
- }
- diff, _ := trie.NewDifferenceIterator(oldIt, newIt)
- iter := trie.NewIterator(diff)
-
- var dirty []common.Address
- for iter.Next() {
- key := newTrie.GetKey(iter.Key)
- if key == nil {
- return nil, fmt.Errorf("no preimage found for hash %x", iter.Key)
- }
- dirty = append(dirty, common.BytesToAddress(key))
- }
- return dirty, nil
-}
-
-// GetAccessibleState returns the first number where the node has accessible
-// state on disk. Note this being the post-state of that block and the pre-state
-// of the next block.
-// The (from, to) parameters are the sequence of blocks to search, which can go
-// either forwards or backwards
-func (api *DebugAPI) GetAccessibleState(from, to rpc.BlockNumber) (uint64, error) {
- if api.eth.blockchain.TrieDB().Scheme() == rawdb.PathScheme {
- return 0, errors.New("state history is not yet available in path-based scheme")
- }
- db := api.eth.ChainDb()
- var pivot uint64
- if p := rawdb.ReadLastPivotNumber(db); p != nil {
- pivot = *p
- log.Info("Found fast-sync pivot marker", "number", pivot)
- }
- var resolveNum = func(num rpc.BlockNumber) (uint64, error) {
- // We don't have state for pending (-2), so treat it as latest
- if num.Int64() < 0 {
- block := api.eth.blockchain.CurrentBlock()
- if block == nil {
- return 0, errors.New("current block missing")
- }
- return block.Number.Uint64(), nil
- }
- return uint64(num.Int64()), nil
- }
- var (
- start uint64
- end uint64
- delta = int64(1)
- lastLog time.Time
- err error
- )
- if start, err = resolveNum(from); err != nil {
- return 0, err
- }
- if end, err = resolveNum(to); err != nil {
- return 0, err
- }
- if start == end {
- return 0, errors.New("from and to needs to be different")
- }
- if start > end {
- delta = -1
- }
- for i := int64(start); i != int64(end); i += delta {
- if time.Since(lastLog) > 8*time.Second {
- log.Info("Finding roots", "from", start, "to", end, "at", i)
- lastLog = time.Now()
- }
- if i < int64(pivot) {
- continue
- }
- h := api.eth.BlockChain().GetHeaderByNumber(uint64(i))
- if h == nil {
- return 0, fmt.Errorf("missing header %d", i)
- }
- if ok, _ := api.eth.ChainDb().Has(h.Root[:]); ok {
- return uint64(i), nil
- }
- }
- return 0, errors.New("no state found")
-}
-
-// SetTrieFlushInterval configures how often in-memory tries are persisted
-// to disk. The value is in terms of block processing time, not wall clock.
-// If the value is shorter than the block generation time, or even 0 or negative,
-// the node will flush trie after processing each block (effectively archive mode).
-func (api *DebugAPI) SetTrieFlushInterval(interval string) error {
- if api.eth.blockchain.TrieDB().Scheme() == rawdb.PathScheme {
- return errors.New("trie flush interval is undefined for path-based scheme")
- }
- t, err := time.ParseDuration(interval)
- if err != nil {
- return err
- }
- api.eth.blockchain.SetTrieFlushInterval(t)
- return nil
-}
-
-// GetTrieFlushInterval gets the current value of in-memory trie flush interval
-func (api *DebugAPI) GetTrieFlushInterval() (string, error) {
- if api.eth.blockchain.TrieDB().Scheme() == rawdb.PathScheme {
- return "", errors.New("trie flush interval is undefined for path-based scheme")
- }
- return api.eth.blockchain.GetTrieFlushInterval().String(), nil
-}
diff --git a/eth/api_debug_test.go b/eth/api_debug_test.go
deleted file mode 100644
index 184b90dd09..0000000000
--- a/eth/api_debug_test.go
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2017 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 eth
-
-import (
- "bytes"
- "fmt"
- "math/big"
- "reflect"
- "strings"
- "testing"
-
- "github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "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/trie"
- "golang.org/x/exp/slices"
-)
-
-var dumper = spew.ConfigState{Indent: " "}
-
-func accountRangeTest(t *testing.T, trie *state.Trie, statedb *state.StateDB, start common.Hash, requestedNum int, expectedNum int) state.Dump {
- result := statedb.RawDump(&state.DumpConfig{
- SkipCode: true,
- SkipStorage: true,
- OnlyWithAddresses: false,
- Start: start.Bytes(),
- Max: uint64(requestedNum),
- })
-
- if len(result.Accounts) != expectedNum {
- t.Fatalf("expected %d results, got %d", expectedNum, len(result.Accounts))
- }
- for addr, acc := range result.Accounts {
- if strings.HasSuffix(addr, "pre") || acc.Address == nil {
- t.Fatalf("account without prestate (address) returned: %v", addr)
- }
- if !statedb.Exist(*acc.Address) {
- t.Fatalf("account not found in state %s", acc.Address.Hex())
- }
- }
- return result
-}
-
-func TestAccountRange(t *testing.T) {
- t.Parallel()
-
- var (
- statedb = state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &trie.Config{Preimages: true})
- sdb, _ = state.New(types.EmptyRootHash, statedb, nil)
- addrs = [AccountRangeMaxResults * 2]common.Address{}
- m = map[common.Address]bool{}
- )
-
- for i := range addrs {
- hash := common.HexToHash(fmt.Sprintf("%x", i))
- addr := common.BytesToAddress(crypto.Keccak256Hash(hash.Bytes()).Bytes())
- addrs[i] = addr
- sdb.SetBalance(addrs[i], big.NewInt(1))
- if _, ok := m[addr]; ok {
- t.Fatalf("bad")
- } else {
- m[addr] = true
- }
- }
- root, _ := sdb.Commit(0, true)
- sdb, _ = state.New(root, statedb, nil)
-
- trie, err := statedb.OpenTrie(root)
- if err != nil {
- t.Fatal(err)
- }
- accountRangeTest(t, &trie, sdb, common.Hash{}, AccountRangeMaxResults/2, AccountRangeMaxResults/2)
- // test pagination
- firstResult := accountRangeTest(t, &trie, sdb, common.Hash{}, AccountRangeMaxResults, AccountRangeMaxResults)
- secondResult := accountRangeTest(t, &trie, sdb, common.BytesToHash(firstResult.Next), AccountRangeMaxResults, AccountRangeMaxResults)
-
- hList := make([]common.Hash, 0)
- for addr1, acc := range firstResult.Accounts {
- // If address is non-available, then it makes no sense to compare
- // them as they might be two different accounts.
- if acc.Address == nil {
- continue
- }
- if _, duplicate := secondResult.Accounts[addr1]; duplicate {
- t.Fatalf("pagination test failed: results should not overlap")
- }
- hList = append(hList, crypto.Keccak256Hash(acc.Address.Bytes()))
- }
- // Test to see if it's possible to recover from the middle of the previous
- // set and get an even split between the first and second sets.
- slices.SortFunc(hList, common.Hash.Cmp)
- middleH := hList[AccountRangeMaxResults/2]
- middleResult := accountRangeTest(t, &trie, sdb, middleH, AccountRangeMaxResults, AccountRangeMaxResults)
- missing, infirst, insecond := 0, 0, 0
- for h := range middleResult.Accounts {
- if _, ok := firstResult.Accounts[h]; ok {
- infirst++
- } else if _, ok := secondResult.Accounts[h]; ok {
- insecond++
- } else {
- missing++
- }
- }
- if missing != 0 {
- t.Fatalf("%d hashes in the 'middle' set were neither in the first not the second set", missing)
- }
- if infirst != AccountRangeMaxResults/2 {
- t.Fatalf("Imbalance in the number of first-test results: %d != %d", infirst, AccountRangeMaxResults/2)
- }
- if insecond != AccountRangeMaxResults/2 {
- t.Fatalf("Imbalance in the number of second-test results: %d != %d", insecond, AccountRangeMaxResults/2)
- }
-}
-
-func TestEmptyAccountRange(t *testing.T) {
- t.Parallel()
-
- var (
- statedb = state.NewDatabase(rawdb.NewMemoryDatabase())
- st, _ = state.New(types.EmptyRootHash, statedb, nil)
- )
- // Commit(although nothing to flush) and re-init the statedb
- st.Commit(0, true)
- st, _ = state.New(types.EmptyRootHash, statedb, nil)
-
- results := st.RawDump(&state.DumpConfig{
- SkipCode: true,
- SkipStorage: true,
- OnlyWithAddresses: true,
- Max: uint64(AccountRangeMaxResults),
- })
- if bytes.Equal(results.Next, (common.Hash{}).Bytes()) {
- t.Fatalf("Empty results should not return a second page")
- }
- if len(results.Accounts) != 0 {
- t.Fatalf("Empty state should not return addresses: %v", results.Accounts)
- }
-}
-
-func TestStorageRangeAt(t *testing.T) {
- t.Parallel()
-
- // Create a state where account 0x010000... has a few storage entries.
- var (
- db = state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &trie.Config{Preimages: true})
- sdb, _ = state.New(types.EmptyRootHash, db, nil)
- addr = common.Address{0x01}
- keys = []common.Hash{ // hashes of Keys of storage
- common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"),
- common.HexToHash("426fcb404ab2d5d8e61a3d918108006bbb0a9be65e92235bb10eefbdb6dcd053"),
- common.HexToHash("48078cfed56339ea54962e72c37c7f588fc4f8e5bc173827ba75cb10a63a96a5"),
- common.HexToHash("5723d2c3a83af9b735e3b7f21531e5623d183a9095a56604ead41f3582fdfb75"),
- }
- storage = storageMap{
- keys[0]: {Key: &common.Hash{0x02}, Value: common.Hash{0x01}},
- keys[1]: {Key: &common.Hash{0x04}, Value: common.Hash{0x02}},
- keys[2]: {Key: &common.Hash{0x01}, Value: common.Hash{0x03}},
- keys[3]: {Key: &common.Hash{0x03}, Value: common.Hash{0x04}},
- }
- )
- for _, entry := range storage {
- sdb.SetState(addr, *entry.Key, entry.Value)
- }
- root, _ := sdb.Commit(0, false)
- sdb, _ = state.New(root, db, nil)
-
- // Check a few combinations of limit and start/end.
- tests := []struct {
- start []byte
- limit int
- want StorageRangeResult
- }{
- {
- start: []byte{}, limit: 0,
- want: StorageRangeResult{storageMap{}, &keys[0]},
- },
- {
- start: []byte{}, limit: 100,
- want: StorageRangeResult{storage, nil},
- },
- {
- start: []byte{}, limit: 2,
- want: StorageRangeResult{storageMap{keys[0]: storage[keys[0]], keys[1]: storage[keys[1]]}, &keys[2]},
- },
- {
- start: []byte{0x00}, limit: 4,
- want: StorageRangeResult{storage, nil},
- },
- {
- start: []byte{0x40}, limit: 2,
- want: StorageRangeResult{storageMap{keys[1]: storage[keys[1]], keys[2]: storage[keys[2]]}, &keys[3]},
- },
- }
- for _, test := range tests {
- result, err := storageRangeAt(sdb, root, addr, test.start, test.limit)
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(result, test.want) {
- t.Fatalf("wrong result for range %#x.., limit %d:\ngot %s\nwant %s",
- test.start, test.limit, dumper.Sdump(result), dumper.Sdump(&test.want))
- }
- }
-}
diff --git a/eth/api_miner.go b/eth/api_miner.go
deleted file mode 100644
index 477531d494..0000000000
--- a/eth/api_miner.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2023 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 eth
-
-import (
- "math/big"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-// MinerAPI provides an API to control the miner.
-type MinerAPI struct {
- e *Ethereum
-}
-
-// NewMinerAPI create a new MinerAPI instance.
-func NewMinerAPI(e *Ethereum) *MinerAPI {
- return &MinerAPI{e}
-}
-
-// Start starts the miner with the given number of threads. If threads is nil,
-// the number of workers started is equal to the number of logical CPUs that are
-// usable by this process. If mining is already running, this method adjust the
-// number of threads allowed to use and updates the minimum price required by the
-// transaction pool.
-func (api *MinerAPI) Start() error {
- return api.e.StartMining()
-}
-
-// Stop terminates the miner, both at the consensus engine level as well as at
-// the block creation level.
-func (api *MinerAPI) Stop() {
- api.e.StopMining()
-}
-
-// SetExtra sets the extra data string that is included when this miner mines a block.
-func (api *MinerAPI) SetExtra(extra string) (bool, error) {
- if err := api.e.Miner().SetExtra([]byte(extra)); err != nil {
- return false, err
- }
- return true, nil
-}
-
-// SetGasPrice sets the minimum accepted gas price for the miner.
-func (api *MinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
- api.e.lock.Lock()
- api.e.gasPrice = (*big.Int)(&gasPrice)
- api.e.lock.Unlock()
-
- api.e.txPool.SetGasTip((*big.Int)(&gasPrice))
- return true
-}
-
-// SetGasLimit sets the gaslimit to target towards during mining.
-func (api *MinerAPI) SetGasLimit(gasLimit hexutil.Uint64) bool {
- api.e.Miner().SetGasCeil(uint64(gasLimit))
- return true
-}
-
-// SetEtherbase sets the etherbase of the miner.
-func (api *MinerAPI) SetEtherbase(etherbase common.Address) bool {
- api.e.SetEtherbase(etherbase)
- return true
-}
-
-// SetRecommitInterval updates the interval for miner sealing work recommitting.
-func (api *MinerAPI) SetRecommitInterval(interval int) {
- api.e.Miner().SetRecommitInterval(time.Duration(interval) * time.Millisecond)
-}
diff --git a/eth/backend.go b/eth/backend.go
deleted file mode 100644
index 774ffaf248..0000000000
--- a/eth/backend.go
+++ /dev/null
@@ -1,552 +0,0 @@
-// Copyright 2014 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 eth implements the Ethereum protocol.
-package eth
-
-import (
- "errors"
- "fmt"
- "math/big"
- "runtime"
- "sync"
-
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/beacon"
- "github.com/ethereum/go-ethereum/consensus/clique"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/state/pruner"
- "github.com/ethereum/go-ethereum/core/txpool"
- "github.com/ethereum/go-ethereum/core/txpool/blobpool"
- "github.com/ethereum/go-ethereum/core/txpool/legacypool"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/ethconfig"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/eth/protocols/snap"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/internal/shutdowncheck"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/dnsdisc"
- "github.com/ethereum/go-ethereum/p2p/enode"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-// Config contains the configuration options of the ETH protocol.
-// Deprecated: use ethconfig.Config instead.
-type Config = ethconfig.Config
-
-// Ethereum implements the Ethereum full node service.
-type Ethereum struct {
- config *ethconfig.Config
-
- // Handlers
- txPool *txpool.TxPool
-
- blockchain *core.BlockChain
- handler *handler
- ethDialCandidates enode.Iterator
- snapDialCandidates enode.Iterator
- merger *consensus.Merger
-
- // DB interfaces
- chainDb ethdb.Database // Block chain database
-
- eventMux *event.TypeMux
- engine consensus.Engine
- accountManager *accounts.Manager
-
- bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
- bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
- closeBloomHandler chan struct{}
-
- APIBackend *EthAPIBackend
-
- miner *miner.Miner
- gasPrice *big.Int
- etherbase common.Address
-
- networkID uint64
- netRPCService *ethapi.NetAPI
-
- p2pServer *p2p.Server
-
- lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)
-
- shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully
-}
-
-// New creates a new Ethereum object (including the
-// initialisation of the common Ethereum object)
-func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
- // Ensure configuration values are compatible and sane
- if config.SyncMode == downloader.LightSync {
- return nil, errors.New("can't run eth.Ethereum in light sync mode, light mode has been deprecated")
- }
- if !config.SyncMode.IsValid() {
- return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode)
- }
- if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(common.Big0) <= 0 {
- log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", ethconfig.Defaults.Miner.GasPrice)
- config.Miner.GasPrice = new(big.Int).Set(ethconfig.Defaults.Miner.GasPrice)
- }
- if config.NoPruning && config.TrieDirtyCache > 0 {
- if config.SnapshotCache > 0 {
- config.TrieCleanCache += config.TrieDirtyCache * 3 / 5
- config.SnapshotCache += config.TrieDirtyCache * 2 / 5
- } else {
- config.TrieCleanCache += config.TrieDirtyCache
- }
- config.TrieDirtyCache = 0
- }
- log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024)
-
- // Assemble the Ethereum object
- chainDb, err := stack.OpenDatabaseWithFreezer("chaindata", config.DatabaseCache, config.DatabaseHandles, config.DatabaseFreezer, "eth/db/chaindata/", false)
- if err != nil {
- return nil, err
- }
- scheme, err := rawdb.ParseStateScheme(config.StateScheme, chainDb)
- if err != nil {
- return nil, err
- }
- // Try to recover offline state pruning only in hash-based.
- if scheme == rawdb.HashScheme {
- if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb); err != nil {
- log.Error("Failed to recover state", "error", err)
- }
- }
- // Transfer mining-related config to the ethash config.
- chainConfig, err := core.LoadChainConfig(chainDb, config.Genesis)
- if err != nil {
- return nil, err
- }
- engine, err := ethconfig.CreateConsensusEngine(chainConfig, chainDb)
- if err != nil {
- return nil, err
- }
- networkID := config.NetworkId
- if networkID == 0 {
- networkID = chainConfig.ChainID.Uint64()
- }
- eth := &Ethereum{
- config: config,
- merger: consensus.NewMerger(chainDb),
- chainDb: chainDb,
- eventMux: stack.EventMux(),
- accountManager: stack.AccountManager(),
- engine: engine,
- closeBloomHandler: make(chan struct{}),
- networkID: networkID,
- gasPrice: config.Miner.GasPrice,
- etherbase: config.Miner.Etherbase,
- bloomRequests: make(chan chan *bloombits.Retrieval),
- bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
- p2pServer: stack.Server(),
- shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb),
- }
- bcVersion := rawdb.ReadDatabaseVersion(chainDb)
- var dbVer = ""
- if bcVersion != nil {
- dbVer = fmt.Sprintf("%d", *bcVersion)
- }
- log.Info("Initialising Ethereum protocol", "network", networkID, "dbversion", dbVer)
-
- if !config.SkipBcVersionCheck {
- if bcVersion != nil && *bcVersion > core.BlockChainVersion {
- return nil, fmt.Errorf("database version is v%d, Geth %s only supports v%d", *bcVersion, params.VersionWithMeta, core.BlockChainVersion)
- } else if bcVersion == nil || *bcVersion < core.BlockChainVersion {
- if bcVersion != nil { // only print warning on upgrade, not on init
- log.Warn("Upgrade blockchain database version", "from", dbVer, "to", core.BlockChainVersion)
- }
- rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion)
- }
- }
- var (
- vmConfig = vm.Config{
- EnablePreimageRecording: config.EnablePreimageRecording,
- }
- cacheConfig = &core.CacheConfig{
- TrieCleanLimit: config.TrieCleanCache,
- TrieCleanNoPrefetch: config.NoPrefetch,
- TrieDirtyLimit: config.TrieDirtyCache,
- TrieDirtyDisabled: config.NoPruning,
- TrieTimeLimit: config.TrieTimeout,
- SnapshotLimit: config.SnapshotCache,
- Preimages: config.Preimages,
- StateHistory: config.StateHistory,
- StateScheme: scheme,
- }
- )
- // Override the chain config with provided settings.
- var overrides core.ChainOverrides
- if config.OverrideCancun != nil {
- overrides.OverrideCancun = config.OverrideCancun
- }
- if config.OverrideVerkle != nil {
- overrides.OverrideVerkle = config.OverrideVerkle
- }
- eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TransactionHistory)
- if err != nil {
- return nil, err
- }
- eth.bloomIndexer.Start(eth.blockchain)
-
- if config.BlobPool.Datadir != "" {
- config.BlobPool.Datadir = stack.ResolvePath(config.BlobPool.Datadir)
- }
- blobPool := blobpool.New(config.BlobPool, eth.blockchain)
-
- if config.TxPool.Journal != "" {
- config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
- }
- legacyPool := legacypool.New(config.TxPool, eth.blockchain)
-
- eth.txPool, err = txpool.New(new(big.Int).SetUint64(config.TxPool.PriceLimit), eth.blockchain, []txpool.SubPool{legacyPool, blobPool})
- if err != nil {
- return nil, err
- }
- // Permit the downloader to use the trie cache allowance during fast sync
- cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit
- if eth.handler, err = newHandler(&handlerConfig{
- Database: chainDb,
- Chain: eth.blockchain,
- TxPool: eth.txPool,
- Merger: eth.merger,
- Network: networkID,
- Sync: config.SyncMode,
- BloomCache: uint64(cacheLimit),
- EventMux: eth.eventMux,
- RequiredBlocks: config.RequiredBlocks,
- }); err != nil {
- return nil, err
- }
-
- eth.miner = miner.New(eth, &config.Miner, eth.blockchain.Config(), eth.EventMux(), eth.engine, eth.isLocalBlock)
- eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData))
-
- eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil}
- if eth.APIBackend.allowUnprotectedTxs {
- log.Info("Unprotected transactions allowed")
- }
- gpoParams := config.GPO
- if gpoParams.Default == nil {
- gpoParams.Default = config.Miner.GasPrice
- }
- eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams)
-
- // Setup DNS discovery iterators.
- dnsclient := dnsdisc.NewClient(dnsdisc.Config{})
- eth.ethDialCandidates, err = dnsclient.NewIterator(eth.config.EthDiscoveryURLs...)
- if err != nil {
- return nil, err
- }
- eth.snapDialCandidates, err = dnsclient.NewIterator(eth.config.SnapDiscoveryURLs...)
- if err != nil {
- return nil, err
- }
-
- // Start the RPC service
- eth.netRPCService = ethapi.NewNetAPI(eth.p2pServer, networkID)
-
- // Register the backend on the node
- stack.RegisterAPIs(eth.APIs())
- stack.RegisterProtocols(eth.Protocols())
- stack.RegisterLifecycle(eth)
-
- // Successful startup; push a marker and check previous unclean shutdowns.
- eth.shutdownTracker.MarkStartup()
-
- return eth, nil
-}
-
-func makeExtraData(extra []byte) []byte {
- if len(extra) == 0 {
- // create default extradata
- extra, _ = rlp.EncodeToBytes([]interface{}{
- uint(params.VersionMajor<<16 | params.VersionMinor<<8 | params.VersionPatch),
- "geth",
- runtime.Version(),
- runtime.GOOS,
- })
- }
- if uint64(len(extra)) > params.MaximumExtraDataSize {
- log.Warn("Miner extra data exceed limit", "extra", hexutil.Bytes(extra), "limit", params.MaximumExtraDataSize)
- extra = nil
- }
- return extra
-}
-
-// APIs return the collection of RPC services the ethereum package offers.
-// NOTE, some of these services probably need to be moved to somewhere else.
-func (s *Ethereum) APIs() []rpc.API {
- apis := ethapi.GetAPIs(s.APIBackend)
-
- // Append any APIs exposed explicitly by the consensus engine
- apis = append(apis, s.engine.APIs(s.BlockChain())...)
-
- // Append all the local APIs and return
- return append(apis, []rpc.API{
- {
- Namespace: "eth",
- Service: NewEthereumAPI(s),
- }, {
- Namespace: "miner",
- Service: NewMinerAPI(s),
- }, {
- Namespace: "eth",
- Service: downloader.NewDownloaderAPI(s.handler.downloader, s.eventMux),
- }, {
- Namespace: "admin",
- Service: NewAdminAPI(s),
- }, {
- Namespace: "debug",
- Service: NewDebugAPI(s),
- }, {
- Namespace: "net",
- Service: s.netRPCService,
- },
- }...)
-}
-
-func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {
- s.blockchain.ResetWithGenesisBlock(gb)
-}
-
-func (s *Ethereum) Etherbase() (eb common.Address, err error) {
- s.lock.RLock()
- etherbase := s.etherbase
- s.lock.RUnlock()
-
- if etherbase != (common.Address{}) {
- return etherbase, nil
- }
- return common.Address{}, errors.New("etherbase must be explicitly specified")
-}
-
-// isLocalBlock checks whether the specified block is mined
-// by local miner accounts.
-//
-// We regard two types of accounts as local miner account: etherbase
-// and accounts specified via `txpool.locals` flag.
-func (s *Ethereum) isLocalBlock(header *types.Header) bool {
- author, err := s.engine.Author(header)
- if err != nil {
- log.Warn("Failed to retrieve block author", "number", header.Number.Uint64(), "hash", header.Hash(), "err", err)
- return false
- }
- // Check whether the given address is etherbase.
- s.lock.RLock()
- etherbase := s.etherbase
- s.lock.RUnlock()
- if author == etherbase {
- return true
- }
- // Check whether the given address is specified by `txpool.local`
- // CLI flag.
- for _, account := range s.config.TxPool.Locals {
- if account == author {
- return true
- }
- }
- return false
-}
-
-// shouldPreserve checks whether we should preserve the given block
-// during the chain reorg depending on whether the author of block
-// is a local account.
-func (s *Ethereum) shouldPreserve(header *types.Header) bool {
- // The reason we need to disable the self-reorg preserving for clique
- // is it can be probable to introduce a deadlock.
- //
- // e.g. If there are 7 available signers
- //
- // r1 A
- // r2 B
- // r3 C
- // r4 D
- // r5 A [X] F G
- // r6 [X]
- //
- // In the round5, the in-turn signer E is offline, so the worst case
- // is A, F and G sign the block of round5 and reject the block of opponents
- // and in the round6, the last available signer B is offline, the whole
- // network is stuck.
- if _, ok := s.engine.(*clique.Clique); ok {
- return false
- }
- return s.isLocalBlock(header)
-}
-
-// SetEtherbase sets the mining reward address.
-func (s *Ethereum) SetEtherbase(etherbase common.Address) {
- s.lock.Lock()
- s.etherbase = etherbase
- s.lock.Unlock()
-
- s.miner.SetEtherbase(etherbase)
-}
-
-// StartMining starts the miner with the given number of CPU threads. If mining
-// is already running, this method adjust the number of threads allowed to use
-// and updates the minimum price required by the transaction pool.
-func (s *Ethereum) StartMining() error {
- // If the miner was not running, initialize it
- if !s.IsMining() {
- // Propagate the initial price point to the transaction pool
- s.lock.RLock()
- price := s.gasPrice
- s.lock.RUnlock()
- s.txPool.SetGasTip(price)
-
- // Configure the local mining address
- eb, err := s.Etherbase()
- if err != nil {
- log.Error("Cannot start mining without etherbase", "err", err)
- return fmt.Errorf("etherbase missing: %v", err)
- }
- var cli *clique.Clique
- if c, ok := s.engine.(*clique.Clique); ok {
- cli = c
- } else if cl, ok := s.engine.(*beacon.Beacon); ok {
- if c, ok := cl.InnerEngine().(*clique.Clique); ok {
- cli = c
- }
- }
- if cli != nil {
- wallet, err := s.accountManager.Find(accounts.Account{Address: eb})
- if wallet == nil || err != nil {
- log.Error("Etherbase account unavailable locally", "err", err)
- return fmt.Errorf("signer missing: %v", err)
- }
- cli.Authorize(eb, wallet.SignData)
- }
- // If mining is started, we can disable the transaction rejection mechanism
- // introduced to speed sync times.
- s.handler.enableSyncedFeatures()
-
- go s.miner.Start()
- }
- return nil
-}
-
-// StopMining terminates the miner, both at the consensus engine level as well as
-// at the block creation level.
-func (s *Ethereum) StopMining() {
- // Update the thread count within the consensus engine
- type threaded interface {
- SetThreads(threads int)
- }
- if th, ok := s.engine.(threaded); ok {
- th.SetThreads(-1)
- }
- // Stop the block creating itself
- s.miner.Stop()
-}
-
-func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
-func (s *Ethereum) Miner() *miner.Miner { return s.miner }
-
-func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
-func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
-func (s *Ethereum) TxPool() *txpool.TxPool { return s.txPool }
-func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
-func (s *Ethereum) Engine() consensus.Engine { return s.engine }
-func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb }
-func (s *Ethereum) IsListening() bool { return true } // Always listening
-func (s *Ethereum) Downloader() *downloader.Downloader { return s.handler.downloader }
-func (s *Ethereum) Synced() bool { return s.handler.synced.Load() }
-func (s *Ethereum) SetSynced() { s.handler.enableSyncedFeatures() }
-func (s *Ethereum) ArchiveMode() bool { return s.config.NoPruning }
-func (s *Ethereum) BloomIndexer() *core.ChainIndexer { return s.bloomIndexer }
-func (s *Ethereum) Merger() *consensus.Merger { return s.merger }
-func (s *Ethereum) SyncMode() downloader.SyncMode {
- mode, _ := s.handler.chainSync.modeAndLocalHead()
- return mode
-}
-
-// Protocols returns all the currently configured
-// network protocols to start.
-func (s *Ethereum) Protocols() []p2p.Protocol {
- protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.ethDialCandidates)
- if s.config.SnapshotCache > 0 {
- protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler), s.snapDialCandidates)...)
- }
- return protos
-}
-
-// Start implements node.Lifecycle, starting all internal goroutines needed by the
-// Ethereum protocol implementation.
-func (s *Ethereum) Start() error {
- eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode())
-
- // Start the bloom bits servicing goroutines
- s.startBloomHandlers(params.BloomBitsBlocks)
-
- // Regularly update shutdown marker
- s.shutdownTracker.Start()
-
- // Figure out a max peers count based on the server limits
- maxPeers := s.p2pServer.MaxPeers
- if s.config.LightServ > 0 {
- if s.config.LightPeers >= s.p2pServer.MaxPeers {
- return fmt.Errorf("invalid peer config: light peer count (%d) >= total peer count (%d)", s.config.LightPeers, s.p2pServer.MaxPeers)
- }
- maxPeers -= s.config.LightPeers
- }
- // Start the networking layer and the light server if requested
- s.handler.Start(maxPeers)
- return nil
-}
-
-// Stop implements node.Lifecycle, terminating all internal goroutines used by the
-// Ethereum protocol.
-func (s *Ethereum) Stop() error {
- // Stop all the peer-related stuff first.
- s.ethDialCandidates.Close()
- s.snapDialCandidates.Close()
- s.handler.Stop()
-
- // Then stop everything else.
- s.bloomIndexer.Close()
- close(s.closeBloomHandler)
- s.txPool.Close()
- s.miner.Close()
- s.blockchain.Stop()
- s.engine.Close()
-
- // Clean shutdown marker as the last thing before closing db
- s.shutdownTracker.Stop()
-
- s.chainDb.Close()
- s.eventMux.Stop()
-
- return nil
-}
diff --git a/eth/bloombits.go b/eth/bloombits.go
deleted file mode 100644
index 0cb7050d23..0000000000
--- a/eth/bloombits.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 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 eth
-
-import (
- "time"
-
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/core/rawdb"
-)
-
-const (
- // bloomServiceThreads is the number of goroutines used globally by an Ethereum
- // instance to service bloombits lookups for all running filters.
- bloomServiceThreads = 16
-
- // bloomFilterThreads is the number of goroutines used locally per filter to
- // multiplex requests onto the global servicing goroutines.
- bloomFilterThreads = 3
-
- // bloomRetrievalBatch is the maximum number of bloom bit retrievals to service
- // in a single batch.
- bloomRetrievalBatch = 16
-
- // bloomRetrievalWait is the maximum time to wait for enough bloom bit requests
- // to accumulate request an entire batch (avoiding hysteresis).
- bloomRetrievalWait = time.Duration(0)
-)
-
-// startBloomHandlers starts a batch of goroutines to accept bloom bit database
-// retrievals from possibly a range of filters and serving the data to satisfy.
-func (eth *Ethereum) startBloomHandlers(sectionSize uint64) {
- for i := 0; i < bloomServiceThreads; i++ {
- go func() {
- for {
- select {
- case <-eth.closeBloomHandler:
- return
-
- case request := <-eth.bloomRequests:
- task := <-request
- task.Bitsets = make([][]byte, len(task.Sections))
- for i, section := range task.Sections {
- head := rawdb.ReadCanonicalHash(eth.chainDb, (section+1)*sectionSize-1)
- if compVector, err := rawdb.ReadBloomBits(eth.chainDb, task.Bit, section, head); err == nil {
- if blob, err := bitutil.DecompressBytes(compVector, int(sectionSize/8)); err == nil {
- task.Bitsets[i] = blob
- } else {
- task.Error = err
- }
- } else {
- task.Error = err
- }
- }
- request <- task
- }
- }
- }()
- }
-}
diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go
deleted file mode 100644
index 37b0248f28..0000000000
--- a/eth/catalyst/api.go
+++ /dev/null
@@ -1,837 +0,0 @@
-// Copyright 2021 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 catalyst implements the temporary eth1/eth2 RPC integration.
-package catalyst
-
-import (
- "errors"
- "fmt"
- "math/big"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/beacon/engine"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-// Register adds the engine API to the full node.
-func Register(stack *node.Node, backend *eth.Ethereum) error {
- log.Warn("Engine API enabled", "protocol", "eth")
- stack.RegisterAPIs([]rpc.API{
- {
- Namespace: "engine",
- Service: NewConsensusAPI(backend),
- Authenticated: true,
- },
- })
- return nil
-}
-
-const (
- // invalidBlockHitEviction is the number of times an invalid block can be
- // referenced in forkchoice update or new payload before it is attempted
- // to be reprocessed again.
- invalidBlockHitEviction = 128
-
- // invalidTipsetsCap is the max number of recent block hashes tracked that
- // have lead to some bad ancestor block. It's just an OOM protection.
- invalidTipsetsCap = 512
-
- // beaconUpdateStartupTimeout is the time to wait for a beacon client to get
- // attached before starting to issue warnings.
- beaconUpdateStartupTimeout = 30 * time.Second
-
- // beaconUpdateConsensusTimeout is the max time allowed for a beacon client
- // to send a consensus update before it's considered offline and the user is
- // warned.
- beaconUpdateConsensusTimeout = 2 * time.Minute
-
- // beaconUpdateWarnFrequency is the frequency at which to warn the user that
- // the beacon client is offline.
- beaconUpdateWarnFrequency = 5 * time.Minute
-)
-
-// All methods provided over the engine endpoint.
-var caps = []string{
- "engine_forkchoiceUpdatedV1",
- "engine_forkchoiceUpdatedV2",
- "engine_forkchoiceUpdatedV3",
- "engine_exchangeTransitionConfigurationV1",
- "engine_getPayloadV1",
- "engine_getPayloadV2",
- "engine_getPayloadV3",
- "engine_newPayloadV1",
- "engine_newPayloadV2",
- "engine_newPayloadV3",
- "engine_getPayloadBodiesByHashV1",
- "engine_getPayloadBodiesByRangeV1",
-}
-
-type ConsensusAPI struct {
- eth *eth.Ethereum
-
- remoteBlocks *headerQueue // Cache of remote payloads received
- localBlocks *payloadQueue // Cache of local payloads generated
-
- // The forkchoice update and new payload method require us to return the
- // latest valid hash in an invalid chain. To support that return, we need
- // to track historical bad blocks as well as bad tipsets in case a chain
- // is constantly built on it.
- //
- // There are a few important caveats in this mechanism:
- // - The bad block tracking is ephemeral, in-memory only. We must never
- // persist any bad block information to disk as a bug in Geth could end
- // up blocking a valid chain, even if a later Geth update would accept
- // it.
- // - Bad blocks will get forgotten after a certain threshold of import
- // attempts and will be retried. The rationale is that if the network
- // really-really-really tries to feed us a block, we should give it a
- // new chance, perhaps us being racey instead of the block being legit
- // bad (this happened in Geth at a point with import vs. pending race).
- // - Tracking all the blocks built on top of the bad one could be a bit
- // problematic, so we will only track the head chain segment of a bad
- // chain to allow discarding progressing bad chains and side chains,
- // without tracking too much bad data.
- invalidBlocksHits map[common.Hash]int // Ephemeral cache to track invalid blocks and their hit count
- invalidTipsets map[common.Hash]*types.Header // Ephemeral cache to track invalid tipsets and their bad ancestor
- invalidLock sync.Mutex // Protects the invalid maps from concurrent access
-
- // Geth can appear to be stuck or do strange things if the beacon client is
- // offline or is sending us strange data. Stash some update stats away so
- // that we can warn the user and not have them open issues on our tracker.
- lastTransitionUpdate time.Time
- lastTransitionLock sync.Mutex
- lastForkchoiceUpdate time.Time
- lastForkchoiceLock sync.Mutex
- lastNewPayloadUpdate time.Time
- lastNewPayloadLock sync.Mutex
-
- forkchoiceLock sync.Mutex // Lock for the forkChoiceUpdated method
- newPayloadLock sync.Mutex // Lock for the NewPayload method
-}
-
-// NewConsensusAPI creates a new consensus api for the given backend.
-// The underlying blockchain needs to have a valid terminal total difficulty set.
-func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
- api := newConsensusAPIWithoutHeartbeat(eth)
- go api.heartbeat()
- return api
-}
-
-// newConsensusAPIWithoutHeartbeat creates a new consensus api for the SimulatedBeacon Node.
-func newConsensusAPIWithoutHeartbeat(eth *eth.Ethereum) *ConsensusAPI {
- if eth.BlockChain().Config().TerminalTotalDifficulty == nil {
- log.Warn("Engine API started but chain not configured for merge yet")
- }
- api := &ConsensusAPI{
- eth: eth,
- remoteBlocks: newHeaderQueue(),
- localBlocks: newPayloadQueue(),
- invalidBlocksHits: make(map[common.Hash]int),
- invalidTipsets: make(map[common.Hash]*types.Header),
- }
- eth.Downloader().SetBadBlockCallback(api.setInvalidAncestor)
- return api
-}
-
-// ForkchoiceUpdatedV1 has several responsibilities:
-//
-// We try to set our blockchain to the headBlock.
-//
-// If the method is called with an empty head block: we return success, which can be used
-// to check if the engine API is enabled.
-//
-// If the total difficulty was not reached: we return INVALID.
-//
-// If the finalizedBlockHash is set: we check if we have the finalizedBlockHash in our db,
-// if not we start a sync.
-//
-// If there are payloadAttributes: we try to assemble a block with the payloadAttributes
-// and return its payloadID.
-func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
- if payloadAttributes != nil {
- if payloadAttributes.Withdrawals != nil {
- return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("withdrawals not supported in V1"))
- }
- if api.eth.BlockChain().Config().IsShanghai(api.eth.BlockChain().Config().LondonBlock, payloadAttributes.Timestamp) {
- return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("forkChoiceUpdateV1 called post-shanghai"))
- }
- }
- return api.forkchoiceUpdated(update, payloadAttributes)
-}
-
-// ForkchoiceUpdatedV2 is equivalent to V1 with the addition of withdrawals in the payload attributes.
-func (api *ConsensusAPI) ForkchoiceUpdatedV2(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
- if payloadAttributes != nil {
- if err := api.verifyPayloadAttributes(payloadAttributes); err != nil {
- return engine.STATUS_INVALID, engine.InvalidParams.With(err)
- }
- }
- return api.forkchoiceUpdated(update, payloadAttributes)
-}
-
-// ForkchoiceUpdatedV3 is equivalent to V2 with the addition of parent beacon block root in the payload attributes.
-func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
- if payloadAttributes != nil {
- if err := api.verifyPayloadAttributes(payloadAttributes); err != nil {
- return engine.STATUS_INVALID, engine.InvalidParams.With(err)
- }
- }
- return api.forkchoiceUpdated(update, payloadAttributes)
-}
-
-func (api *ConsensusAPI) verifyPayloadAttributes(attr *engine.PayloadAttributes) error {
- c := api.eth.BlockChain().Config()
-
- // Verify withdrawals attribute for Shanghai.
- if err := checkAttribute(c.IsShanghai, attr.Withdrawals != nil, c.LondonBlock, attr.Timestamp); err != nil {
- return fmt.Errorf("invalid withdrawals: %w", err)
- }
- // Verify beacon root attribute for Cancun.
- if err := checkAttribute(c.IsCancun, attr.BeaconRoot != nil, c.LondonBlock, attr.Timestamp); err != nil {
- return fmt.Errorf("invalid parent beacon block root: %w", err)
- }
- return nil
-}
-
-func checkAttribute(active func(*big.Int, uint64) bool, exists bool, block *big.Int, time uint64) error {
- if active(block, time) && !exists {
- return errors.New("fork active, missing expected attribute")
- }
- if !active(block, time) && exists {
- return errors.New("fork inactive, unexpected attribute set")
- }
- return nil
-}
-
-func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) {
- api.forkchoiceLock.Lock()
- defer api.forkchoiceLock.Unlock()
-
- log.Trace("Engine API request received", "method", "ForkchoiceUpdated", "head", update.HeadBlockHash, "finalized", update.FinalizedBlockHash, "safe", update.SafeBlockHash)
- if update.HeadBlockHash == (common.Hash{}) {
- log.Warn("Forkchoice requested update to zero hash")
- return engine.STATUS_INVALID, nil // TODO(karalabe): Why does someone send us this?
- }
- // Stash away the last update to warn the user if the beacon client goes offline
- api.lastForkchoiceLock.Lock()
- api.lastForkchoiceUpdate = time.Now()
- api.lastForkchoiceLock.Unlock()
-
- // Check whether we have the block yet in our database or not. If not, we'll
- // need to either trigger a sync, or to reject this forkchoice update for a
- // reason.
- block := api.eth.BlockChain().GetBlockByHash(update.HeadBlockHash)
- if block == nil {
- // If this block was previously invalidated, keep rejecting it here too
- if res := api.checkInvalidAncestor(update.HeadBlockHash, update.HeadBlockHash); res != nil {
- return engine.ForkChoiceResponse{PayloadStatus: *res, PayloadID: nil}, nil
- }
- // If the head hash is unknown (was not given to us in a newPayload request),
- // we cannot resolve the header, so not much to do. This could be extended in
- // the future to resolve from the `eth` network, but it's an unexpected case
- // that should be fixed, not papered over.
- header := api.remoteBlocks.get(update.HeadBlockHash)
- if header == nil {
- log.Warn("Forkchoice requested unknown head", "hash", update.HeadBlockHash)
- return engine.STATUS_SYNCING, nil
- }
- // If the finalized hash is known, we can direct the downloader to move
- // potentially more data to the freezer from the get go.
- finalized := api.remoteBlocks.get(update.FinalizedBlockHash)
-
- // Header advertised via a past newPayload request. Start syncing to it.
- // Before we do however, make sure any legacy sync in switched off so we
- // don't accidentally have 2 cycles running.
- if merger := api.eth.Merger(); !merger.TDDReached() {
- merger.ReachTTD()
- api.eth.Downloader().Cancel()
- }
- context := []interface{}{"number", header.Number, "hash", header.Hash()}
- if update.FinalizedBlockHash != (common.Hash{}) {
- if finalized == nil {
- context = append(context, []interface{}{"finalized", "unknown"}...)
- } else {
- context = append(context, []interface{}{"finalized", finalized.Number}...)
- }
- }
- log.Info("Forkchoice requested sync to new head", context...)
- if err := api.eth.Downloader().BeaconSync(api.eth.SyncMode(), header, finalized); err != nil {
- return engine.STATUS_SYNCING, err
- }
- return engine.STATUS_SYNCING, nil
- }
- // Block is known locally, just sanity check that the beacon client does not
- // attempt to push us back to before the merge.
- if block.Difficulty().BitLen() > 0 || block.NumberU64() == 0 {
- var (
- td = api.eth.BlockChain().GetTd(update.HeadBlockHash, block.NumberU64())
- ptd = api.eth.BlockChain().GetTd(block.ParentHash(), block.NumberU64()-1)
- ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty
- )
- if td == nil || (block.NumberU64() > 0 && ptd == nil) {
- log.Error("TDs unavailable for TTD check", "number", block.NumberU64(), "hash", update.HeadBlockHash, "td", td, "parent", block.ParentHash(), "ptd", ptd)
- return engine.STATUS_INVALID, errors.New("TDs unavailable for TDD check")
- }
- if td.Cmp(ttd) < 0 {
- log.Error("Refusing beacon update to pre-merge", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
- return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil
- }
- if block.NumberU64() > 0 && ptd.Cmp(ttd) >= 0 {
- log.Error("Parent block is already post-ttd", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
- return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil
- }
- }
- valid := func(id *engine.PayloadID) engine.ForkChoiceResponse {
- return engine.ForkChoiceResponse{
- PayloadStatus: engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &update.HeadBlockHash},
- PayloadID: id,
- }
- }
- if rawdb.ReadCanonicalHash(api.eth.ChainDb(), block.NumberU64()) != update.HeadBlockHash {
- // Block is not canonical, set head.
- if latestValid, err := api.eth.BlockChain().SetCanonical(block); err != nil {
- return engine.ForkChoiceResponse{PayloadStatus: engine.PayloadStatusV1{Status: engine.INVALID, LatestValidHash: &latestValid}}, err
- }
- } else if api.eth.BlockChain().CurrentBlock().Hash() == update.HeadBlockHash {
- // If the specified head matches with our local head, do nothing and keep
- // generating the payload. It's a special corner case that a few slots are
- // missing and we are requested to generate the payload in slot.
- } else {
- // If the head block is already in our canonical chain, the beacon client is
- // probably resyncing. Ignore the update.
- log.Info("Ignoring beacon update to old head", "number", block.NumberU64(), "hash", update.HeadBlockHash, "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)), "have", api.eth.BlockChain().CurrentBlock().Number)
- return valid(nil), nil
- }
- api.eth.SetSynced()
-
- // If the beacon client also advertised a finalized block, mark the local
- // chain final and completely in PoS mode.
- if update.FinalizedBlockHash != (common.Hash{}) {
- if merger := api.eth.Merger(); !merger.PoSFinalized() {
- merger.FinalizePoS()
- }
- // If the finalized block is not in our canonical tree, somethings wrong
- finalBlock := api.eth.BlockChain().GetBlockByHash(update.FinalizedBlockHash)
- if finalBlock == nil {
- log.Warn("Final block not available in database", "hash", update.FinalizedBlockHash)
- return engine.STATUS_INVALID, engine.InvalidForkChoiceState.With(errors.New("final block not available in database"))
- } else if rawdb.ReadCanonicalHash(api.eth.ChainDb(), finalBlock.NumberU64()) != update.FinalizedBlockHash {
- log.Warn("Final block not in canonical chain", "number", block.NumberU64(), "hash", update.HeadBlockHash)
- return engine.STATUS_INVALID, engine.InvalidForkChoiceState.With(errors.New("final block not in canonical chain"))
- }
- // Set the finalized block
- api.eth.BlockChain().SetFinalized(finalBlock.Header())
- }
- // Check if the safe block hash is in our canonical tree, if not somethings wrong
- if update.SafeBlockHash != (common.Hash{}) {
- safeBlock := api.eth.BlockChain().GetBlockByHash(update.SafeBlockHash)
- if safeBlock == nil {
- log.Warn("Safe block not available in database")
- return engine.STATUS_INVALID, engine.InvalidForkChoiceState.With(errors.New("safe block not available in database"))
- }
- if rawdb.ReadCanonicalHash(api.eth.ChainDb(), safeBlock.NumberU64()) != update.SafeBlockHash {
- log.Warn("Safe block not in canonical chain")
- return engine.STATUS_INVALID, engine.InvalidForkChoiceState.With(errors.New("safe block not in canonical chain"))
- }
- // Set the safe block
- api.eth.BlockChain().SetSafe(safeBlock.Header())
- }
- // If payload generation was requested, create a new block to be potentially
- // sealed by the beacon client. The payload will be requested later, and we
- // will replace it arbitrarily many times in between.
- if payloadAttributes != nil {
- args := &miner.BuildPayloadArgs{
- Parent: update.HeadBlockHash,
- Timestamp: payloadAttributes.Timestamp,
- FeeRecipient: payloadAttributes.SuggestedFeeRecipient,
- Random: payloadAttributes.Random,
- Withdrawals: payloadAttributes.Withdrawals,
- BeaconRoot: payloadAttributes.BeaconRoot,
- }
- id := args.Id()
- // If we already are busy generating this work, then we do not need
- // to start a second process.
- if api.localBlocks.has(id) {
- return valid(&id), nil
- }
- payload, err := api.eth.Miner().BuildPayload(args)
- if err != nil {
- log.Error("Failed to build payload", "err", err)
- return valid(nil), engine.InvalidPayloadAttributes.With(err)
- }
- api.localBlocks.put(id, payload)
- return valid(&id), nil
- }
- return valid(nil), nil
-}
-
-// ExchangeTransitionConfigurationV1 checks the given configuration against
-// the configuration of the node.
-func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config engine.TransitionConfigurationV1) (*engine.TransitionConfigurationV1, error) {
- log.Trace("Engine API request received", "method", "ExchangeTransitionConfiguration", "ttd", config.TerminalTotalDifficulty)
- if config.TerminalTotalDifficulty == nil {
- return nil, errors.New("invalid terminal total difficulty")
- }
- // Stash away the last update to warn the user if the beacon client goes offline
- api.lastTransitionLock.Lock()
- api.lastTransitionUpdate = time.Now()
- api.lastTransitionLock.Unlock()
-
- ttd := api.eth.BlockChain().Config().TerminalTotalDifficulty
- if ttd == nil || ttd.Cmp(config.TerminalTotalDifficulty.ToInt()) != 0 {
- log.Warn("Invalid TTD configured", "geth", ttd, "beacon", config.TerminalTotalDifficulty)
- return nil, fmt.Errorf("invalid ttd: execution %v consensus %v", ttd, config.TerminalTotalDifficulty)
- }
- if config.TerminalBlockHash != (common.Hash{}) {
- if hash := api.eth.BlockChain().GetCanonicalHash(uint64(config.TerminalBlockNumber)); hash == config.TerminalBlockHash {
- return &engine.TransitionConfigurationV1{
- TerminalTotalDifficulty: (*hexutil.Big)(ttd),
- TerminalBlockHash: config.TerminalBlockHash,
- TerminalBlockNumber: config.TerminalBlockNumber,
- }, nil
- }
- return nil, errors.New("invalid terminal block hash")
- }
- return &engine.TransitionConfigurationV1{TerminalTotalDifficulty: (*hexutil.Big)(ttd)}, nil
-}
-
-// GetPayloadV1 returns a cached payload by id.
-func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.ExecutableData, error) {
- data, err := api.getPayload(payloadID, false)
- if err != nil {
- return nil, err
- }
- return data.ExecutionPayload, nil
-}
-
-// GetPayloadV2 returns a cached payload by id.
-func (api *ConsensusAPI) GetPayloadV2(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
- return api.getPayload(payloadID, false)
-}
-
-// GetPayloadV3 returns a cached payload by id.
-func (api *ConsensusAPI) GetPayloadV3(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
- return api.getPayload(payloadID, false)
-}
-
-func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool) (*engine.ExecutionPayloadEnvelope, error) {
- log.Trace("Engine API request received", "method", "GetPayload", "id", payloadID)
- data := api.localBlocks.get(payloadID, full)
- if data == nil {
- return nil, engine.UnknownPayload
- }
- return data, nil
-}
-
-// NewPayloadV1 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
-func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
- if params.Withdrawals != nil {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1"))
- }
- return api.newPayload(params, nil, nil)
-}
-
-// NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
-func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
- if api.eth.BlockChain().Config().IsShanghai(new(big.Int).SetUint64(params.Number), params.Timestamp) {
- if params.Withdrawals == nil {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil withdrawals post-shanghai"))
- }
- } else if params.Withdrawals != nil {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil withdrawals pre-shanghai"))
- }
- if api.eth.BlockChain().Config().IsCancun(new(big.Int).SetUint64(params.Number), params.Timestamp) {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("newPayloadV2 called post-cancun"))
- }
- return api.newPayload(params, nil, nil)
-}
-
-// NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
-func (api *ConsensusAPI) NewPayloadV3(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) {
- if params.ExcessBlobGas == nil {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil excessBlobGas post-cancun"))
- }
- if params.BlobGasUsed == nil {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil params.BlobGasUsed post-cancun"))
- }
- if versionedHashes == nil {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil versionedHashes post-cancun"))
- }
- if beaconRoot == nil {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("nil parentBeaconBlockRoot post-cancun"))
- }
-
- if !api.eth.BlockChain().Config().IsCancun(new(big.Int).SetUint64(params.Number), params.Timestamp) {
- return engine.PayloadStatusV1{Status: engine.INVALID}, engine.UnsupportedFork.With(errors.New("newPayloadV3 called pre-cancun"))
- }
-
- return api.newPayload(params, versionedHashes, beaconRoot)
-}
-
-func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashes []common.Hash, beaconRoot *common.Hash) (engine.PayloadStatusV1, error) {
- // The locking here is, strictly, not required. Without these locks, this can happen:
- //
- // 1. NewPayload( execdata-N ) is invoked from the CL. It goes all the way down to
- // api.eth.BlockChain().InsertBlockWithoutSetHead, where it is blocked on
- // e.g database compaction.
- // 2. The call times out on the CL layer, which issues another NewPayload (execdata-N) call.
- // Similarly, this also get stuck on the same place. Importantly, since the
- // first call has not gone through, the early checks for "do we already have this block"
- // will all return false.
- // 3. When the db compaction ends, then N calls inserting the same payload are processed
- // sequentially.
- // Hence, we use a lock here, to be sure that the previous call has finished before we
- // check whether we already have the block locally.
- api.newPayloadLock.Lock()
- defer api.newPayloadLock.Unlock()
-
- log.Trace("Engine API request received", "method", "NewPayload", "number", params.Number, "hash", params.BlockHash)
- block, err := engine.ExecutableDataToBlock(params, versionedHashes, beaconRoot)
- if err != nil {
- log.Warn("Invalid NewPayload params", "params", params, "error", err)
- return api.invalid(err, nil), nil
- }
- // Stash away the last update to warn the user if the beacon client goes offline
- api.lastNewPayloadLock.Lock()
- api.lastNewPayloadUpdate = time.Now()
- api.lastNewPayloadLock.Unlock()
-
- // If we already have the block locally, ignore the entire execution and just
- // return a fake success.
- if block := api.eth.BlockChain().GetBlockByHash(params.BlockHash); block != nil {
- log.Warn("Ignoring already known beacon payload", "number", params.Number, "hash", params.BlockHash, "age", common.PrettyAge(time.Unix(int64(block.Time()), 0)))
- hash := block.Hash()
- return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil
- }
- // If this block was rejected previously, keep rejecting it
- if res := api.checkInvalidAncestor(block.Hash(), block.Hash()); res != nil {
- return *res, nil
- }
- // If the parent is missing, we - in theory - could trigger a sync, but that
- // would also entail a reorg. That is problematic if multiple sibling blocks
- // are being fed to us, and even more so, if some semi-distant uncle shortens
- // our live chain. As such, payload execution will not permit reorgs and thus
- // will not trigger a sync cycle. That is fine though, if we get a fork choice
- // update after legit payload executions.
- parent := api.eth.BlockChain().GetBlock(block.ParentHash(), block.NumberU64()-1)
- if parent == nil {
- return api.delayPayloadImport(block)
- }
- // We have an existing parent, do some sanity checks to avoid the beacon client
- // triggering too early
- var (
- ptd = api.eth.BlockChain().GetTd(parent.Hash(), parent.NumberU64())
- ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty
- gptd = api.eth.BlockChain().GetTd(parent.ParentHash(), parent.NumberU64()-1)
- )
- if ptd.Cmp(ttd) < 0 {
- log.Warn("Ignoring pre-merge payload", "number", params.Number, "hash", params.BlockHash, "td", ptd, "ttd", ttd)
- return engine.INVALID_TERMINAL_BLOCK, nil
- }
- if parent.Difficulty().BitLen() > 0 && gptd != nil && gptd.Cmp(ttd) >= 0 {
- log.Error("Ignoring pre-merge parent block", "number", params.Number, "hash", params.BlockHash, "td", ptd, "ttd", ttd)
- return engine.INVALID_TERMINAL_BLOCK, nil
- }
- if block.Time() <= parent.Time() {
- log.Warn("Invalid timestamp", "parent", block.Time(), "block", block.Time())
- return api.invalid(errors.New("invalid timestamp"), parent.Header()), nil
- }
- // Another corner case: if the node is in snap sync mode, but the CL client
- // tries to make it import a block. That should be denied as pushing something
- // into the database directly will conflict with the assumptions of snap sync
- // that it has an empty db that it can fill itself.
- if api.eth.SyncMode() != downloader.FullSync {
- return api.delayPayloadImport(block)
- }
- if !api.eth.BlockChain().HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
- api.remoteBlocks.put(block.Hash(), block.Header())
- log.Warn("State not available, ignoring new payload")
- return engine.PayloadStatusV1{Status: engine.ACCEPTED}, nil
- }
- log.Trace("Inserting block without sethead", "hash", block.Hash(), "number", block.Number)
- if err := api.eth.BlockChain().InsertBlockWithoutSetHead(block); err != nil {
- log.Warn("NewPayloadV1: inserting block failed", "error", err)
-
- api.invalidLock.Lock()
- api.invalidBlocksHits[block.Hash()] = 1
- api.invalidTipsets[block.Hash()] = block.Header()
- api.invalidLock.Unlock()
-
- return api.invalid(err, parent.Header()), nil
- }
- // We've accepted a valid payload from the beacon client. Mark the local
- // chain transitions to notify other subsystems (e.g. downloader) of the
- // behavioral change.
- if merger := api.eth.Merger(); !merger.TDDReached() {
- merger.ReachTTD()
- api.eth.Downloader().Cancel()
- }
- hash := block.Hash()
- return engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &hash}, nil
-}
-
-// delayPayloadImport stashes the given block away for import at a later time,
-// either via a forkchoice update or a sync extension. This method is meant to
-// be called by the newpayload command when the block seems to be ok, but some
-// prerequisite prevents it from being processed (e.g. no parent, or snap sync).
-func (api *ConsensusAPI) delayPayloadImport(block *types.Block) (engine.PayloadStatusV1, error) {
- // Sanity check that this block's parent is not on a previously invalidated
- // chain. If it is, mark the block as invalid too.
- if res := api.checkInvalidAncestor(block.ParentHash(), block.Hash()); res != nil {
- return *res, nil
- }
- // Stash the block away for a potential forced forkchoice update to it
- // at a later time.
- api.remoteBlocks.put(block.Hash(), block.Header())
-
- // Although we don't want to trigger a sync, if there is one already in
- // progress, try to extend if with the current payload request to relieve
- // some strain from the forkchoice update.
- err := api.eth.Downloader().BeaconExtend(api.eth.SyncMode(), block.Header())
- if err == nil {
- log.Debug("Payload accepted for sync extension", "number", block.NumberU64(), "hash", block.Hash())
- return engine.PayloadStatusV1{Status: engine.SYNCING}, nil
- }
- // Either no beacon sync was started yet, or it rejected the delivered
- // payload as non-integratable on top of the existing sync. We'll just
- // have to rely on the beacon client to forcefully update the head with
- // a forkchoice update request.
- if api.eth.SyncMode() == downloader.FullSync {
- // In full sync mode, failure to import a well-formed block can only mean
- // that the parent state is missing and the syncer rejected extending the
- // current cycle with the new payload.
- log.Warn("Ignoring payload with missing parent", "number", block.NumberU64(), "hash", block.Hash(), "parent", block.ParentHash(), "reason", err)
- } else {
- // In non-full sync mode (i.e. snap sync) all payloads are rejected until
- // snap sync terminates as snap sync relies on direct database injections
- // and cannot afford concurrent out-if-band modifications via imports.
- log.Warn("Ignoring payload while snap syncing", "number", block.NumberU64(), "hash", block.Hash(), "reason", err)
- }
- return engine.PayloadStatusV1{Status: engine.SYNCING}, nil
-}
-
-// setInvalidAncestor is a callback for the downloader to notify us if a bad block
-// is encountered during the async sync.
-func (api *ConsensusAPI) setInvalidAncestor(invalid *types.Header, origin *types.Header) {
- api.invalidLock.Lock()
- defer api.invalidLock.Unlock()
-
- api.invalidTipsets[origin.Hash()] = invalid
- api.invalidBlocksHits[invalid.Hash()]++
-}
-
-// checkInvalidAncestor checks whether the specified chain end links to a known
-// bad ancestor. If yes, it constructs the payload failure response to return.
-func (api *ConsensusAPI) checkInvalidAncestor(check common.Hash, head common.Hash) *engine.PayloadStatusV1 {
- api.invalidLock.Lock()
- defer api.invalidLock.Unlock()
-
- // If the hash to check is unknown, return valid
- invalid, ok := api.invalidTipsets[check]
- if !ok {
- return nil
- }
- // If the bad hash was hit too many times, evict it and try to reprocess in
- // the hopes that we have a data race that we can exit out of.
- badHash := invalid.Hash()
-
- api.invalidBlocksHits[badHash]++
- if api.invalidBlocksHits[badHash] >= invalidBlockHitEviction {
- log.Warn("Too many bad block import attempt, trying", "number", invalid.Number, "hash", badHash)
- delete(api.invalidBlocksHits, badHash)
-
- for descendant, badHeader := range api.invalidTipsets {
- if badHeader.Hash() == badHash {
- delete(api.invalidTipsets, descendant)
- }
- }
- return nil
- }
- // Not too many failures yet, mark the head of the invalid chain as invalid
- if check != head {
- log.Warn("Marked new chain head as invalid", "hash", head, "badnumber", invalid.Number, "badhash", badHash)
- for len(api.invalidTipsets) >= invalidTipsetsCap {
- for key := range api.invalidTipsets {
- delete(api.invalidTipsets, key)
- break
- }
- }
- api.invalidTipsets[head] = invalid
- }
- // If the last valid hash is the terminal pow block, return 0x0 for latest valid hash
- lastValid := &invalid.ParentHash
- if header := api.eth.BlockChain().GetHeader(invalid.ParentHash, invalid.Number.Uint64()-1); header != nil && header.Difficulty.Sign() != 0 {
- lastValid = &common.Hash{}
- }
- failure := "links to previously rejected block"
- return &engine.PayloadStatusV1{
- Status: engine.INVALID,
- LatestValidHash: lastValid,
- ValidationError: &failure,
- }
-}
-
-// invalid returns a response "INVALID" with the latest valid hash supplied by latest.
-func (api *ConsensusAPI) invalid(err error, latestValid *types.Header) engine.PayloadStatusV1 {
- var currentHash *common.Hash
- if latestValid != nil {
- if latestValid.Difficulty.BitLen() != 0 {
- // Set latest valid hash to 0x0 if parent is PoW block
- currentHash = &common.Hash{}
- } else {
- // Otherwise set latest valid hash to parent hash
- h := latestValid.Hash()
- currentHash = &h
- }
- }
- errorMsg := err.Error()
- return engine.PayloadStatusV1{Status: engine.INVALID, LatestValidHash: currentHash, ValidationError: &errorMsg}
-}
-
-// heartbeat loops indefinitely, and checks if there have been beacon client updates
-// received in the last while. If not - or if they but strange ones - it warns the
-// user that something might be off with their consensus node.
-//
-// TODO(karalabe): Spin this goroutine down somehow
-func (api *ConsensusAPI) heartbeat() {
- // Sleep a bit on startup since there's obviously no beacon client yet
- // attached, so no need to print scary warnings to the user.
- time.Sleep(beaconUpdateStartupTimeout)
-
- // If the network is not yet merged/merging, don't bother continuing.
- if api.eth.BlockChain().Config().TerminalTotalDifficulty == nil {
- return
- }
-
- var offlineLogged time.Time
-
- for {
- // Sleep a bit and retrieve the last known consensus updates
- time.Sleep(5 * time.Second)
-
- api.lastTransitionLock.Lock()
- lastTransitionUpdate := api.lastTransitionUpdate
- api.lastTransitionLock.Unlock()
-
- api.lastForkchoiceLock.Lock()
- lastForkchoiceUpdate := api.lastForkchoiceUpdate
- api.lastForkchoiceLock.Unlock()
-
- api.lastNewPayloadLock.Lock()
- lastNewPayloadUpdate := api.lastNewPayloadUpdate
- api.lastNewPayloadLock.Unlock()
-
- // If there have been no updates for the past while, warn the user
- // that the beacon client is probably offline
- if api.eth.BlockChain().Config().TerminalTotalDifficultyPassed || api.eth.Merger().TDDReached() {
- if time.Since(lastForkchoiceUpdate) <= beaconUpdateConsensusTimeout || time.Since(lastNewPayloadUpdate) <= beaconUpdateConsensusTimeout {
- offlineLogged = time.Time{}
- continue
- }
-
- if time.Since(offlineLogged) > beaconUpdateWarnFrequency {
- if lastForkchoiceUpdate.IsZero() && lastNewPayloadUpdate.IsZero() {
- if lastTransitionUpdate.IsZero() {
- log.Warn("Post-merge network, but no beacon client seen. Please launch one to follow the chain!")
- } else {
- log.Warn("Beacon client online, but never received consensus updates. Please ensure your beacon client is operational to follow the chain!")
- }
- } else {
- log.Warn("Beacon client online, but no consensus updates received in a while. Please fix your beacon client to follow the chain!")
- }
- offlineLogged = time.Now()
- }
- continue
- }
- }
-}
-
-// ExchangeCapabilities returns the current methods provided by this node.
-func (api *ConsensusAPI) ExchangeCapabilities([]string) []string {
- return caps
-}
-
-// GetPayloadBodiesByHashV1 implements engine_getPayloadBodiesByHashV1 which allows for retrieval of a list
-// of block bodies by the engine api.
-func (api *ConsensusAPI) GetPayloadBodiesByHashV1(hashes []common.Hash) []*engine.ExecutionPayloadBodyV1 {
- bodies := make([]*engine.ExecutionPayloadBodyV1, len(hashes))
- for i, hash := range hashes {
- block := api.eth.BlockChain().GetBlockByHash(hash)
- bodies[i] = getBody(block)
- }
- return bodies
-}
-
-// GetPayloadBodiesByRangeV1 implements engine_getPayloadBodiesByRangeV1 which allows for retrieval of a range
-// of block bodies by the engine api.
-func (api *ConsensusAPI) GetPayloadBodiesByRangeV1(start, count hexutil.Uint64) ([]*engine.ExecutionPayloadBodyV1, error) {
- if start == 0 || count == 0 {
- return nil, engine.InvalidParams.With(fmt.Errorf("invalid start or count, start: %v count: %v", start, count))
- }
- if count > 1024 {
- return nil, engine.TooLargeRequest.With(fmt.Errorf("requested count too large: %v", count))
- }
- // limit count up until current
- current := api.eth.BlockChain().CurrentBlock().Number.Uint64()
- last := uint64(start) + uint64(count) - 1
- if last > current {
- last = current
- }
- bodies := make([]*engine.ExecutionPayloadBodyV1, 0, uint64(count))
- for i := uint64(start); i <= last; i++ {
- block := api.eth.BlockChain().GetBlockByNumber(i)
- bodies = append(bodies, getBody(block))
- }
- return bodies, nil
-}
-
-func getBody(block *types.Block) *engine.ExecutionPayloadBodyV1 {
- if block == nil {
- return nil
- }
-
- var (
- body = block.Body()
- txs = make([]hexutil.Bytes, len(body.Transactions))
- withdrawals = body.Withdrawals
- )
-
- for j, tx := range body.Transactions {
- data, _ := tx.MarshalBinary()
- txs[j] = hexutil.Bytes(data)
- }
-
- // Post-shanghai withdrawals MUST be set to empty slice instead of nil
- if withdrawals == nil && block.Header().WithdrawalsHash != nil {
- withdrawals = make([]*types.Withdrawal, 0)
- }
-
- return &engine.ExecutionPayloadBodyV1{
- TransactionData: txs,
- Withdrawals: withdrawals,
- }
-}
diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go
deleted file mode 100644
index c875c485dd..0000000000
--- a/eth/catalyst/api_test.go
+++ /dev/null
@@ -1,1644 +0,0 @@
-// Copyright 2021 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 catalyst
-
-import (
- "bytes"
- "context"
- crand "crypto/rand"
- "fmt"
- "math/big"
- "math/rand"
- "reflect"
- "sync"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/beacon/engine"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- beaconConsensus "github.com/ethereum/go-ethereum/consensus/beacon"
- "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/crypto"
- "github.com/ethereum/go-ethereum/crypto/kzg4844"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/ethconfig"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/trie"
- "github.com/mattn/go-colorable"
-)
-
-var (
- // testKey is a private key to use for funding a tester account.
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
-
- // testAddr is the Ethereum address of the tester account.
- testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
-
- testBalance = big.NewInt(2e18)
-)
-
-func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) {
- config := *params.AllEthashProtocolChanges
- engine := consensus.Engine(beaconConsensus.New(ethash.NewFaker()))
- if merged {
- config.TerminalTotalDifficulty = common.Big0
- config.TerminalTotalDifficultyPassed = true
- engine = beaconConsensus.NewFaker()
- }
- genesis := &core.Genesis{
- Config: &config,
- Alloc: core.GenesisAlloc{
- testAddr: {Balance: testBalance},
- params.BeaconRootsStorageAddress: {Balance: common.Big0, Code: common.Hex2Bytes("3373fffffffffffffffffffffffffffffffffffffffe14604457602036146024575f5ffd5b620180005f350680545f35146037575f5ffd5b6201800001545f5260205ff35b6201800042064281555f359062018000015500")},
- },
- ExtraData: []byte("test genesis"),
- Timestamp: 9000,
- BaseFee: big.NewInt(params.InitialBaseFee),
- Difficulty: big.NewInt(0),
- }
- testNonce := uint64(0)
- generate := func(i int, g *core.BlockGen) {
- g.OffsetTime(5)
- g.SetExtra([]byte("test"))
- tx, _ := types.SignTx(types.NewTransaction(testNonce, common.HexToAddress("0x9a9070028361F7AAbeB3f2F2Dc07F82C4a98A02a"), big.NewInt(1), params.TxGas, big.NewInt(params.InitialBaseFee*2), nil), types.LatestSigner(&config), testKey)
- g.AddTx(tx)
- testNonce++
- }
- _, blocks, _ := core.GenerateChainWithGenesis(genesis, engine, n, generate)
-
- if !merged {
- totalDifficulty := big.NewInt(0)
- for _, b := range blocks {
- totalDifficulty.Add(totalDifficulty, b.Difficulty())
- }
- config.TerminalTotalDifficulty = totalDifficulty
- }
-
- return genesis, blocks
-}
-
-func TestEth2AssembleBlock(t *testing.T) {
- genesis, blocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, blocks)
- defer n.Close()
-
- api := NewConsensusAPI(ethservice)
- signer := types.NewEIP155Signer(ethservice.BlockChain().Config().ChainID)
- tx, err := types.SignTx(types.NewTransaction(uint64(10), blocks[9].Coinbase(), big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, testKey)
- if err != nil {
- t.Fatalf("error signing transaction, err=%v", err)
- }
- ethservice.TxPool().Add([]*types.Transaction{tx}, true, false)
- blockParams := engine.PayloadAttributes{
- Timestamp: blocks[9].Time() + 5,
- }
- // The miner needs to pick up on the txs in the pool, so a few retries might be
- // needed.
- if _, testErr := assembleWithTransactions(api, blocks[9].Hash(), &blockParams, 1); testErr != nil {
- t.Fatal(testErr)
- }
-}
-
-// assembleWithTransactions tries to assemble a block, retrying until it has 'want',
-// number of transactions in it, or it has retried three times.
-func assembleWithTransactions(api *ConsensusAPI, parentHash common.Hash, params *engine.PayloadAttributes, want int) (execData *engine.ExecutableData, err error) {
- for retries := 3; retries > 0; retries-- {
- execData, err = assembleBlock(api, parentHash, params)
- if err != nil {
- return nil, err
- }
- if have, want := len(execData.Transactions), want; have != want {
- err = fmt.Errorf("invalid number of transactions, have %d want %d", have, want)
- continue
- }
- return execData, nil
- }
- return nil, err
-}
-
-func TestEth2AssembleBlockWithAnotherBlocksTxs(t *testing.T) {
- genesis, blocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, blocks[:9])
- defer n.Close()
-
- api := NewConsensusAPI(ethservice)
-
- // Put the 10th block's tx in the pool and produce a new block
- txs := blocks[9].Transactions()
- api.eth.TxPool().Add(txs, false, true)
- blockParams := engine.PayloadAttributes{
- Timestamp: blocks[8].Time() + 5,
- }
- // The miner needs to pick up on the txs in the pool, so a few retries might be
- // needed.
- if _, err := assembleWithTransactions(api, blocks[8].Hash(), &blockParams, blocks[9].Transactions().Len()); err != nil {
- t.Fatal(err)
- }
-}
-
-func TestSetHeadBeforeTotalDifficulty(t *testing.T) {
- genesis, blocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, blocks)
- defer n.Close()
-
- api := NewConsensusAPI(ethservice)
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: blocks[5].Hash(),
- SafeBlockHash: common.Hash{},
- FinalizedBlockHash: common.Hash{},
- }
- if resp, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
- t.Errorf("fork choice updated should not error: %v", err)
- } else if resp.PayloadStatus.Status != engine.INVALID_TERMINAL_BLOCK.Status {
- t.Errorf("fork choice updated before total terminal difficulty should be INVALID")
- }
-}
-
-func TestEth2PrepareAndGetPayload(t *testing.T) {
- genesis, blocks := generateMergeChain(10, false)
- // We need to properly set the terminal total difficulty
- genesis.Config.TerminalTotalDifficulty.Sub(genesis.Config.TerminalTotalDifficulty, blocks[9].Difficulty())
- n, ethservice := startEthService(t, genesis, blocks[:9])
- defer n.Close()
-
- api := NewConsensusAPI(ethservice)
-
- // Put the 10th block's tx in the pool and produce a new block
- txs := blocks[9].Transactions()
- ethservice.TxPool().Add(txs, true, false)
- blockParams := engine.PayloadAttributes{
- Timestamp: blocks[8].Time() + 5,
- }
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: blocks[8].Hash(),
- SafeBlockHash: common.Hash{},
- FinalizedBlockHash: common.Hash{},
- }
- _, err := api.ForkchoiceUpdatedV1(fcState, &blockParams)
- if err != nil {
- t.Fatalf("error preparing payload, err=%v", err)
- }
- // give the payload some time to be built
- time.Sleep(100 * time.Millisecond)
- payloadID := (&miner.BuildPayloadArgs{
- Parent: fcState.HeadBlockHash,
- Timestamp: blockParams.Timestamp,
- FeeRecipient: blockParams.SuggestedFeeRecipient,
- Random: blockParams.Random,
- BeaconRoot: blockParams.BeaconRoot,
- }).Id()
- execData, err := api.GetPayloadV1(payloadID)
- if err != nil {
- t.Fatalf("error getting payload, err=%v", err)
- }
- if len(execData.Transactions) != blocks[9].Transactions().Len() {
- t.Fatalf("invalid number of transactions %d != 1", len(execData.Transactions))
- }
- // Test invalid payloadID
- var invPayload engine.PayloadID
- copy(invPayload[:], payloadID[:])
- invPayload[0] = ^invPayload[0]
- _, err = api.GetPayloadV1(invPayload)
- if err == nil {
- t.Fatal("expected error retrieving invalid payload")
- }
-}
-
-func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan core.RemovedLogsEvent, wantNew, wantRemoved int) {
- t.Helper()
-
- if len(logsCh) != wantNew {
- t.Fatalf("wrong number of log events: got %d, want %d", len(logsCh), wantNew)
- }
- if len(rmLogsCh) != wantRemoved {
- t.Fatalf("wrong number of removed log events: got %d, want %d", len(rmLogsCh), wantRemoved)
- }
- // Drain events.
- for i := 0; i < len(logsCh); i++ {
- <-logsCh
- }
- for i := 0; i < len(rmLogsCh); i++ {
- <-rmLogsCh
- }
-}
-
-func TestInvalidPayloadTimestamp(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
- var (
- api = NewConsensusAPI(ethservice)
- parent = ethservice.BlockChain().CurrentBlock()
- )
- tests := []struct {
- time uint64
- shouldErr bool
- }{
- {0, true},
- {parent.Time, true},
- {parent.Time - 1, true},
-
- // TODO (MariusVanDerWijden) following tests are currently broken,
- // fixed in upcoming merge-kiln-v2 pr
- //{parent.Time() + 1, false},
- //{uint64(time.Now().Unix()) + uint64(time.Minute), false},
- }
-
- for i, test := range tests {
- t.Run(fmt.Sprintf("Timestamp test: %v", i), func(t *testing.T) {
- params := engine.PayloadAttributes{
- Timestamp: test.time,
- Random: crypto.Keccak256Hash([]byte{byte(123)}),
- SuggestedFeeRecipient: parent.Coinbase,
- }
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: parent.Hash(),
- SafeBlockHash: common.Hash{},
- FinalizedBlockHash: common.Hash{},
- }
- _, err := api.ForkchoiceUpdatedV1(fcState, ¶ms)
- if test.shouldErr && err == nil {
- t.Fatalf("expected error preparing payload with invalid timestamp, err=%v", err)
- } else if !test.shouldErr && err != nil {
- t.Fatalf("error preparing payload with valid timestamp, err=%v", err)
- }
- })
- }
-}
-
-func TestEth2NewBlock(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
-
- var (
- api = NewConsensusAPI(ethservice)
- parent = preMergeBlocks[len(preMergeBlocks)-1]
-
- // This EVM code generates a log when the contract is created.
- logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
- )
- // The event channels.
- newLogCh := make(chan []*types.Log, 10)
- rmLogsCh := make(chan core.RemovedLogsEvent, 10)
- ethservice.BlockChain().SubscribeLogsEvent(newLogCh)
- ethservice.BlockChain().SubscribeRemovedLogsEvent(rmLogsCh)
-
- for i := 0; i < 10; i++ {
- statedb, _ := ethservice.BlockChain().StateAt(parent.Root())
- nonce := statedb.GetNonce(testAddr)
- tx, _ := types.SignTx(types.NewContractCreation(nonce, new(big.Int), 1000000, big.NewInt(2*params.InitialBaseFee), logCode), types.LatestSigner(ethservice.BlockChain().Config()), testKey)
- ethservice.TxPool().Add([]*types.Transaction{tx}, true, false)
-
- execData, err := assembleWithTransactions(api, parent.Hash(), &engine.PayloadAttributes{
- Timestamp: parent.Time() + 5,
- }, 1)
- if err != nil {
- t.Fatalf("Failed to create the executable data %v", err)
- }
- block, err := engine.ExecutableDataToBlock(*execData, nil, nil)
- if err != nil {
- t.Fatalf("Failed to convert executable data to block %v", err)
- }
- newResp, err := api.NewPayloadV1(*execData)
- switch {
- case err != nil:
- t.Fatalf("Failed to insert block: %v", err)
- case newResp.Status != "VALID":
- t.Fatalf("Failed to insert block: %v", newResp.Status)
- case ethservice.BlockChain().CurrentBlock().Number.Uint64() != block.NumberU64()-1:
- t.Fatalf("Chain head shouldn't be updated")
- }
- checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: block.Hash(),
- SafeBlockHash: block.Hash(),
- FinalizedBlockHash: block.Hash(),
- }
- if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
- t.Fatalf("Failed to insert block: %v", err)
- }
- if have, want := ethservice.BlockChain().CurrentBlock().Number.Uint64(), block.NumberU64(); have != want {
- t.Fatalf("Chain head should be updated, have %d want %d", have, want)
- }
- checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
-
- parent = block
- }
-
- // Introduce fork chain
- var (
- head = ethservice.BlockChain().CurrentBlock().Number.Uint64()
- )
- parent = preMergeBlocks[len(preMergeBlocks)-1]
- for i := 0; i < 10; i++ {
- execData, err := assembleBlock(api, parent.Hash(), &engine.PayloadAttributes{
- Timestamp: parent.Time() + 6,
- })
- if err != nil {
- t.Fatalf("Failed to create the executable data %v", err)
- }
- block, err := engine.ExecutableDataToBlock(*execData, nil, nil)
- if err != nil {
- t.Fatalf("Failed to convert executable data to block %v", err)
- }
- newResp, err := api.NewPayloadV1(*execData)
- if err != nil || newResp.Status != "VALID" {
- t.Fatalf("Failed to insert block: %v", err)
- }
- if ethservice.BlockChain().CurrentBlock().Number.Uint64() != head {
- t.Fatalf("Chain head shouldn't be updated")
- }
-
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: block.Hash(),
- SafeBlockHash: block.Hash(),
- FinalizedBlockHash: block.Hash(),
- }
- if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
- t.Fatalf("Failed to insert block: %v", err)
- }
- if ethservice.BlockChain().CurrentBlock().Number.Uint64() != block.NumberU64() {
- t.Fatalf("Chain head should be updated")
- }
- parent, head = block, block.NumberU64()
- }
-}
-
-func TestEth2DeepReorg(t *testing.T) {
- // TODO (MariusVanDerWijden) TestEth2DeepReorg is currently broken, because it tries to reorg
- // before the totalTerminalDifficulty threshold
- /*
- genesis, preMergeBlocks := generateMergeChain(core.TriesInMemory * 2, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
-
- var (
- api = NewConsensusAPI(ethservice, nil)
- parent = preMergeBlocks[len(preMergeBlocks)-core.TriesInMemory-1]
- head = ethservice.BlockChain().CurrentBlock().Number.Uint64()()
- )
- if ethservice.BlockChain().HasBlockAndState(parent.Hash(), parent.NumberU64()) {
- t.Errorf("Block %d not pruned", parent.NumberU64())
- }
- for i := 0; i < 10; i++ {
- execData, err := api.assembleBlock(AssembleBlockParams{
- ParentHash: parent.Hash(),
- Timestamp: parent.Time() + 5,
- })
- if err != nil {
- t.Fatalf("Failed to create the executable data %v", err)
- }
- block, err := ExecutableDataToBlock(ethservice.BlockChain().Config(), parent.Header(), *execData)
- if err != nil {
- t.Fatalf("Failed to convert executable data to block %v", err)
- }
- newResp, err := api.ExecutePayload(*execData)
- if err != nil || newResp.Status != "VALID" {
- t.Fatalf("Failed to insert block: %v", err)
- }
- if ethservice.BlockChain().CurrentBlock().Number.Uint64()() != head {
- t.Fatalf("Chain head shouldn't be updated")
- }
- if err := api.setHead(block.Hash()); err != nil {
- t.Fatalf("Failed to set head: %v", err)
- }
- if ethservice.BlockChain().CurrentBlock().Number.Uint64()() != block.NumberU64() {
- t.Fatalf("Chain head should be updated")
- }
- parent, head = block, block.NumberU64()
- }
- */
-}
-
-// startEthService creates a full node instance for testing.
-func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block) (*node.Node, *eth.Ethereum) {
- t.Helper()
-
- n, err := node.New(&node.Config{
- P2P: p2p.Config{
- ListenAddr: "0.0.0.0:0",
- NoDiscovery: true,
- MaxPeers: 25,
- }})
- if err != nil {
- t.Fatal("can't create node:", err)
- }
-
- ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256}
- ethservice, err := eth.New(n, ethcfg)
- if err != nil {
- t.Fatal("can't create eth service:", err)
- }
- if err := n.Start(); err != nil {
- t.Fatal("can't start node:", err)
- }
- if _, err := ethservice.BlockChain().InsertChain(blocks); err != nil {
- n.Close()
- t.Fatal("can't import test blocks:", err)
- }
-
- ethservice.SetEtherbase(testAddr)
- ethservice.SetSynced()
- return n, ethservice
-}
-
-func TestFullAPI(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
- var (
- parent = ethservice.BlockChain().CurrentBlock()
- // This EVM code generates a log when the contract is created.
- logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
- )
-
- callback := func(parent *types.Header) {
- statedb, _ := ethservice.BlockChain().StateAt(parent.Root)
- nonce := statedb.GetNonce(testAddr)
- tx, _ := types.SignTx(types.NewContractCreation(nonce, new(big.Int), 1000000, big.NewInt(2*params.InitialBaseFee), logCode), types.LatestSigner(ethservice.BlockChain().Config()), testKey)
- ethservice.TxPool().Add([]*types.Transaction{tx}, true, false)
- }
-
- setupBlocks(t, ethservice, 10, parent, callback, nil)
-}
-
-func setupBlocks(t *testing.T, ethservice *eth.Ethereum, n int, parent *types.Header, callback func(parent *types.Header), withdrawals [][]*types.Withdrawal) []*types.Header {
- api := NewConsensusAPI(ethservice)
- var blocks []*types.Header
- for i := 0; i < n; i++ {
- callback(parent)
- var w []*types.Withdrawal
- if withdrawals != nil {
- w = withdrawals[i]
- }
-
- payload := getNewPayload(t, api, parent, w)
- execResp, err := api.NewPayloadV2(*payload)
- if err != nil {
- t.Fatalf("can't execute payload: %v", err)
- }
- if execResp.Status != engine.VALID {
- t.Fatalf("invalid status: %v", execResp.Status)
- }
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: payload.BlockHash,
- SafeBlockHash: payload.ParentHash,
- FinalizedBlockHash: payload.ParentHash,
- }
- if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
- t.Fatalf("Failed to insert block: %v", err)
- }
- if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number {
- t.Fatal("Chain head should be updated")
- }
- if ethservice.BlockChain().CurrentFinalBlock().Number.Uint64() != payload.Number-1 {
- t.Fatal("Finalized block should be updated")
- }
- parent = ethservice.BlockChain().CurrentBlock()
- blocks = append(blocks, parent)
- }
- return blocks
-}
-
-func TestExchangeTransitionConfig(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
-
- // invalid ttd
- api := NewConsensusAPI(ethservice)
- config := engine.TransitionConfigurationV1{
- TerminalTotalDifficulty: (*hexutil.Big)(big.NewInt(0)),
- TerminalBlockHash: common.Hash{},
- TerminalBlockNumber: 0,
- }
- if _, err := api.ExchangeTransitionConfigurationV1(config); err == nil {
- t.Fatal("expected error on invalid config, invalid ttd")
- }
- // invalid terminal block hash
- config = engine.TransitionConfigurationV1{
- TerminalTotalDifficulty: (*hexutil.Big)(genesis.Config.TerminalTotalDifficulty),
- TerminalBlockHash: common.Hash{1},
- TerminalBlockNumber: 0,
- }
- if _, err := api.ExchangeTransitionConfigurationV1(config); err == nil {
- t.Fatal("expected error on invalid config, invalid hash")
- }
- // valid config
- config = engine.TransitionConfigurationV1{
- TerminalTotalDifficulty: (*hexutil.Big)(genesis.Config.TerminalTotalDifficulty),
- TerminalBlockHash: common.Hash{},
- TerminalBlockNumber: 0,
- }
- if _, err := api.ExchangeTransitionConfigurationV1(config); err != nil {
- t.Fatalf("expected no error on valid config, got %v", err)
- }
- // valid config
- config = engine.TransitionConfigurationV1{
- TerminalTotalDifficulty: (*hexutil.Big)(genesis.Config.TerminalTotalDifficulty),
- TerminalBlockHash: preMergeBlocks[5].Hash(),
- TerminalBlockNumber: 6,
- }
- if _, err := api.ExchangeTransitionConfigurationV1(config); err != nil {
- t.Fatalf("expected no error on valid config, got %v", err)
- }
-}
-
-/*
-TestNewPayloadOnInvalidChain sets up a valid chain and tries to feed blocks
-from an invalid chain to test if latestValidHash (LVH) works correctly.
-
-We set up the following chain where P1 ... Pn and P1” are valid while
-P1' is invalid.
-We expect
-(1) The LVH to point to the current inserted payload if it was valid.
-(2) The LVH to point to the valid parent on an invalid payload (if the parent is available).
-(3) If the parent is unavailable, the LVH should not be set.
-
- CommonAncestor◄─▲── P1 ◄── P2 ◄─ P3 ◄─ ... ◄─ Pn
- │
- └── P1' ◄─ P2' ◄─ P3' ◄─ ... ◄─ Pn'
- │
- └── P1''
-*/
-func TestNewPayloadOnInvalidChain(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
-
- var (
- api = NewConsensusAPI(ethservice)
- parent = ethservice.BlockChain().CurrentBlock()
- signer = types.LatestSigner(ethservice.BlockChain().Config())
- // This EVM code generates a log when the contract is created.
- logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
- )
- for i := 0; i < 10; i++ {
- statedb, _ := ethservice.BlockChain().StateAt(parent.Root)
- tx := types.MustSignNewTx(testKey, signer, &types.LegacyTx{
- Nonce: statedb.GetNonce(testAddr),
- Value: new(big.Int),
- Gas: 1000000,
- GasPrice: big.NewInt(2 * params.InitialBaseFee),
- Data: logCode,
- })
- ethservice.TxPool().Add([]*types.Transaction{tx}, false, true)
- var (
- params = engine.PayloadAttributes{
- Timestamp: parent.Time + 1,
- Random: crypto.Keccak256Hash([]byte{byte(i)}),
- SuggestedFeeRecipient: parent.Coinbase,
- }
- fcState = engine.ForkchoiceStateV1{
- HeadBlockHash: parent.Hash(),
- SafeBlockHash: common.Hash{},
- FinalizedBlockHash: common.Hash{},
- }
- payload *engine.ExecutableData
- resp engine.ForkChoiceResponse
- err error
- )
- for i := 0; ; i++ {
- if resp, err = api.ForkchoiceUpdatedV1(fcState, ¶ms); err != nil {
- t.Fatalf("error preparing payload, err=%v", err)
- }
- if resp.PayloadStatus.Status != engine.VALID {
- t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status)
- }
- // give the payload some time to be built
- time.Sleep(50 * time.Millisecond)
- if payload, err = api.GetPayloadV1(*resp.PayloadID); err != nil {
- t.Fatalf("can't get payload: %v", err)
- }
- if len(payload.Transactions) > 0 {
- break
- }
- // No luck this time we need to update the params and try again.
- params.Timestamp = params.Timestamp + 1
- if i > 10 {
- t.Fatalf("payload should not be empty")
- }
- }
- execResp, err := api.NewPayloadV1(*payload)
- if err != nil {
- t.Fatalf("can't execute payload: %v", err)
- }
- if execResp.Status != engine.VALID {
- t.Fatalf("invalid status: %v", execResp.Status)
- }
- fcState = engine.ForkchoiceStateV1{
- HeadBlockHash: payload.BlockHash,
- SafeBlockHash: payload.ParentHash,
- FinalizedBlockHash: payload.ParentHash,
- }
- if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
- t.Fatalf("Failed to insert block: %v", err)
- }
- if ethservice.BlockChain().CurrentBlock().Number.Uint64() != payload.Number {
- t.Fatalf("Chain head should be updated")
- }
- parent = ethservice.BlockChain().CurrentBlock()
- }
-}
-
-func assembleBlock(api *ConsensusAPI, parentHash common.Hash, params *engine.PayloadAttributes) (*engine.ExecutableData, error) {
- args := &miner.BuildPayloadArgs{
- Parent: parentHash,
- Timestamp: params.Timestamp,
- FeeRecipient: params.SuggestedFeeRecipient,
- Random: params.Random,
- Withdrawals: params.Withdrawals,
- BeaconRoot: params.BeaconRoot,
- }
- payload, err := api.eth.Miner().BuildPayload(args)
- if err != nil {
- return nil, err
- }
- return payload.ResolveFull().ExecutionPayload, nil
-}
-
-func TestEmptyBlocks(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
-
- commonAncestor := ethservice.BlockChain().CurrentBlock()
- api := NewConsensusAPI(ethservice)
-
- // Setup 10 blocks on the canonical chain
- setupBlocks(t, ethservice, 10, commonAncestor, func(parent *types.Header) {}, nil)
-
- // (1) check LatestValidHash by sending a normal payload (P1'')
- payload := getNewPayload(t, api, commonAncestor, nil)
-
- status, err := api.NewPayloadV1(*payload)
- if err != nil {
- t.Fatal(err)
- }
- if status.Status != engine.VALID {
- t.Errorf("invalid status: expected VALID got: %v", status.Status)
- }
- if !bytes.Equal(status.LatestValidHash[:], payload.BlockHash[:]) {
- t.Fatalf("invalid LVH: got %v want %v", status.LatestValidHash, payload.BlockHash)
- }
-
- // (2) Now send P1' which is invalid
- payload = getNewPayload(t, api, commonAncestor, nil)
- payload.GasUsed += 1
- payload = setBlockhash(payload)
- // Now latestValidHash should be the common ancestor
- status, err = api.NewPayloadV1(*payload)
- if err != nil {
- t.Fatal(err)
- }
- if status.Status != engine.INVALID {
- t.Errorf("invalid status: expected INVALID got: %v", status.Status)
- }
- // Expect 0x0 on INVALID block on top of PoW block
- expected := common.Hash{}
- if !bytes.Equal(status.LatestValidHash[:], expected[:]) {
- t.Fatalf("invalid LVH: got %v want %v", status.LatestValidHash, expected)
- }
-
- // (3) Now send a payload with unknown parent
- payload = getNewPayload(t, api, commonAncestor, nil)
- payload.ParentHash = common.Hash{1}
- payload = setBlockhash(payload)
- // Now latestValidHash should be the common ancestor
- status, err = api.NewPayloadV1(*payload)
- if err != nil {
- t.Fatal(err)
- }
- if status.Status != engine.SYNCING {
- t.Errorf("invalid status: expected SYNCING got: %v", status.Status)
- }
- if status.LatestValidHash != nil {
- t.Fatalf("invalid LVH: got %v wanted nil", status.LatestValidHash)
- }
-}
-
-func getNewPayload(t *testing.T, api *ConsensusAPI, parent *types.Header, withdrawals []*types.Withdrawal) *engine.ExecutableData {
- params := engine.PayloadAttributes{
- Timestamp: parent.Time + 1,
- Random: crypto.Keccak256Hash([]byte{byte(1)}),
- SuggestedFeeRecipient: parent.Coinbase,
- Withdrawals: withdrawals,
- }
-
- payload, err := assembleBlock(api, parent.Hash(), ¶ms)
- if err != nil {
- t.Fatal(err)
- }
- return payload
-}
-
-// setBlockhash sets the blockhash of a modified ExecutableData.
-// Can be used to make modified payloads look valid.
-func setBlockhash(data *engine.ExecutableData) *engine.ExecutableData {
- txs, _ := decodeTransactions(data.Transactions)
- number := big.NewInt(0)
- number.SetUint64(data.Number)
- header := &types.Header{
- ParentHash: data.ParentHash,
- UncleHash: types.EmptyUncleHash,
- Coinbase: data.FeeRecipient,
- Root: data.StateRoot,
- TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)),
- ReceiptHash: data.ReceiptsRoot,
- Bloom: types.BytesToBloom(data.LogsBloom),
- Difficulty: common.Big0,
- Number: number,
- GasLimit: data.GasLimit,
- GasUsed: data.GasUsed,
- Time: data.Timestamp,
- BaseFee: data.BaseFeePerGas,
- Extra: data.ExtraData,
- MixDigest: data.Random,
- }
- block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
- data.BlockHash = block.Hash()
- return data
-}
-
-func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
- var txs = make([]*types.Transaction, len(enc))
- for i, encTx := range enc {
- var tx types.Transaction
- if err := tx.UnmarshalBinary(encTx); err != nil {
- return nil, fmt.Errorf("invalid transaction %d: %v", i, err)
- }
- txs[i] = &tx
- }
- return txs, nil
-}
-
-func TestTrickRemoteBlockCache(t *testing.T) {
- // Setup two nodes
- genesis, preMergeBlocks := generateMergeChain(10, false)
- nodeA, ethserviceA := startEthService(t, genesis, preMergeBlocks)
- nodeB, ethserviceB := startEthService(t, genesis, preMergeBlocks)
- defer nodeA.Close()
- defer nodeB.Close()
- for nodeB.Server().NodeInfo().Ports.Listener == 0 {
- time.Sleep(250 * time.Millisecond)
- }
- nodeA.Server().AddPeer(nodeB.Server().Self())
- nodeB.Server().AddPeer(nodeA.Server().Self())
- apiA := NewConsensusAPI(ethserviceA)
- apiB := NewConsensusAPI(ethserviceB)
-
- commonAncestor := ethserviceA.BlockChain().CurrentBlock()
-
- // Setup 10 blocks on the canonical chain
- setupBlocks(t, ethserviceA, 10, commonAncestor, func(parent *types.Header) {}, nil)
- commonAncestor = ethserviceA.BlockChain().CurrentBlock()
-
- var invalidChain []*engine.ExecutableData
- // create a valid payload (P1)
- //payload1 := getNewPayload(t, apiA, commonAncestor)
- //invalidChain = append(invalidChain, payload1)
-
- // create an invalid payload2 (P2)
- payload2 := getNewPayload(t, apiA, commonAncestor, nil)
- //payload2.ParentHash = payload1.BlockHash
- payload2.GasUsed += 1
- payload2 = setBlockhash(payload2)
- invalidChain = append(invalidChain, payload2)
-
- head := payload2
- // create some valid payloads on top
- for i := 0; i < 10; i++ {
- payload := getNewPayload(t, apiA, commonAncestor, nil)
- payload.ParentHash = head.BlockHash
- payload = setBlockhash(payload)
- invalidChain = append(invalidChain, payload)
- head = payload
- }
-
- // feed the payloads to node B
- for _, payload := range invalidChain {
- status, err := apiB.NewPayloadV1(*payload)
- if err != nil {
- panic(err)
- }
- if status.Status == engine.VALID {
- t.Error("invalid status: VALID on an invalid chain")
- }
- // Now reorg to the head of the invalid chain
- resp, err := apiB.ForkchoiceUpdatedV1(engine.ForkchoiceStateV1{HeadBlockHash: payload.BlockHash, SafeBlockHash: payload.BlockHash, FinalizedBlockHash: payload.ParentHash}, nil)
- if err != nil {
- t.Fatal(err)
- }
- if resp.PayloadStatus.Status == engine.VALID {
- t.Error("invalid status: VALID on an invalid chain")
- }
- time.Sleep(100 * time.Millisecond)
- }
-}
-
-func TestInvalidBloom(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- ethservice.Merger().ReachTTD()
- defer n.Close()
-
- commonAncestor := ethservice.BlockChain().CurrentBlock()
- api := NewConsensusAPI(ethservice)
-
- // Setup 10 blocks on the canonical chain
- setupBlocks(t, ethservice, 10, commonAncestor, func(parent *types.Header) {}, nil)
-
- // (1) check LatestValidHash by sending a normal payload (P1'')
- payload := getNewPayload(t, api, commonAncestor, nil)
- payload.LogsBloom = append(payload.LogsBloom, byte(1))
- status, err := api.NewPayloadV1(*payload)
- if err != nil {
- t.Fatal(err)
- }
- if status.Status != engine.INVALID {
- t.Errorf("invalid status: expected INVALID got: %v", status.Status)
- }
-}
-
-func TestNewPayloadOnInvalidTerminalBlock(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(100, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
- api := NewConsensusAPI(ethservice)
-
- // Test parent already post TTD in FCU
- parent := preMergeBlocks[len(preMergeBlocks)-2]
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: parent.Hash(),
- SafeBlockHash: common.Hash{},
- FinalizedBlockHash: common.Hash{},
- }
- resp, err := api.ForkchoiceUpdatedV1(fcState, nil)
- if err != nil {
- t.Fatalf("error sending forkchoice, err=%v", err)
- }
- if resp.PayloadStatus != engine.INVALID_TERMINAL_BLOCK {
- t.Fatalf("error sending invalid forkchoice, invalid status: %v", resp.PayloadStatus.Status)
- }
-
- // Test parent already post TTD in NewPayload
- args := &miner.BuildPayloadArgs{
- Parent: parent.Hash(),
- Timestamp: parent.Time() + 1,
- Random: crypto.Keccak256Hash([]byte{byte(1)}),
- FeeRecipient: parent.Coinbase(),
- }
- payload, err := api.eth.Miner().BuildPayload(args)
- if err != nil {
- t.Fatalf("error preparing payload, err=%v", err)
- }
- data := *payload.Resolve().ExecutionPayload
- // We need to recompute the blockhash, since the miner computes a wrong (correct) blockhash
- txs, _ := decodeTransactions(data.Transactions)
- header := &types.Header{
- ParentHash: data.ParentHash,
- UncleHash: types.EmptyUncleHash,
- Coinbase: data.FeeRecipient,
- Root: data.StateRoot,
- TxHash: types.DeriveSha(types.Transactions(txs), trie.NewStackTrie(nil)),
- ReceiptHash: data.ReceiptsRoot,
- Bloom: types.BytesToBloom(data.LogsBloom),
- Difficulty: common.Big0,
- Number: new(big.Int).SetUint64(data.Number),
- GasLimit: data.GasLimit,
- GasUsed: data.GasUsed,
- Time: data.Timestamp,
- BaseFee: data.BaseFeePerGas,
- Extra: data.ExtraData,
- MixDigest: data.Random,
- }
- block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */)
- data.BlockHash = block.Hash()
- // Send the new payload
- resp2, err := api.NewPayloadV1(data)
- if err != nil {
- t.Fatalf("error sending NewPayload, err=%v", err)
- }
- if resp2 != engine.INVALID_TERMINAL_BLOCK {
- t.Fatalf("error sending invalid forkchoice, invalid status: %v", resp.PayloadStatus.Status)
- }
-}
-
-// TestSimultaneousNewBlock does several parallel inserts, both as
-// newPayLoad and forkchoiceUpdate. This is to test that the api behaves
-// well even of the caller is not being 'serial'.
-func TestSimultaneousNewBlock(t *testing.T) {
- genesis, preMergeBlocks := generateMergeChain(10, false)
- n, ethservice := startEthService(t, genesis, preMergeBlocks)
- defer n.Close()
-
- var (
- api = NewConsensusAPI(ethservice)
- parent = preMergeBlocks[len(preMergeBlocks)-1]
- )
- for i := 0; i < 10; i++ {
- execData, err := assembleBlock(api, parent.Hash(), &engine.PayloadAttributes{
- Timestamp: parent.Time() + 5,
- })
- if err != nil {
- t.Fatalf("Failed to create the executable data %v", err)
- }
- // Insert it 10 times in parallel. Should be ignored.
- {
- var (
- wg sync.WaitGroup
- testErr error
- errMu sync.Mutex
- )
- wg.Add(10)
- for ii := 0; ii < 10; ii++ {
- go func() {
- defer wg.Done()
- if newResp, err := api.NewPayloadV1(*execData); err != nil {
- errMu.Lock()
- testErr = fmt.Errorf("Failed to insert block: %w", err)
- errMu.Unlock()
- } else if newResp.Status != "VALID" {
- errMu.Lock()
- testErr = fmt.Errorf("Failed to insert block: %v", newResp.Status)
- errMu.Unlock()
- }
- }()
- }
- wg.Wait()
- if testErr != nil {
- t.Fatal(testErr)
- }
- }
- block, err := engine.ExecutableDataToBlock(*execData, nil, nil)
- if err != nil {
- t.Fatalf("Failed to convert executable data to block %v", err)
- }
- if ethservice.BlockChain().CurrentBlock().Number.Uint64() != block.NumberU64()-1 {
- t.Fatalf("Chain head shouldn't be updated")
- }
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: block.Hash(),
- SafeBlockHash: block.Hash(),
- FinalizedBlockHash: block.Hash(),
- }
- {
- var (
- wg sync.WaitGroup
- testErr error
- errMu sync.Mutex
- )
- wg.Add(10)
- // Do each FCU 10 times
- for ii := 0; ii < 10; ii++ {
- go func() {
- defer wg.Done()
- if _, err := api.ForkchoiceUpdatedV1(fcState, nil); err != nil {
- errMu.Lock()
- testErr = fmt.Errorf("Failed to insert block: %w", err)
- errMu.Unlock()
- }
- }()
- }
- wg.Wait()
- if testErr != nil {
- t.Fatal(testErr)
- }
- }
- if have, want := ethservice.BlockChain().CurrentBlock().Number.Uint64(), block.NumberU64(); have != want {
- t.Fatalf("Chain head should be updated, have %d want %d", have, want)
- }
- parent = block
- }
-}
-
-// TestWithdrawals creates and verifies two post-Shanghai blocks. The first
-// includes zero withdrawals and the second includes two.
-func TestWithdrawals(t *testing.T) {
- genesis, blocks := generateMergeChain(10, true)
- // Set shanghai time to last block + 5 seconds (first post-merge block)
- time := blocks[len(blocks)-1].Time() + 5
- genesis.Config.ShanghaiTime = &time
-
- n, ethservice := startEthService(t, genesis, blocks)
- ethservice.Merger().ReachTTD()
- defer n.Close()
-
- api := NewConsensusAPI(ethservice)
-
- // 10: Build Shanghai block with no withdrawals.
- parent := ethservice.BlockChain().CurrentHeader()
- blockParams := engine.PayloadAttributes{
- Timestamp: parent.Time + 5,
- Withdrawals: make([]*types.Withdrawal, 0),
- }
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: parent.Hash(),
- }
- resp, err := api.ForkchoiceUpdatedV2(fcState, &blockParams)
- if err != nil {
- t.Fatalf("error preparing payload, err=%v", err)
- }
- if resp.PayloadStatus.Status != engine.VALID {
- t.Fatalf("unexpected status (got: %s, want: %s)", resp.PayloadStatus.Status, engine.VALID)
- }
-
- // 10: verify state root is the same as parent
- payloadID := (&miner.BuildPayloadArgs{
- Parent: fcState.HeadBlockHash,
- Timestamp: blockParams.Timestamp,
- FeeRecipient: blockParams.SuggestedFeeRecipient,
- Random: blockParams.Random,
- Withdrawals: blockParams.Withdrawals,
- BeaconRoot: blockParams.BeaconRoot,
- }).Id()
- execData, err := api.GetPayloadV2(payloadID)
- if err != nil {
- t.Fatalf("error getting payload, err=%v", err)
- }
- if execData.ExecutionPayload.StateRoot != parent.Root {
- t.Fatalf("mismatch state roots (got: %s, want: %s)", execData.ExecutionPayload.StateRoot, blocks[8].Root())
- }
-
- // 10: verify locally built block
- if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
- t.Fatalf("error validating payload: %v", err)
- } else if status.Status != engine.VALID {
- t.Fatalf("invalid payload")
- }
-
- // 11: build shanghai block with withdrawal
- aa := common.Address{0xaa}
- bb := common.Address{0xbb}
- blockParams = engine.PayloadAttributes{
- Timestamp: execData.ExecutionPayload.Timestamp + 5,
- Withdrawals: []*types.Withdrawal{
- {
- Index: 0,
- Address: aa,
- Amount: 32,
- },
- {
- Index: 1,
- Address: bb,
- Amount: 33,
- },
- },
- }
- fcState.HeadBlockHash = execData.ExecutionPayload.BlockHash
- _, err = api.ForkchoiceUpdatedV2(fcState, &blockParams)
- if err != nil {
- t.Fatalf("error preparing payload, err=%v", err)
- }
-
- // 11: verify locally build block.
- payloadID = (&miner.BuildPayloadArgs{
- Parent: fcState.HeadBlockHash,
- Timestamp: blockParams.Timestamp,
- FeeRecipient: blockParams.SuggestedFeeRecipient,
- Random: blockParams.Random,
- Withdrawals: blockParams.Withdrawals,
- BeaconRoot: blockParams.BeaconRoot,
- }).Id()
- execData, err = api.GetPayloadV2(payloadID)
- if err != nil {
- t.Fatalf("error getting payload, err=%v", err)
- }
- if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
- t.Fatalf("error validating payload: %v", err)
- } else if status.Status != engine.VALID {
- t.Fatalf("invalid payload")
- }
-
- // 11: set block as head.
- fcState.HeadBlockHash = execData.ExecutionPayload.BlockHash
- _, err = api.ForkchoiceUpdatedV2(fcState, nil)
- if err != nil {
- t.Fatalf("error preparing payload, err=%v", err)
- }
-
- // 11: verify withdrawals were processed.
- db, _, err := ethservice.APIBackend.StateAndHeaderByNumber(context.Background(), rpc.BlockNumber(execData.ExecutionPayload.Number))
- if err != nil {
- t.Fatalf("unable to load db: %v", err)
- }
- for i, w := range blockParams.Withdrawals {
- // w.Amount is in gwei, balance in wei
- if db.GetBalance(w.Address).Uint64() != w.Amount*params.GWei {
- t.Fatalf("failed to process withdrawal %d", i)
- }
- }
-}
-
-func TestNilWithdrawals(t *testing.T) {
- genesis, blocks := generateMergeChain(10, true)
- // Set shanghai time to last block + 4 seconds (first post-merge block)
- time := blocks[len(blocks)-1].Time() + 4
- genesis.Config.ShanghaiTime = &time
-
- n, ethservice := startEthService(t, genesis, blocks)
- ethservice.Merger().ReachTTD()
- defer n.Close()
-
- api := NewConsensusAPI(ethservice)
- parent := ethservice.BlockChain().CurrentHeader()
- aa := common.Address{0xaa}
-
- type test struct {
- blockParams engine.PayloadAttributes
- wantErr bool
- }
- tests := []test{
- // Before Shanghai
- {
- blockParams: engine.PayloadAttributes{
- Timestamp: parent.Time + 2,
- Withdrawals: nil,
- },
- wantErr: false,
- },
- {
- blockParams: engine.PayloadAttributes{
- Timestamp: parent.Time + 2,
- Withdrawals: make([]*types.Withdrawal, 0),
- },
- wantErr: true,
- },
- {
- blockParams: engine.PayloadAttributes{
- Timestamp: parent.Time + 2,
- Withdrawals: []*types.Withdrawal{
- {
- Index: 0,
- Address: aa,
- Amount: 32,
- },
- },
- },
- wantErr: true,
- },
- // After Shanghai
- {
- blockParams: engine.PayloadAttributes{
- Timestamp: parent.Time + 5,
- Withdrawals: nil,
- },
- wantErr: true,
- },
- {
- blockParams: engine.PayloadAttributes{
- Timestamp: parent.Time + 5,
- Withdrawals: make([]*types.Withdrawal, 0),
- },
- wantErr: false,
- },
- {
- blockParams: engine.PayloadAttributes{
- Timestamp: parent.Time + 5,
- Withdrawals: []*types.Withdrawal{
- {
- Index: 0,
- Address: aa,
- Amount: 32,
- },
- },
- },
- wantErr: false,
- },
- }
-
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: parent.Hash(),
- }
-
- for _, test := range tests {
- _, err := api.ForkchoiceUpdatedV2(fcState, &test.blockParams)
- if test.wantErr {
- if err == nil {
- t.Fatal("wanted error on fcuv2 with invalid withdrawals")
- }
- continue
- }
- if err != nil {
- t.Fatalf("error preparing payload, err=%v", err)
- }
-
- // 11: verify locally build block.
- payloadID := (&miner.BuildPayloadArgs{
- Parent: fcState.HeadBlockHash,
- Timestamp: test.blockParams.Timestamp,
- FeeRecipient: test.blockParams.SuggestedFeeRecipient,
- Random: test.blockParams.Random,
- BeaconRoot: test.blockParams.BeaconRoot,
- }).Id()
- execData, err := api.GetPayloadV2(payloadID)
- if err != nil {
- t.Fatalf("error getting payload, err=%v", err)
- }
- if status, err := api.NewPayloadV2(*execData.ExecutionPayload); err != nil {
- t.Fatalf("error validating payload: %v", err)
- } else if status.Status != engine.VALID {
- t.Fatalf("invalid payload")
- }
- }
-}
-
-func setupBodies(t *testing.T) (*node.Node, *eth.Ethereum, []*types.Block) {
- genesis, blocks := generateMergeChain(10, true)
- // enable shanghai on the last block
- time := blocks[len(blocks)-1].Header().Time + 1
- genesis.Config.ShanghaiTime = &time
- n, ethservice := startEthService(t, genesis, blocks)
-
- var (
- parent = ethservice.BlockChain().CurrentBlock()
- // This EVM code generates a log when the contract is created.
- logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
- )
-
- callback := func(parent *types.Header) {
- statedb, _ := ethservice.BlockChain().StateAt(parent.Root)
- nonce := statedb.GetNonce(testAddr)
- tx, _ := types.SignTx(types.NewContractCreation(nonce, new(big.Int), 1000000, big.NewInt(2*params.InitialBaseFee), logCode), types.LatestSigner(ethservice.BlockChain().Config()), testKey)
- ethservice.TxPool().Add([]*types.Transaction{tx}, false, false)
- }
-
- withdrawals := make([][]*types.Withdrawal, 10)
- withdrawals[0] = nil // should be filtered out by miner
- withdrawals[1] = make([]*types.Withdrawal, 0)
- for i := 2; i < len(withdrawals); i++ {
- addr := make([]byte, 20)
- crand.Read(addr)
- withdrawals[i] = []*types.Withdrawal{
- {Index: rand.Uint64(), Validator: rand.Uint64(), Amount: rand.Uint64(), Address: common.BytesToAddress(addr)},
- }
- }
-
- postShanghaiHeaders := setupBlocks(t, ethservice, 10, parent, callback, withdrawals)
- postShanghaiBlocks := make([]*types.Block, len(postShanghaiHeaders))
- for i, header := range postShanghaiHeaders {
- postShanghaiBlocks[i] = ethservice.BlockChain().GetBlock(header.Hash(), header.Number.Uint64())
- }
- return n, ethservice, append(blocks, postShanghaiBlocks...)
-}
-
-func allHashes(blocks []*types.Block) []common.Hash {
- var hashes []common.Hash
- for _, b := range blocks {
- hashes = append(hashes, b.Hash())
- }
- return hashes
-}
-func allBodies(blocks []*types.Block) []*types.Body {
- var bodies []*types.Body
- for _, b := range blocks {
- bodies = append(bodies, b.Body())
- }
- return bodies
-}
-
-func TestGetBlockBodiesByHash(t *testing.T) {
- node, eth, blocks := setupBodies(t)
- api := NewConsensusAPI(eth)
- defer node.Close()
-
- tests := []struct {
- results []*types.Body
- hashes []common.Hash
- }{
- // First pow block
- {
- results: []*types.Body{eth.BlockChain().GetBlockByNumber(0).Body()},
- hashes: []common.Hash{eth.BlockChain().GetBlockByNumber(0).Hash()},
- },
- // Last pow block
- {
- results: []*types.Body{blocks[9].Body()},
- hashes: []common.Hash{blocks[9].Hash()},
- },
- // First post-merge block
- {
- results: []*types.Body{blocks[10].Body()},
- hashes: []common.Hash{blocks[10].Hash()},
- },
- // Pre & post merge blocks
- {
- results: []*types.Body{blocks[0].Body(), blocks[9].Body(), blocks[14].Body()},
- hashes: []common.Hash{blocks[0].Hash(), blocks[9].Hash(), blocks[14].Hash()},
- },
- // unavailable block
- {
- results: []*types.Body{blocks[0].Body(), nil, blocks[14].Body()},
- hashes: []common.Hash{blocks[0].Hash(), {1, 2}, blocks[14].Hash()},
- },
- // same block multiple times
- {
- results: []*types.Body{blocks[0].Body(), nil, blocks[0].Body(), blocks[0].Body()},
- hashes: []common.Hash{blocks[0].Hash(), {1, 2}, blocks[0].Hash(), blocks[0].Hash()},
- },
- // all blocks
- {
- results: allBodies(blocks),
- hashes: allHashes(blocks),
- },
- }
-
- for k, test := range tests {
- result := api.GetPayloadBodiesByHashV1(test.hashes)
- for i, r := range result {
- if !equalBody(test.results[i], r) {
- t.Fatalf("test %v: invalid response: expected %+v got %+v", k, test.results[i], r)
- }
- }
- }
-}
-
-func TestGetBlockBodiesByRange(t *testing.T) {
- node, eth, blocks := setupBodies(t)
- api := NewConsensusAPI(eth)
- defer node.Close()
-
- tests := []struct {
- results []*types.Body
- start hexutil.Uint64
- count hexutil.Uint64
- }{
- {
- results: []*types.Body{blocks[9].Body()},
- start: 10,
- count: 1,
- },
- // Genesis
- {
- results: []*types.Body{blocks[0].Body()},
- start: 1,
- count: 1,
- },
- // First post-merge block
- {
- results: []*types.Body{blocks[9].Body()},
- start: 10,
- count: 1,
- },
- // Pre & post merge blocks
- {
- results: []*types.Body{blocks[7].Body(), blocks[8].Body(), blocks[9].Body(), blocks[10].Body()},
- start: 8,
- count: 4,
- },
- // unavailable block
- {
- results: []*types.Body{blocks[18].Body(), blocks[19].Body()},
- start: 19,
- count: 3,
- },
- // unavailable block
- {
- results: []*types.Body{blocks[19].Body()},
- start: 20,
- count: 2,
- },
- {
- results: []*types.Body{blocks[19].Body()},
- start: 20,
- count: 1,
- },
- // whole range unavailable
- {
- results: make([]*types.Body, 0),
- start: 22,
- count: 2,
- },
- // allBlocks
- {
- results: allBodies(blocks),
- start: 1,
- count: hexutil.Uint64(len(blocks)),
- },
- }
-
- for k, test := range tests {
- result, err := api.GetPayloadBodiesByRangeV1(test.start, test.count)
- if err != nil {
- t.Fatal(err)
- }
- if len(result) == len(test.results) {
- for i, r := range result {
- if !equalBody(test.results[i], r) {
- t.Fatalf("test %d: invalid response: expected \n%+v\ngot\n%+v", k, test.results[i], r)
- }
- }
- } else {
- t.Fatalf("test %d: invalid length want %v got %v", k, len(test.results), len(result))
- }
- }
-}
-
-func TestGetBlockBodiesByRangeInvalidParams(t *testing.T) {
- node, eth, _ := setupBodies(t)
- api := NewConsensusAPI(eth)
- defer node.Close()
- tests := []struct {
- start hexutil.Uint64
- count hexutil.Uint64
- want *engine.EngineAPIError
- }{
- // Genesis
- {
- start: 0,
- count: 1,
- want: engine.InvalidParams,
- },
- // No block requested
- {
- start: 1,
- count: 0,
- want: engine.InvalidParams,
- },
- // Genesis & no block
- {
- start: 0,
- count: 0,
- want: engine.InvalidParams,
- },
- // More than 1024 blocks
- {
- start: 1,
- count: 1025,
- want: engine.TooLargeRequest,
- },
- }
- for i, tc := range tests {
- result, err := api.GetPayloadBodiesByRangeV1(tc.start, tc.count)
- if err == nil {
- t.Fatalf("test %d: expected error, got %v", i, result)
- }
- if have, want := err.Error(), tc.want.Error(); have != want {
- t.Fatalf("test %d: have %s, want %s", i, have, want)
- }
- }
-}
-
-func equalBody(a *types.Body, b *engine.ExecutionPayloadBodyV1) bool {
- if a == nil && b == nil {
- return true
- } else if a == nil || b == nil {
- return false
- }
- if len(a.Transactions) != len(b.TransactionData) {
- return false
- }
- for i, tx := range a.Transactions {
- data, _ := tx.MarshalBinary()
- if !bytes.Equal(data, b.TransactionData[i]) {
- return false
- }
- }
- return reflect.DeepEqual(a.Withdrawals, b.Withdrawals)
-}
-
-func TestBlockToPayloadWithBlobs(t *testing.T) {
- header := types.Header{}
- var txs []*types.Transaction
-
- inner := types.BlobTx{
- BlobHashes: make([]common.Hash, 1),
- }
-
- txs = append(txs, types.NewTx(&inner))
- sidecars := []*types.BlobTxSidecar{
- {
- Blobs: make([]kzg4844.Blob, 1),
- Commitments: make([]kzg4844.Commitment, 1),
- Proofs: make([]kzg4844.Proof, 1),
- },
- }
-
- block := types.NewBlock(&header, txs, nil, nil, trie.NewStackTrie(nil))
- envelope := engine.BlockToExecutableData(block, nil, sidecars)
- var want int
- for _, tx := range txs {
- want += len(tx.BlobHashes())
- }
- if got := len(envelope.BlobsBundle.Commitments); got != want {
- t.Fatalf("invalid number of commitments: got %v, want %v", got, want)
- }
- if got := len(envelope.BlobsBundle.Proofs); got != want {
- t.Fatalf("invalid number of proofs: got %v, want %v", got, want)
- }
- if got := len(envelope.BlobsBundle.Blobs); got != want {
- t.Fatalf("invalid number of blobs: got %v, want %v", got, want)
- }
- _, err := engine.ExecutableDataToBlock(*envelope.ExecutionPayload, make([]common.Hash, 1), nil)
- if err != nil {
- t.Error(err)
- }
-}
-
-// This checks that beaconRoot is applied to the state from the engine API.
-func TestParentBeaconBlockRoot(t *testing.T) {
- log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(colorable.NewColorableStderr(), log.LevelTrace, true)))
-
- genesis, blocks := generateMergeChain(10, true)
-
- // Set cancun time to last block + 5 seconds
- time := blocks[len(blocks)-1].Time() + 5
- genesis.Config.ShanghaiTime = &time
- genesis.Config.CancunTime = &time
-
- n, ethservice := startEthService(t, genesis, blocks)
- ethservice.Merger().ReachTTD()
- defer n.Close()
-
- api := NewConsensusAPI(ethservice)
-
- // 11: Build Shanghai block with no withdrawals.
- parent := ethservice.BlockChain().CurrentHeader()
- blockParams := engine.PayloadAttributes{
- Timestamp: parent.Time + 5,
- Withdrawals: make([]*types.Withdrawal, 0),
- BeaconRoot: &common.Hash{42},
- }
- fcState := engine.ForkchoiceStateV1{
- HeadBlockHash: parent.Hash(),
- }
- resp, err := api.ForkchoiceUpdatedV2(fcState, &blockParams)
- if err != nil {
- t.Fatalf("error preparing payload, err=%v", err.(*engine.EngineAPIError).ErrorData())
- }
- if resp.PayloadStatus.Status != engine.VALID {
- t.Fatalf("unexpected status (got: %s, want: %s)", resp.PayloadStatus.Status, engine.VALID)
- }
-
- // 11: verify state root is the same as parent
- payloadID := (&miner.BuildPayloadArgs{
- Parent: fcState.HeadBlockHash,
- Timestamp: blockParams.Timestamp,
- FeeRecipient: blockParams.SuggestedFeeRecipient,
- Random: blockParams.Random,
- Withdrawals: blockParams.Withdrawals,
- BeaconRoot: blockParams.BeaconRoot,
- }).Id()
- execData, err := api.GetPayloadV3(payloadID)
- if err != nil {
- t.Fatalf("error getting payload, err=%v", err)
- }
-
- // 11: verify locally built block
- if status, err := api.NewPayloadV3(*execData.ExecutionPayload, []common.Hash{}, &common.Hash{42}); err != nil {
- t.Fatalf("error validating payload: %v", err)
- } else if status.Status != engine.VALID {
- t.Fatalf("invalid payload")
- }
-
- fcState.HeadBlockHash = execData.ExecutionPayload.BlockHash
- resp, err = api.ForkchoiceUpdatedV3(fcState, nil)
- if err != nil {
- t.Fatalf("error preparing payload, err=%v", err.(*engine.EngineAPIError).ErrorData())
- }
- if resp.PayloadStatus.Status != engine.VALID {
- t.Fatalf("unexpected status (got: %s, want: %s)", resp.PayloadStatus.Status, engine.VALID)
- }
-
- // 11: verify beacon root was processed.
- db, _, err := ethservice.APIBackend.StateAndHeaderByNumber(context.Background(), rpc.BlockNumber(execData.ExecutionPayload.Number))
- if err != nil {
- t.Fatalf("unable to load db: %v", err)
- }
- var (
- timeIdx = common.BigToHash(big.NewInt(int64(execData.ExecutionPayload.Timestamp % 98304)))
- rootIdx = common.BigToHash(big.NewInt(int64((execData.ExecutionPayload.Timestamp % 98304) + 98304)))
- )
-
- if num := db.GetState(params.BeaconRootsStorageAddress, timeIdx); num != timeIdx {
- t.Fatalf("incorrect number stored: want %s, got %s", timeIdx, num)
- }
- if root := db.GetState(params.BeaconRootsStorageAddress, rootIdx); root != *blockParams.BeaconRoot {
- t.Fatalf("incorrect root stored: want %s, got %s", *blockParams.BeaconRoot, root)
- }
-}
diff --git a/eth/catalyst/queue.go b/eth/catalyst/queue.go
deleted file mode 100644
index 634dc1b2e6..0000000000
--- a/eth/catalyst/queue.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// 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 catalyst
-
-import (
- "sync"
-
- "github.com/ethereum/go-ethereum/beacon/engine"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/miner"
-)
-
-// maxTrackedPayloads is the maximum number of prepared payloads the execution
-// engine tracks before evicting old ones. Ideally we should only ever track the
-// latest one; but have a slight wiggle room for non-ideal conditions.
-const maxTrackedPayloads = 10
-
-// maxTrackedHeaders is the maximum number of executed payloads the execution
-// engine tracks before evicting old ones. These are tracked outside the chain
-// during initial sync to allow ForkchoiceUpdate to reference past blocks via
-// hashes only. For the sync target it would be enough to track only the latest
-// header, but snap sync also needs the latest finalized height for the ancient
-// limit.
-const maxTrackedHeaders = 96
-
-// payloadQueueItem represents an id->payload tuple to store until it's retrieved
-// or evicted.
-type payloadQueueItem struct {
- id engine.PayloadID
- payload *miner.Payload
-}
-
-// payloadQueue tracks the latest handful of constructed payloads to be retrieved
-// by the beacon chain if block production is requested.
-type payloadQueue struct {
- payloads []*payloadQueueItem
- lock sync.RWMutex
-}
-
-// newPayloadQueue creates a pre-initialized queue with a fixed number of slots
-// all containing empty items.
-func newPayloadQueue() *payloadQueue {
- return &payloadQueue{
- payloads: make([]*payloadQueueItem, maxTrackedPayloads),
- }
-}
-
-// put inserts a new payload into the queue at the given id.
-func (q *payloadQueue) put(id engine.PayloadID, payload *miner.Payload) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- copy(q.payloads[1:], q.payloads)
- q.payloads[0] = &payloadQueueItem{
- id: id,
- payload: payload,
- }
-}
-
-// get retrieves a previously stored payload item or nil if it does not exist.
-func (q *payloadQueue) get(id engine.PayloadID, full bool) *engine.ExecutionPayloadEnvelope {
- q.lock.RLock()
- defer q.lock.RUnlock()
-
- for _, item := range q.payloads {
- if item == nil {
- return nil // no more items
- }
- if item.id == id {
- if !full {
- return item.payload.Resolve()
- }
- return item.payload.ResolveFull()
- }
- }
- return nil
-}
-
-// has checks if a particular payload is already tracked.
-func (q *payloadQueue) has(id engine.PayloadID) bool {
- q.lock.RLock()
- defer q.lock.RUnlock()
-
- for _, item := range q.payloads {
- if item == nil {
- return false
- }
- if item.id == id {
- return true
- }
- }
- return false
-}
-
-// headerQueueItem represents an hash->header tuple to store until it's retrieved
-// or evicted.
-type headerQueueItem struct {
- hash common.Hash
- header *types.Header
-}
-
-// headerQueue tracks the latest handful of constructed headers to be retrieved
-// by the beacon chain if block production is requested.
-type headerQueue struct {
- headers []*headerQueueItem
- lock sync.RWMutex
-}
-
-// newHeaderQueue creates a pre-initialized queue with a fixed number of slots
-// all containing empty items.
-func newHeaderQueue() *headerQueue {
- return &headerQueue{
- headers: make([]*headerQueueItem, maxTrackedHeaders),
- }
-}
-
-// put inserts a new header into the queue at the given hash.
-func (q *headerQueue) put(hash common.Hash, data *types.Header) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- copy(q.headers[1:], q.headers)
- q.headers[0] = &headerQueueItem{
- hash: hash,
- header: data,
- }
-}
-
-// get retrieves a previously stored header item or nil if it does not exist.
-func (q *headerQueue) get(hash common.Hash) *types.Header {
- q.lock.RLock()
- defer q.lock.RUnlock()
-
- for _, item := range q.headers {
- if item == nil {
- return nil // no more items
- }
- if item.hash == hash {
- return item.header
- }
- }
- return nil
-}
diff --git a/eth/catalyst/simulated_beacon.go b/eth/catalyst/simulated_beacon.go
deleted file mode 100644
index d8b8641e6a..0000000000
--- a/eth/catalyst/simulated_beacon.go
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2023 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 catalyst
-
-import (
- "crypto/rand"
- "errors"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/beacon/engine"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-const devEpochLength = 32
-
-// withdrawalQueue implements a FIFO queue which holds withdrawals that are
-// pending inclusion.
-type withdrawalQueue struct {
- pending chan *types.Withdrawal
-}
-
-// add queues a withdrawal for future inclusion.
-func (w *withdrawalQueue) add(withdrawal *types.Withdrawal) error {
- select {
- case w.pending <- withdrawal:
- break
- default:
- return errors.New("withdrawal queue full")
- }
- return nil
-}
-
-// gatherPending returns a number of queued withdrawals up to a maximum count.
-func (w *withdrawalQueue) gatherPending(maxCount int) []*types.Withdrawal {
- withdrawals := []*types.Withdrawal{}
- for {
- select {
- case withdrawal := <-w.pending:
- withdrawals = append(withdrawals, withdrawal)
- if len(withdrawals) == maxCount {
- break
- }
- default:
- return withdrawals
- }
- }
-}
-
-type SimulatedBeacon struct {
- shutdownCh chan struct{}
- eth *eth.Ethereum
- period uint64
- withdrawals withdrawalQueue
-
- feeRecipient common.Address
- feeRecipientLock sync.Mutex // lock gates concurrent access to the feeRecipient
-
- engineAPI *ConsensusAPI
- curForkchoiceState engine.ForkchoiceStateV1
- lastBlockTime uint64
-}
-
-func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) {
- block := eth.BlockChain().CurrentBlock()
- current := engine.ForkchoiceStateV1{
- HeadBlockHash: block.Hash(),
- SafeBlockHash: block.Hash(),
- FinalizedBlockHash: block.Hash(),
- }
- engineAPI := newConsensusAPIWithoutHeartbeat(eth)
-
- // if genesis block, send forkchoiceUpdated to trigger transition to PoS
- if block.Number.Sign() == 0 {
- if _, err := engineAPI.ForkchoiceUpdatedV2(current, nil); err != nil {
- return nil, err
- }
- }
- return &SimulatedBeacon{
- eth: eth,
- period: period,
- shutdownCh: make(chan struct{}),
- engineAPI: engineAPI,
- lastBlockTime: block.Time,
- curForkchoiceState: current,
- withdrawals: withdrawalQueue{make(chan *types.Withdrawal, 20)},
- }, nil
-}
-
-func (c *SimulatedBeacon) setFeeRecipient(feeRecipient common.Address) {
- c.feeRecipientLock.Lock()
- c.feeRecipient = feeRecipient
- c.feeRecipientLock.Unlock()
-}
-
-// Start invokes the SimulatedBeacon life-cycle function in a goroutine.
-func (c *SimulatedBeacon) Start() error {
- if c.period == 0 {
- go c.loopOnDemand()
- } else {
- go c.loop()
- }
- return nil
-}
-
-// Stop halts the SimulatedBeacon service.
-func (c *SimulatedBeacon) Stop() error {
- close(c.shutdownCh)
- return nil
-}
-
-// sealBlock initiates payload building for a new block and creates a new block
-// with the completed payload.
-func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal) error {
- tstamp := uint64(time.Now().Unix())
- if tstamp <= c.lastBlockTime {
- tstamp = c.lastBlockTime + 1
- }
- c.feeRecipientLock.Lock()
- feeRecipient := c.feeRecipient
- c.feeRecipientLock.Unlock()
-
- // Reset to CurrentBlock in case of the chain was rewound
- if header := c.eth.BlockChain().CurrentBlock(); c.curForkchoiceState.HeadBlockHash != header.Hash() {
- finalizedHash := c.finalizedBlockHash(header.Number.Uint64())
- c.setCurrentState(header.Hash(), *finalizedHash)
- }
-
- var random [32]byte
- rand.Read(random[:])
- fcResponse, err := c.engineAPI.ForkchoiceUpdatedV2(c.curForkchoiceState, &engine.PayloadAttributes{
- Timestamp: tstamp,
- SuggestedFeeRecipient: feeRecipient,
- Withdrawals: withdrawals,
- Random: random,
- })
- if err != nil {
- return err
- }
- if fcResponse == engine.STATUS_SYNCING {
- return errors.New("chain rewind prevented invocation of payload creation")
- }
-
- envelope, err := c.engineAPI.getPayload(*fcResponse.PayloadID, true)
- if err != nil {
- return err
- }
- payload := envelope.ExecutionPayload
-
- var finalizedHash common.Hash
- if payload.Number%devEpochLength == 0 {
- finalizedHash = payload.BlockHash
- } else {
- if fh := c.finalizedBlockHash(payload.Number); fh == nil {
- return errors.New("chain rewind interrupted calculation of finalized block hash")
- } else {
- finalizedHash = *fh
- }
- }
-
- // Mark the payload as canon
- if _, err = c.engineAPI.NewPayloadV2(*payload); err != nil {
- return err
- }
- c.setCurrentState(payload.BlockHash, finalizedHash)
- // Mark the block containing the payload as canonical
- if _, err = c.engineAPI.ForkchoiceUpdatedV2(c.curForkchoiceState, nil); err != nil {
- return err
- }
- c.lastBlockTime = payload.Timestamp
- return nil
-}
-
-// loopOnDemand runs the block production loop for "on-demand" configuration (period = 0)
-func (c *SimulatedBeacon) loopOnDemand() {
- var (
- newTxs = make(chan core.NewTxsEvent)
- sub = c.eth.TxPool().SubscribeTransactions(newTxs, true)
- )
- defer sub.Unsubscribe()
-
- for {
- select {
- case <-c.shutdownCh:
- return
- case w := <-c.withdrawals.pending:
- withdrawals := append(c.withdrawals.gatherPending(9), w)
- if err := c.sealBlock(withdrawals); err != nil {
- log.Warn("Error performing sealing work", "err", err)
- }
- case <-newTxs:
- withdrawals := c.withdrawals.gatherPending(10)
- if err := c.sealBlock(withdrawals); err != nil {
- log.Warn("Error performing sealing work", "err", err)
- }
- }
- }
-}
-
-// loop runs the block production loop for non-zero period configuration
-func (c *SimulatedBeacon) loop() {
- timer := time.NewTimer(0)
- for {
- select {
- case <-c.shutdownCh:
- return
- case <-timer.C:
- withdrawals := c.withdrawals.gatherPending(10)
- if err := c.sealBlock(withdrawals); err != nil {
- log.Warn("Error performing sealing work", "err", err)
- } else {
- timer.Reset(time.Second * time.Duration(c.period))
- }
- }
- }
-}
-
-// finalizedBlockHash returns the block hash of the finalized block corresponding to the given number
-// or nil if doesn't exist in the chain.
-func (c *SimulatedBeacon) finalizedBlockHash(number uint64) *common.Hash {
- var finalizedNumber uint64
- if number%devEpochLength == 0 {
- finalizedNumber = number
- } else {
- finalizedNumber = (number - 1) / devEpochLength * devEpochLength
- }
-
- if finalizedBlock := c.eth.BlockChain().GetBlockByNumber(finalizedNumber); finalizedBlock != nil {
- fh := finalizedBlock.Hash()
- return &fh
- }
- return nil
-}
-
-// setCurrentState sets the current forkchoice state
-func (c *SimulatedBeacon) setCurrentState(headHash, finalizedHash common.Hash) {
- c.curForkchoiceState = engine.ForkchoiceStateV1{
- HeadBlockHash: headHash,
- SafeBlockHash: headHash,
- FinalizedBlockHash: finalizedHash,
- }
-}
-
-func RegisterSimulatedBeaconAPIs(stack *node.Node, sim *SimulatedBeacon) {
- stack.RegisterAPIs([]rpc.API{
- {
- Namespace: "dev",
- Service: &api{sim},
- Version: "1.0",
- },
- })
-}
diff --git a/eth/catalyst/simulated_beacon_api.go b/eth/catalyst/simulated_beacon_api.go
deleted file mode 100644
index 93670257f6..0000000000
--- a/eth/catalyst/simulated_beacon_api.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2023 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 catalyst
-
-import (
- "context"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
-)
-
-type api struct {
- simBeacon *SimulatedBeacon
-}
-
-func (a *api) AddWithdrawal(ctx context.Context, withdrawal *types.Withdrawal) error {
- return a.simBeacon.withdrawals.add(withdrawal)
-}
-
-func (a *api) SetFeeRecipient(ctx context.Context, feeRecipient common.Address) {
- a.simBeacon.setFeeRecipient(feeRecipient)
-}
diff --git a/eth/catalyst/simulated_beacon_test.go b/eth/catalyst/simulated_beacon_test.go
deleted file mode 100644
index 6fa97ad87a..0000000000
--- a/eth/catalyst/simulated_beacon_test.go
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2023 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 catalyst
-
-import (
- "context"
- "math/big"
- "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/crypto"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/ethconfig"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/params"
-)
-
-func startSimulatedBeaconEthService(t *testing.T, genesis *core.Genesis) (*node.Node, *eth.Ethereum, *SimulatedBeacon) {
- t.Helper()
-
- n, err := node.New(&node.Config{
- P2P: p2p.Config{
- ListenAddr: "127.0.0.1:8545",
- NoDiscovery: true,
- MaxPeers: 0,
- },
- })
- if err != nil {
- t.Fatal("can't create node:", err)
- }
-
- ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: downloader.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256}
- ethservice, err := eth.New(n, ethcfg)
- if err != nil {
- t.Fatal("can't create eth service:", err)
- }
-
- simBeacon, err := NewSimulatedBeacon(1, ethservice)
- if err != nil {
- t.Fatal("can't create simulated beacon:", err)
- }
-
- n.RegisterLifecycle(simBeacon)
-
- if err := n.Start(); err != nil {
- t.Fatal("can't start node:", err)
- }
-
- ethservice.SetSynced()
- return n, ethservice, simBeacon
-}
-
-// send 20 transactions, >10 withdrawals and ensure they are included in order
-// send enough transactions to fill multiple blocks
-func TestSimulatedBeaconSendWithdrawals(t *testing.T) {
- var withdrawals []types.Withdrawal
- txs := make(map[common.Hash]types.Transaction)
-
- var (
- // testKey is a private key to use for funding a tester account.
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
-
- // testAddr is the Ethereum address of the tester account.
- testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
- )
-
- // short period (1 second) for testing purposes
- var gasLimit uint64 = 10_000_000
- genesis := core.DeveloperGenesisBlock(gasLimit, &testAddr)
- node, ethService, mock := startSimulatedBeaconEthService(t, genesis)
- _ = mock
- defer node.Close()
-
- chainHeadCh := make(chan core.ChainHeadEvent, 10)
- subscription := ethService.BlockChain().SubscribeChainHeadEvent(chainHeadCh)
- defer subscription.Unsubscribe()
-
- // generate some withdrawals
- for i := 0; i < 20; i++ {
- withdrawals = append(withdrawals, types.Withdrawal{Index: uint64(i)})
- if err := mock.withdrawals.add(&withdrawals[i]); err != nil {
- t.Fatal("addWithdrawal failed", err)
- }
- }
-
- // generate a bunch of transactions
- signer := types.NewEIP155Signer(ethService.BlockChain().Config().ChainID)
- for i := 0; i < 20; i++ {
- tx, err := types.SignTx(types.NewTransaction(uint64(i), common.Address{}, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, testKey)
- if err != nil {
- t.Fatalf("error signing transaction, err=%v", err)
- }
- txs[tx.Hash()] = *tx
-
- if err := ethService.APIBackend.SendTx(context.Background(), tx); err != nil {
- t.Fatal("SendTx failed", err)
- }
- }
-
- includedTxs := make(map[common.Hash]struct{})
- var includedWithdrawals []uint64
-
- timer := time.NewTimer(12 * time.Second)
- for {
- select {
- case evt := <-chainHeadCh:
- for _, includedTx := range evt.Block.Transactions() {
- includedTxs[includedTx.Hash()] = struct{}{}
- }
- for _, includedWithdrawal := range evt.Block.Withdrawals() {
- includedWithdrawals = append(includedWithdrawals, includedWithdrawal.Index)
- }
-
- // ensure all withdrawals/txs included. this will take two blocks b/c number of withdrawals > 10
- if len(includedTxs) == len(txs) && len(includedWithdrawals) == len(withdrawals) && evt.Block.Number().Cmp(big.NewInt(2)) == 0 {
- return
- }
- case <-timer.C:
- t.Fatal("timed out without including all withdrawals/txs")
- }
- }
-}
diff --git a/eth/catalyst/tester.go b/eth/catalyst/tester.go
deleted file mode 100644
index 0922ac0ba6..0000000000
--- a/eth/catalyst/tester.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// 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 catalyst
-
-import (
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
-)
-
-// FullSyncTester is an auxiliary service that allows Geth to perform full sync
-// alone without consensus-layer attached. Users must specify a valid block hash
-// as the sync target.
-//
-// This tester can be applied to different networks, no matter it's pre-merge or
-// post-merge, but only for full-sync.
-type FullSyncTester struct {
- stack *node.Node
- backend *eth.Ethereum
- target common.Hash
- closed chan struct{}
- wg sync.WaitGroup
-}
-
-// RegisterFullSyncTester registers the full-sync tester service into the node
-// stack for launching and stopping the service controlled by node.
-func RegisterFullSyncTester(stack *node.Node, backend *eth.Ethereum, target common.Hash) (*FullSyncTester, error) {
- cl := &FullSyncTester{
- stack: stack,
- backend: backend,
- target: target,
- closed: make(chan struct{}),
- }
- stack.RegisterLifecycle(cl)
- return cl, nil
-}
-
-// Start launches the beacon sync with provided sync target.
-func (tester *FullSyncTester) Start() error {
- tester.wg.Add(1)
- go func() {
- defer tester.wg.Done()
-
- // Trigger beacon sync with the provided block hash as trusted
- // chain head.
- err := tester.backend.Downloader().BeaconDevSync(downloader.FullSync, tester.target, tester.closed)
- if err != nil {
- log.Info("Failed to trigger beacon sync", "err", err)
- }
-
- ticker := time.NewTicker(time.Second * 5)
- defer ticker.Stop()
-
- for {
- select {
- case <-ticker.C:
- // Stop in case the target block is already stored locally.
- if block := tester.backend.BlockChain().GetBlockByHash(tester.target); block != nil {
- log.Info("Full-sync target reached", "number", block.NumberU64(), "hash", block.Hash())
- go tester.stack.Close() // async since we need to close ourselves
- return
- }
-
- case <-tester.closed:
- return
- }
- }
- }()
- return nil
-}
-
-// Stop stops the full-sync tester to stop all background activities.
-// This function can only be called for one time.
-func (tester *FullSyncTester) Stop() error {
- close(tester.closed)
- tester.wg.Wait()
- return nil
-}
diff --git a/eth/downloader/api.go b/eth/downloader/api.go
deleted file mode 100644
index b3f7113bcd..0000000000
--- a/eth/downloader/api.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2015 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 downloader
-
-import (
- "context"
- "sync"
-
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-// DownloaderAPI provides an API which gives information about the current synchronisation status.
-// It offers only methods that operates on data that can be available to anyone without security risks.
-type DownloaderAPI struct {
- d *Downloader
- mux *event.TypeMux
- installSyncSubscription chan chan interface{}
- uninstallSyncSubscription chan *uninstallSyncSubscriptionRequest
-}
-
-// NewDownloaderAPI create a new DownloaderAPI. The API has an internal event loop that
-// listens for events from the downloader through the global event mux. In case it receives one of
-// these events it broadcasts it to all syncing subscriptions that are installed through the
-// installSyncSubscription channel.
-func NewDownloaderAPI(d *Downloader, m *event.TypeMux) *DownloaderAPI {
- api := &DownloaderAPI{
- d: d,
- mux: m,
- installSyncSubscription: make(chan chan interface{}),
- uninstallSyncSubscription: make(chan *uninstallSyncSubscriptionRequest),
- }
-
- go api.eventLoop()
-
- return api
-}
-
-// eventLoop runs a loop until the event mux closes. It will install and uninstall new
-// sync subscriptions and broadcasts sync status updates to the installed sync subscriptions.
-func (api *DownloaderAPI) eventLoop() {
- var (
- sub = api.mux.Subscribe(StartEvent{}, DoneEvent{}, FailedEvent{})
- syncSubscriptions = make(map[chan interface{}]struct{})
- )
-
- for {
- select {
- case i := <-api.installSyncSubscription:
- syncSubscriptions[i] = struct{}{}
- case u := <-api.uninstallSyncSubscription:
- delete(syncSubscriptions, u.c)
- close(u.uninstalled)
- case event := <-sub.Chan():
- if event == nil {
- return
- }
-
- var notification interface{}
- switch event.Data.(type) {
- case StartEvent:
- notification = &SyncingResult{
- Syncing: true,
- Status: api.d.Progress(),
- }
- case DoneEvent, FailedEvent:
- notification = false
- }
- // broadcast
- for c := range syncSubscriptions {
- c <- notification
- }
- }
- }
-}
-
-// Syncing provides information when this nodes starts synchronising with the Ethereum network and when it's finished.
-func (api *DownloaderAPI) Syncing(ctx context.Context) (*rpc.Subscription, error) {
- notifier, supported := rpc.NotifierFromContext(ctx)
- if !supported {
- return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
- }
-
- rpcSub := notifier.CreateSubscription()
-
- go func() {
- statuses := make(chan interface{})
- sub := api.SubscribeSyncStatus(statuses)
-
- for {
- select {
- case status := <-statuses:
- notifier.Notify(rpcSub.ID, status)
- case <-rpcSub.Err():
- sub.Unsubscribe()
- return
- case <-notifier.Closed():
- sub.Unsubscribe()
- return
- }
- }
- }()
-
- return rpcSub, nil
-}
-
-// SyncingResult provides information about the current synchronisation status for this node.
-type SyncingResult struct {
- Syncing bool `json:"syncing"`
- Status ethereum.SyncProgress `json:"status"`
-}
-
-// uninstallSyncSubscriptionRequest uninstalls a syncing subscription in the API event loop.
-type uninstallSyncSubscriptionRequest struct {
- c chan interface{}
- uninstalled chan interface{}
-}
-
-// SyncStatusSubscription represents a syncing subscription.
-type SyncStatusSubscription struct {
- api *DownloaderAPI // register subscription in event loop of this api instance
- c chan interface{} // channel where events are broadcasted to
- unsubOnce sync.Once // make sure unsubscribe logic is executed once
-}
-
-// Unsubscribe uninstalls the subscription from the DownloadAPI event loop.
-// The status channel that was passed to subscribeSyncStatus isn't used anymore
-// after this method returns.
-func (s *SyncStatusSubscription) Unsubscribe() {
- s.unsubOnce.Do(func() {
- req := uninstallSyncSubscriptionRequest{s.c, make(chan interface{})}
- s.api.uninstallSyncSubscription <- &req
-
- for {
- select {
- case <-s.c:
- // drop new status events until uninstall confirmation
- continue
- case <-req.uninstalled:
- return
- }
- }
- })
-}
-
-// SubscribeSyncStatus creates a subscription that will broadcast new synchronisation updates.
-// The given channel must receive interface values, the result can either.
-func (api *DownloaderAPI) SubscribeSyncStatus(status chan interface{}) *SyncStatusSubscription {
- api.installSyncSubscription <- status
- return &SyncStatusSubscription{api: api, c: status}
-}
diff --git a/eth/downloader/beacondevsync.go b/eth/downloader/beacondevsync.go
deleted file mode 100644
index 9a38fedd46..0000000000
--- a/eth/downloader/beacondevsync.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2023 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 downloader
-
-import (
- "errors"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// BeaconDevSync is a development helper to test synchronization by providing
-// a block hash instead of header to run the beacon sync against.
-//
-// The method will reach out to the network to retrieve the header of the sync
-// target instead of receiving it from the consensus node.
-//
-// Note, this must not be used in live code. If the forkchcoice endpoint where
-// to use this instead of giving us the payload first, then essentially nobody
-// in the network would have the block yet that we'd attempt to retrieve.
-func (d *Downloader) BeaconDevSync(mode SyncMode, hash common.Hash, stop chan struct{}) error {
- // Be very loud that this code should not be used in a live node
- log.Warn("----------------------------------")
- log.Warn("Beacon syncing with hash as target", "hash", hash)
- log.Warn("This is unhealthy for a live node!")
- log.Warn("----------------------------------")
-
- log.Info("Waiting for peers to retrieve sync target")
- for {
- // If the node is going down, unblock
- select {
- case <-stop:
- return errors.New("stop requested")
- default:
- }
- // Pick a random peer to sync from and keep retrying if none are yet
- // available due to fresh startup
- d.peers.lock.RLock()
- var peer *peerConnection
- for _, peer = range d.peers.peers {
- break
- }
- d.peers.lock.RUnlock()
-
- if peer == nil {
- time.Sleep(time.Second)
- continue
- }
- // Found a peer, attempt to retrieve the header whilst blocking and
- // retry if it fails for whatever reason
- log.Info("Attempting to retrieve sync target", "peer", peer.id)
- headers, metas, err := d.fetchHeadersByHash(peer, hash, 1, 0, false)
- if err != nil || len(headers) != 1 {
- log.Warn("Failed to fetch sync target", "headers", len(headers), "err", err)
- time.Sleep(time.Second)
- continue
- }
- // Head header retrieved, if the hash matches, start the actual sync
- if metas[0] != hash {
- log.Error("Received invalid sync target", "want", hash, "have", metas[0])
- time.Sleep(time.Second)
- continue
- }
- return d.BeaconSync(mode, headers[0], headers[0])
- }
-}
diff --git a/eth/downloader/beaconsync.go b/eth/downloader/beaconsync.go
deleted file mode 100644
index df8af68bc7..0000000000
--- a/eth/downloader/beaconsync.go
+++ /dev/null
@@ -1,389 +0,0 @@
-// 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 downloader
-
-import (
- "fmt"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// beaconBackfiller is the chain and state backfilling that can be commenced once
-// the skeleton syncer has successfully reverse downloaded all the headers up to
-// the genesis block or an existing header in the database. Its operation is fully
-// directed by the skeleton sync's head/tail events.
-type beaconBackfiller struct {
- downloader *Downloader // Downloader to direct via this callback implementation
- syncMode SyncMode // Sync mode to use for backfilling the skeleton chains
- success func() // Callback to run on successful sync cycle completion
- filling bool // Flag whether the downloader is backfilling or not
- filled *types.Header // Last header filled by the last terminated sync loop
- started chan struct{} // Notification channel whether the downloader inited
- lock sync.Mutex // Mutex protecting the sync lock
-}
-
-// newBeaconBackfiller is a helper method to create the backfiller.
-func newBeaconBackfiller(dl *Downloader, success func()) backfiller {
- return &beaconBackfiller{
- downloader: dl,
- success: success,
- }
-}
-
-// suspend cancels any background downloader threads and returns the last header
-// that has been successfully backfilled.
-func (b *beaconBackfiller) suspend() *types.Header {
- // If no filling is running, don't waste cycles
- b.lock.Lock()
- filling := b.filling
- filled := b.filled
- started := b.started
- b.lock.Unlock()
-
- if !filling {
- return filled // Return the filled header on the previous sync completion
- }
- // A previous filling should be running, though it may happen that it hasn't
- // yet started (being done on a new goroutine). Many concurrent beacon head
- // announcements can lead to sync start/stop thrashing. In that case we need
- // to wait for initialization before we can safely cancel it. It is safe to
- // read this channel multiple times, it gets closed on startup.
- <-started
-
- // Now that we're sure the downloader successfully started up, we can cancel
- // it safely without running the risk of data races.
- b.downloader.Cancel()
-
- // Sync cycle was just terminated, retrieve and return the last filled header.
- // Can't use `filled` as that contains a stale value from before cancellation.
- return b.downloader.blockchain.CurrentSnapBlock()
-}
-
-// resume starts the downloader threads for backfilling state and chain data.
-func (b *beaconBackfiller) resume() {
- b.lock.Lock()
- if b.filling {
- // If a previous filling cycle is still running, just ignore this start
- // request. // TODO(karalabe): We should make this channel driven
- b.lock.Unlock()
- return
- }
- b.filling = true
- b.filled = nil
- b.started = make(chan struct{})
- mode := b.syncMode
- b.lock.Unlock()
-
- // Start the backfilling on its own thread since the downloader does not have
- // its own lifecycle runloop.
- go func() {
- // Set the backfiller to non-filling when download completes
- defer func() {
- b.lock.Lock()
- b.filling = false
- b.filled = b.downloader.blockchain.CurrentSnapBlock()
- b.lock.Unlock()
- }()
- // If the downloader fails, report an error as in beacon chain mode there
- // should be no errors as long as the chain we're syncing to is valid.
- if err := b.downloader.synchronise("", common.Hash{}, nil, nil, mode, true, b.started); err != nil {
- log.Error("Beacon backfilling failed", "err", err)
- return
- }
- // Synchronization succeeded. Since this happens async, notify the outer
- // context to disable snap syncing and enable transaction propagation.
- if b.success != nil {
- b.success()
- }
- }()
-}
-
-// setMode updates the sync mode from the current one to the requested one. If
-// there's an active sync in progress, it will be cancelled and restarted.
-func (b *beaconBackfiller) setMode(mode SyncMode) {
- // Update the old sync mode and track if it was changed
- b.lock.Lock()
- updated := b.syncMode != mode
- filling := b.filling
- b.syncMode = mode
- b.lock.Unlock()
-
- // If the sync mode was changed mid-sync, restart. This should never ever
- // really happen, we just handle it to detect programming errors.
- if !updated || !filling {
- return
- }
- log.Error("Downloader sync mode changed mid-run", "old", mode.String(), "new", mode.String())
- b.suspend()
- b.resume()
-}
-
-// SetBadBlockCallback sets the callback to run when a bad block is hit by the
-// block processor. This method is not thread safe and should be set only once
-// on startup before system events are fired.
-func (d *Downloader) SetBadBlockCallback(onBadBlock badBlockFn) {
- d.badBlock = onBadBlock
-}
-
-// BeaconSync is the post-merge version of the chain synchronization, where the
-// chain is not downloaded from genesis onward, rather from trusted head announces
-// backwards.
-//
-// Internally backfilling and state sync is done the same way, but the header
-// retrieval and scheduling is replaced.
-func (d *Downloader) BeaconSync(mode SyncMode, head *types.Header, final *types.Header) error {
- return d.beaconSync(mode, head, final, true)
-}
-
-// BeaconExtend is an optimistic version of BeaconSync, where an attempt is made
-// to extend the current beacon chain with a new header, but in case of a mismatch,
-// the old sync will not be terminated and reorged, rather the new head is dropped.
-//
-// This is useful if a beacon client is feeding us large chunks of payloads to run,
-// but is not setting the head after each.
-func (d *Downloader) BeaconExtend(mode SyncMode, head *types.Header) error {
- return d.beaconSync(mode, head, nil, false)
-}
-
-// beaconSync is the post-merge version of the chain synchronization, where the
-// chain is not downloaded from genesis onward, rather from trusted head announces
-// backwards.
-//
-// Internally backfilling and state sync is done the same way, but the header
-// retrieval and scheduling is replaced.
-func (d *Downloader) beaconSync(mode SyncMode, head *types.Header, final *types.Header, force bool) error {
- // When the downloader starts a sync cycle, it needs to be aware of the sync
- // mode to use (full, snap). To keep the skeleton chain oblivious, inject the
- // mode into the backfiller directly.
- //
- // Super crazy dangerous type cast. Should be fine (TM), we're only using a
- // different backfiller implementation for skeleton tests.
- d.skeleton.filler.(*beaconBackfiller).setMode(mode)
-
- // Signal the skeleton sync to switch to a new head, however it wants
- if err := d.skeleton.Sync(head, final, force); err != nil {
- return err
- }
- return nil
-}
-
-// findBeaconAncestor tries to locate the common ancestor link of the local chain
-// and the beacon chain just requested. In the general case when our node was in
-// sync and on the correct chain, checking the top N links should already get us
-// a match. In the rare scenario when we ended up on a long reorganisation (i.e.
-// none of the head links match), we do a binary search to find the ancestor.
-func (d *Downloader) findBeaconAncestor() (uint64, error) {
- // Figure out the current local head position
- var chainHead *types.Header
-
- switch d.getMode() {
- case FullSync:
- chainHead = d.blockchain.CurrentBlock()
- case SnapSync:
- chainHead = d.blockchain.CurrentSnapBlock()
- default:
- chainHead = d.lightchain.CurrentHeader()
- }
- number := chainHead.Number.Uint64()
-
- // Retrieve the skeleton bounds and ensure they are linked to the local chain
- beaconHead, beaconTail, _, err := d.skeleton.Bounds()
- if err != nil {
- // This is a programming error. The chain backfiller was called with an
- // invalid beacon sync state. Ideally we would panic here, but erroring
- // gives us at least a remote chance to recover. It's still a big fault!
- log.Error("Failed to retrieve beacon bounds", "err", err)
- return 0, err
- }
- var linked bool
- switch d.getMode() {
- case FullSync:
- linked = d.blockchain.HasBlock(beaconTail.ParentHash, beaconTail.Number.Uint64()-1)
- case SnapSync:
- linked = d.blockchain.HasFastBlock(beaconTail.ParentHash, beaconTail.Number.Uint64()-1)
- default:
- linked = d.blockchain.HasHeader(beaconTail.ParentHash, beaconTail.Number.Uint64()-1)
- }
- if !linked {
- // This is a programming error. The chain backfiller was called with a
- // tail that's not linked to the local chain. Whilst this should never
- // happen, there might be some weirdnesses if beacon sync backfilling
- // races with the user (or beacon client) calling setHead. Whilst panic
- // would be the ideal thing to do, it is safer long term to attempt a
- // recovery and fix any noticed issue after the fact.
- log.Error("Beacon sync linkup unavailable", "number", beaconTail.Number.Uint64()-1, "hash", beaconTail.ParentHash)
- return 0, fmt.Errorf("beacon linkup unavailable locally: %d [%x]", beaconTail.Number.Uint64()-1, beaconTail.ParentHash)
- }
- // Binary search to find the ancestor
- start, end := beaconTail.Number.Uint64()-1, number
- if number := beaconHead.Number.Uint64(); end > number {
- // This shouldn't really happen in a healthy network, but if the consensus
- // clients feeds us a shorter chain as the canonical, we should not attempt
- // to access non-existent skeleton items.
- log.Warn("Beacon head lower than local chain", "beacon", number, "local", end)
- end = number
- }
- for start+1 < end {
- // Split our chain interval in two, and request the hash to cross check
- check := (start + end) / 2
-
- h := d.skeleton.Header(check)
- n := h.Number.Uint64()
-
- var known bool
- switch d.getMode() {
- case FullSync:
- known = d.blockchain.HasBlock(h.Hash(), n)
- case SnapSync:
- known = d.blockchain.HasFastBlock(h.Hash(), n)
- default:
- known = d.lightchain.HasHeader(h.Hash(), n)
- }
- if !known {
- end = check
- continue
- }
- start = check
- }
- return start, nil
-}
-
-// fetchBeaconHeaders feeds skeleton headers to the downloader queue for scheduling
-// until sync errors or is finished.
-func (d *Downloader) fetchBeaconHeaders(from uint64) error {
- var head *types.Header
- _, tail, _, err := d.skeleton.Bounds()
- if err != nil {
- return err
- }
- // A part of headers are not in the skeleton space, try to resolve
- // them from the local chain. Note the range should be very short
- // and it should only happen when there are less than 64 post-merge
- // blocks in the network.
- var localHeaders []*types.Header
- if from < tail.Number.Uint64() {
- count := tail.Number.Uint64() - from
- if count > uint64(fsMinFullBlocks) {
- return fmt.Errorf("invalid origin (%d) of beacon sync (%d)", from, tail.Number)
- }
- localHeaders = d.readHeaderRange(tail, int(count))
- log.Warn("Retrieved beacon headers from local", "from", from, "count", count)
- }
- for {
- // Some beacon headers might have appeared since the last cycle, make
- // sure we're always syncing to all available ones
- head, _, _, err = d.skeleton.Bounds()
- if err != nil {
- return err
- }
- // If the pivot became stale (older than 2*64-8 (bit of wiggle room)),
- // move it ahead to HEAD-64
- d.pivotLock.Lock()
- if d.pivotHeader != nil {
- if head.Number.Uint64() > d.pivotHeader.Number.Uint64()+2*uint64(fsMinFullBlocks)-8 {
- // Retrieve the next pivot header, either from skeleton chain
- // or the filled chain
- number := head.Number.Uint64() - uint64(fsMinFullBlocks)
-
- log.Warn("Pivot seemingly stale, moving", "old", d.pivotHeader.Number, "new", number)
- if d.pivotHeader = d.skeleton.Header(number); d.pivotHeader == nil {
- if number < tail.Number.Uint64() {
- dist := tail.Number.Uint64() - number
- if len(localHeaders) >= int(dist) {
- d.pivotHeader = localHeaders[dist-1]
- log.Warn("Retrieved pivot header from local", "number", d.pivotHeader.Number, "hash", d.pivotHeader.Hash(), "latest", head.Number, "oldest", tail.Number)
- }
- }
- }
- // Print an error log and return directly in case the pivot header
- // is still not found. It means the skeleton chain is not linked
- // correctly with local chain.
- if d.pivotHeader == nil {
- log.Error("Pivot header is not found", "number", number)
- d.pivotLock.Unlock()
- return errNoPivotHeader
- }
- // Write out the pivot into the database so a rollback beyond
- // it will reenable snap sync and update the state root that
- // the state syncer will be downloading
- rawdb.WriteLastPivotNumber(d.stateDB, d.pivotHeader.Number.Uint64())
- }
- }
- d.pivotLock.Unlock()
-
- // Retrieve a batch of headers and feed it to the header processor
- var (
- headers = make([]*types.Header, 0, maxHeadersProcess)
- hashes = make([]common.Hash, 0, maxHeadersProcess)
- )
- for i := 0; i < maxHeadersProcess && from <= head.Number.Uint64(); i++ {
- header := d.skeleton.Header(from)
-
- // The header is not found in skeleton space, try to find it in local chain.
- if header == nil && from < tail.Number.Uint64() {
- dist := tail.Number.Uint64() - from
- if len(localHeaders) >= int(dist) {
- header = localHeaders[dist-1]
- }
- }
- // The header is still missing, the beacon sync is corrupted and bail out
- // the error here.
- if header == nil {
- return fmt.Errorf("missing beacon header %d", from)
- }
- headers = append(headers, header)
- hashes = append(hashes, headers[i].Hash())
- from++
- }
- if len(headers) > 0 {
- log.Trace("Scheduling new beacon headers", "count", len(headers), "from", from-uint64(len(headers)))
- select {
- case d.headerProcCh <- &headerTask{
- headers: headers,
- hashes: hashes,
- }:
- case <-d.cancelCh:
- return errCanceled
- }
- }
- // If we still have headers to import, loop and keep pushing them
- if from <= head.Number.Uint64() {
- continue
- }
- // If the pivot block is committed, signal header sync termination
- if d.committed.Load() {
- select {
- case d.headerProcCh <- nil:
- return nil
- case <-d.cancelCh:
- return errCanceled
- }
- }
- // State sync still going, wait a bit for new headers and retry
- log.Trace("Pivot not yet committed, waiting...")
- select {
- case <-time.After(fsHeaderContCheck):
- case <-d.cancelCh:
- return errCanceled
- }
- }
-}
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go
deleted file mode 100644
index f1cfa92d5d..0000000000
--- a/eth/downloader/downloader.go
+++ /dev/null
@@ -1,1844 +0,0 @@
-// Copyright 2015 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 downloader contains the manual full chain synchronisation.
-package downloader
-
-import (
- "errors"
- "fmt"
- "math/big"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/state/snapshot"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/protocols/snap"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-var (
- MaxBlockFetch = 128 // Amount of blocks to be fetched per retrieval request
- MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request
- MaxSkeletonSize = 128 // Number of header fetches to need for a skeleton assembly
- MaxReceiptFetch = 256 // Amount of transaction receipts to allow fetching per request
-
- maxQueuedHeaders = 32 * 1024 // [eth/62] Maximum number of headers to queue for import (DOS protection)
- maxHeadersProcess = 2048 // Number of header download results to import at once into the chain
- maxResultsProcess = 2048 // Number of content download results to import at once into the chain
- fullMaxForkAncestry uint64 = params.FullImmutabilityThreshold // Maximum chain reorganisation (locally redeclared so tests can reduce it)
- lightMaxForkAncestry uint64 = params.LightImmutabilityThreshold // Maximum chain reorganisation (locally redeclared so tests can reduce it)
-
- reorgProtThreshold = 48 // Threshold number of recent blocks to disable mini reorg protection
- reorgProtHeaderDelay = 2 // Number of headers to delay delivering to cover mini reorgs
-
- fsHeaderSafetyNet = 2048 // Number of headers to discard in case a chain violation is detected
- fsHeaderContCheck = 3 * time.Second // Time interval to check for header continuations during state download
- fsMinFullBlocks = 64 // Number of blocks to retrieve fully even in snap sync
-)
-
-var (
- errBusy = errors.New("busy")
- errUnknownPeer = errors.New("peer is unknown or unhealthy")
- errBadPeer = errors.New("action from bad peer ignored")
- errStallingPeer = errors.New("peer is stalling")
- errUnsyncedPeer = errors.New("unsynced peer")
- errNoPeers = errors.New("no peers to keep download active")
- errTimeout = errors.New("timeout")
- errEmptyHeaderSet = errors.New("empty header set by peer")
- errPeersUnavailable = errors.New("no peers available or all tried for download")
- errInvalidAncestor = errors.New("retrieved ancestor is invalid")
- errInvalidChain = errors.New("retrieved hash chain is invalid")
- errInvalidBody = errors.New("retrieved block body is invalid")
- errInvalidReceipt = errors.New("retrieved receipt is invalid")
- errCancelStateFetch = errors.New("state data download canceled (requested)")
- errCancelContentProcessing = errors.New("content processing canceled (requested)")
- errCanceled = errors.New("syncing canceled (requested)")
- errTooOld = errors.New("peer's protocol version too old")
- errNoAncestorFound = errors.New("no common ancestor found")
- errNoPivotHeader = errors.New("pivot header is not found")
- ErrMergeTransition = errors.New("legacy sync reached the merge")
-)
-
-// peerDropFn is a callback type for dropping a peer detected as malicious.
-type peerDropFn func(id string)
-
-// badBlockFn is a callback for the async beacon sync to notify the caller that
-// the origin header requested to sync to, produced a chain with a bad block.
-type badBlockFn func(invalid *types.Header, origin *types.Header)
-
-// headerTask is a set of downloaded headers to queue along with their precomputed
-// hashes to avoid constant rehashing.
-type headerTask struct {
- headers []*types.Header
- hashes []common.Hash
-}
-
-type Downloader struct {
- mode atomic.Uint32 // Synchronisation mode defining the strategy used (per sync cycle), use d.getMode() to get the SyncMode
- mux *event.TypeMux // Event multiplexer to announce sync operation events
-
- genesis uint64 // Genesis block number to limit sync to (e.g. light client CHT)
- queue *queue // Scheduler for selecting the hashes to download
- peers *peerSet // Set of active peers from which download can proceed
-
- stateDB ethdb.Database // Database to state sync into (and deduplicate via)
-
- // Statistics
- syncStatsChainOrigin uint64 // Origin block number where syncing started at
- syncStatsChainHeight uint64 // Highest block number known when syncing started
- syncStatsLock sync.RWMutex // Lock protecting the sync stats fields
-
- lightchain LightChain
- blockchain BlockChain
-
- // Callbacks
- dropPeer peerDropFn // Drops a peer for misbehaving
- badBlock badBlockFn // Reports a block as rejected by the chain
-
- // Status
- synchroniseMock func(id string, hash common.Hash) error // Replacement for synchronise during testing
- synchronising atomic.Bool
- notified atomic.Bool
- committed atomic.Bool
- ancientLimit uint64 // The maximum block number which can be regarded as ancient data.
-
- // Channels
- headerProcCh chan *headerTask // Channel to feed the header processor new tasks
-
- // Skeleton sync
- skeleton *skeleton // Header skeleton to backfill the chain with (eth2 mode)
-
- // State sync
- pivotHeader *types.Header // Pivot block header to dynamically push the syncing state root
- pivotLock sync.RWMutex // Lock protecting pivot header reads from updates
-
- SnapSyncer *snap.Syncer // TODO(karalabe): make private! hack for now
- stateSyncStart chan *stateSync
-
- // Cancellation and termination
- cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop)
- cancelCh chan struct{} // Channel to cancel mid-flight syncs
- cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers
- cancelWg sync.WaitGroup // Make sure all fetcher goroutines have exited.
-
- quitCh chan struct{} // Quit channel to signal termination
- quitLock sync.Mutex // Lock to prevent double closes
-
- // Testing hooks
- syncInitHook func(uint64, uint64) // Method to call upon initiating a new sync run
- bodyFetchHook func([]*types.Header) // Method to call upon starting a block body fetch
- receiptFetchHook func([]*types.Header) // Method to call upon starting a receipt fetch
- chainInsertHook func([]*fetchResult) // Method to call upon inserting a chain of blocks (possibly in multiple invocations)
-
- // Progress reporting metrics
- syncStartBlock uint64 // Head snap block when Geth was started
- syncStartTime time.Time // Time instance when chain sync started
- syncLogTime time.Time // Time instance when status was last reported
-}
-
-// LightChain encapsulates functions required to synchronise a light chain.
-type LightChain interface {
- // HasHeader verifies a header's presence in the local chain.
- HasHeader(common.Hash, uint64) bool
-
- // GetHeaderByHash retrieves a header from the local chain.
- GetHeaderByHash(common.Hash) *types.Header
-
- // CurrentHeader retrieves the head header from the local chain.
- CurrentHeader() *types.Header
-
- // GetTd returns the total difficulty of a local block.
- GetTd(common.Hash, uint64) *big.Int
-
- // InsertHeaderChain inserts a batch of headers into the local chain.
- InsertHeaderChain([]*types.Header) (int, error)
-
- // SetHead rewinds the local chain to a new head.
- SetHead(uint64) error
-}
-
-// BlockChain encapsulates functions required to sync a (full or snap) blockchain.
-type BlockChain interface {
- LightChain
-
- // HasBlock verifies a block's presence in the local chain.
- HasBlock(common.Hash, uint64) bool
-
- // HasFastBlock verifies a snap block's presence in the local chain.
- HasFastBlock(common.Hash, uint64) bool
-
- // GetBlockByHash retrieves a block from the local chain.
- GetBlockByHash(common.Hash) *types.Block
-
- // CurrentBlock retrieves the head block from the local chain.
- CurrentBlock() *types.Header
-
- // CurrentSnapBlock retrieves the head snap block from the local chain.
- CurrentSnapBlock() *types.Header
-
- // SnapSyncCommitHead directly commits the head block to a certain entity.
- SnapSyncCommitHead(common.Hash) error
-
- // InsertChain inserts a batch of blocks into the local chain.
- InsertChain(types.Blocks) (int, error)
-
- // InsertReceiptChain inserts a batch of receipts into the local chain.
- InsertReceiptChain(types.Blocks, []types.Receipts, uint64) (int, error)
-
- // Snapshots returns the blockchain snapshot tree to paused it during sync.
- Snapshots() *snapshot.Tree
-
- // TrieDB retrieves the low level trie database used for interacting
- // with trie nodes.
- TrieDB() *trie.Database
-}
-
-// New creates a new downloader to fetch hashes and blocks from remote peers.
-func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, lightchain LightChain, dropPeer peerDropFn, success func()) *Downloader {
- if lightchain == nil {
- lightchain = chain
- }
- dl := &Downloader{
- stateDB: stateDb,
- mux: mux,
- queue: newQueue(blockCacheMaxItems, blockCacheInitialItems),
- peers: newPeerSet(),
- blockchain: chain,
- lightchain: lightchain,
- dropPeer: dropPeer,
- headerProcCh: make(chan *headerTask, 1),
- quitCh: make(chan struct{}),
- SnapSyncer: snap.NewSyncer(stateDb, chain.TrieDB().Scheme()),
- stateSyncStart: make(chan *stateSync),
- syncStartBlock: chain.CurrentSnapBlock().Number.Uint64(),
- }
- // Create the post-merge skeleton syncer and start the process
- dl.skeleton = newSkeleton(stateDb, dl.peers, dropPeer, newBeaconBackfiller(dl, success))
-
- go dl.stateFetcher()
- return dl
-}
-
-// Progress retrieves the synchronisation boundaries, specifically the origin
-// block where synchronisation started at (may have failed/suspended); the block
-// or header sync is currently at; and the latest known block which the sync targets.
-//
-// In addition, during the state download phase of snap synchronisation the number
-// of processed and the total number of known states are also returned. Otherwise
-// these are zero.
-func (d *Downloader) Progress() ethereum.SyncProgress {
- // Lock the current stats and return the progress
- d.syncStatsLock.RLock()
- defer d.syncStatsLock.RUnlock()
-
- current := uint64(0)
- mode := d.getMode()
- switch {
- case d.blockchain != nil && mode == FullSync:
- current = d.blockchain.CurrentBlock().Number.Uint64()
- case d.blockchain != nil && mode == SnapSync:
- current = d.blockchain.CurrentSnapBlock().Number.Uint64()
- case d.lightchain != nil:
- current = d.lightchain.CurrentHeader().Number.Uint64()
- default:
- log.Error("Unknown downloader chain/mode combo", "light", d.lightchain != nil, "full", d.blockchain != nil, "mode", mode)
- }
- progress, pending := d.SnapSyncer.Progress()
-
- return ethereum.SyncProgress{
- StartingBlock: d.syncStatsChainOrigin,
- CurrentBlock: current,
- HighestBlock: d.syncStatsChainHeight,
- SyncedAccounts: progress.AccountSynced,
- SyncedAccountBytes: uint64(progress.AccountBytes),
- SyncedBytecodes: progress.BytecodeSynced,
- SyncedBytecodeBytes: uint64(progress.BytecodeBytes),
- SyncedStorage: progress.StorageSynced,
- SyncedStorageBytes: uint64(progress.StorageBytes),
- HealedTrienodes: progress.TrienodeHealSynced,
- HealedTrienodeBytes: uint64(progress.TrienodeHealBytes),
- HealedBytecodes: progress.BytecodeHealSynced,
- HealedBytecodeBytes: uint64(progress.BytecodeHealBytes),
- HealingTrienodes: pending.TrienodeHeal,
- HealingBytecode: pending.BytecodeHeal,
- }
-}
-
-// RegisterPeer injects a new download peer into the set of block source to be
-// used for fetching hashes and blocks from.
-func (d *Downloader) RegisterPeer(id string, version uint, peer Peer) error {
- var logger log.Logger
- if len(id) < 16 {
- // Tests use short IDs, don't choke on them
- logger = log.New("peer", id)
- } else {
- logger = log.New("peer", id[:8])
- }
- logger.Trace("Registering sync peer")
- if err := d.peers.Register(newPeerConnection(id, version, peer, logger)); err != nil {
- logger.Error("Failed to register sync peer", "err", err)
- return err
- }
- return nil
-}
-
-// UnregisterPeer remove a peer from the known list, preventing any action from
-// the specified peer. An effort is also made to return any pending fetches into
-// the queue.
-func (d *Downloader) UnregisterPeer(id string) error {
- // Unregister the peer from the active peer set and revoke any fetch tasks
- var logger log.Logger
- if len(id) < 16 {
- // Tests use short IDs, don't choke on them
- logger = log.New("peer", id)
- } else {
- logger = log.New("peer", id[:8])
- }
- logger.Trace("Unregistering sync peer")
- if err := d.peers.Unregister(id); err != nil {
- logger.Error("Failed to unregister sync peer", "err", err)
- return err
- }
- d.queue.Revoke(id)
-
- return nil
-}
-
-// LegacySync tries to sync up our local block chain with a remote peer, both
-// adding various sanity checks as well as wrapping it with various log entries.
-func (d *Downloader) LegacySync(id string, head common.Hash, td, ttd *big.Int, mode SyncMode) error {
- err := d.synchronise(id, head, td, ttd, mode, false, nil)
-
- switch err {
- case nil, errBusy, errCanceled:
- return err
- }
- if errors.Is(err, errInvalidChain) || errors.Is(err, errBadPeer) || errors.Is(err, errTimeout) ||
- errors.Is(err, errStallingPeer) || errors.Is(err, errUnsyncedPeer) || errors.Is(err, errEmptyHeaderSet) ||
- errors.Is(err, errPeersUnavailable) || errors.Is(err, errTooOld) || errors.Is(err, errInvalidAncestor) {
- log.Warn("Synchronisation failed, dropping peer", "peer", id, "err", err)
- if d.dropPeer == nil {
- // The dropPeer method is nil when `--copydb` is used for a local copy.
- // Timeouts can occur if e.g. compaction hits at the wrong time, and can be ignored
- log.Warn("Downloader wants to drop peer, but peerdrop-function is not set", "peer", id)
- } else {
- d.dropPeer(id)
- }
- return err
- }
- if errors.Is(err, ErrMergeTransition) {
- return err // This is an expected fault, don't keep printing it in a spin-loop
- }
- log.Warn("Synchronisation failed, retrying", "err", err)
- return err
-}
-
-// synchronise will select the peer and use it for synchronising. If an empty string is given
-// it will use the best peer possible and synchronize if its TD is higher than our own. If any of the
-// checks fail an error will be returned. This method is synchronous
-func (d *Downloader) synchronise(id string, hash common.Hash, td, ttd *big.Int, mode SyncMode, beaconMode bool, beaconPing chan struct{}) error {
- // The beacon header syncer is async. It will start this synchronization and
- // will continue doing other tasks. However, if synchronization needs to be
- // cancelled, the syncer needs to know if we reached the startup point (and
- // inited the cancel channel) or not yet. Make sure that we'll signal even in
- // case of a failure.
- if beaconPing != nil {
- defer func() {
- select {
- case <-beaconPing: // already notified
- default:
- close(beaconPing) // weird exit condition, notify that it's safe to cancel (the nothing)
- }
- }()
- }
- // Mock out the synchronisation if testing
- if d.synchroniseMock != nil {
- return d.synchroniseMock(id, hash)
- }
- // Make sure only one goroutine is ever allowed past this point at once
- if !d.synchronising.CompareAndSwap(false, true) {
- return errBusy
- }
- defer d.synchronising.Store(false)
-
- // Post a user notification of the sync (only once per session)
- if d.notified.CompareAndSwap(false, true) {
- log.Info("Block synchronisation started")
- }
- if mode == SnapSync {
- // Snap sync will directly modify the persistent state, making the entire
- // trie database unusable until the state is fully synced. To prevent any
- // subsequent state reads, explicitly disable the trie database and state
- // syncer is responsible to address and correct any state missing.
- if d.blockchain.TrieDB().Scheme() == rawdb.PathScheme {
- if err := d.blockchain.TrieDB().Disable(); err != nil {
- return err
- }
- }
- // Snap sync uses the snapshot namespace to store potentially flaky data until
- // sync completely heals and finishes. Pause snapshot maintenance in the mean-
- // time to prevent access.
- if snapshots := d.blockchain.Snapshots(); snapshots != nil { // Only nil in tests
- snapshots.Disable()
- }
- }
- // Reset the queue, peer set and wake channels to clean any internal leftover state
- d.queue.Reset(blockCacheMaxItems, blockCacheInitialItems)
- d.peers.Reset()
-
- for _, ch := range []chan bool{d.queue.blockWakeCh, d.queue.receiptWakeCh} {
- select {
- case <-ch:
- default:
- }
- }
- for empty := false; !empty; {
- select {
- case <-d.headerProcCh:
- default:
- empty = true
- }
- }
- // Create cancel channel for aborting mid-flight and mark the master peer
- d.cancelLock.Lock()
- d.cancelCh = make(chan struct{})
- d.cancelPeer = id
- d.cancelLock.Unlock()
-
- defer d.Cancel() // No matter what, we can't leave the cancel channel open
-
- // Atomically set the requested sync mode
- d.mode.Store(uint32(mode))
-
- // Retrieve the origin peer and initiate the downloading process
- var p *peerConnection
- if !beaconMode { // Beacon mode doesn't need a peer to sync from
- p = d.peers.Peer(id)
- if p == nil {
- return errUnknownPeer
- }
- }
- if beaconPing != nil {
- close(beaconPing)
- }
- return d.syncWithPeer(p, hash, td, ttd, beaconMode)
-}
-
-func (d *Downloader) getMode() SyncMode {
- return SyncMode(d.mode.Load())
-}
-
-// syncWithPeer starts a block synchronization based on the hash chain from the
-// specified peer and head hash.
-func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd *big.Int, beaconMode bool) (err error) {
- d.mux.Post(StartEvent{})
- defer func() {
- // reset on error
- if err != nil {
- d.mux.Post(FailedEvent{err})
- } else {
- latest := d.lightchain.CurrentHeader()
- d.mux.Post(DoneEvent{latest})
- }
- }()
- mode := d.getMode()
-
- if !beaconMode {
- log.Debug("Synchronising with the network", "peer", p.id, "eth", p.version, "head", hash, "td", td, "mode", mode)
- } else {
- log.Debug("Backfilling with the network", "mode", mode)
- }
- defer func(start time.Time) {
- log.Debug("Synchronisation terminated", "elapsed", common.PrettyDuration(time.Since(start)))
- }(time.Now())
-
- // Look up the sync boundaries: the common ancestor and the target block
- var latest, pivot, final *types.Header
- if !beaconMode {
- // In legacy mode, use the master peer to retrieve the headers from
- latest, pivot, err = d.fetchHead(p)
- if err != nil {
- return err
- }
- } else {
- // In beacon mode, use the skeleton chain to retrieve the headers from
- latest, _, final, err = d.skeleton.Bounds()
- if err != nil {
- return err
- }
- if latest.Number.Uint64() > uint64(fsMinFullBlocks) {
- number := latest.Number.Uint64() - uint64(fsMinFullBlocks)
-
- // Retrieve the pivot header from the skeleton chain segment but
- // fallback to local chain if it's not found in skeleton space.
- if pivot = d.skeleton.Header(number); pivot == nil {
- _, oldest, _, _ := d.skeleton.Bounds() // error is already checked
- if number < oldest.Number.Uint64() {
- count := int(oldest.Number.Uint64() - number) // it's capped by fsMinFullBlocks
- headers := d.readHeaderRange(oldest, count)
- if len(headers) == count {
- pivot = headers[len(headers)-1]
- log.Warn("Retrieved pivot header from local", "number", pivot.Number, "hash", pivot.Hash(), "latest", latest.Number, "oldest", oldest.Number)
- }
- }
- }
- // Print an error log and return directly in case the pivot header
- // is still not found. It means the skeleton chain is not linked
- // correctly with local chain.
- if pivot == nil {
- log.Error("Pivot header is not found", "number", number)
- return errNoPivotHeader
- }
- }
- }
- // If no pivot block was returned, the head is below the min full block
- // threshold (i.e. new chain). In that case we won't really snap sync
- // anyway, but still need a valid pivot block to avoid some code hitting
- // nil panics on access.
- if mode == SnapSync && pivot == nil {
- pivot = d.blockchain.CurrentBlock()
- }
- height := latest.Number.Uint64()
-
- var origin uint64
- if !beaconMode {
- // In legacy mode, reach out to the network and find the ancestor
- origin, err = d.findAncestor(p, latest)
- if err != nil {
- return err
- }
- } else {
- // In beacon mode, use the skeleton chain for the ancestor lookup
- origin, err = d.findBeaconAncestor()
- if err != nil {
- return err
- }
- }
- d.syncStatsLock.Lock()
- if d.syncStatsChainHeight <= origin || d.syncStatsChainOrigin > origin {
- d.syncStatsChainOrigin = origin
- }
- d.syncStatsChainHeight = height
- d.syncStatsLock.Unlock()
-
- // Ensure our origin point is below any snap sync pivot point
- if mode == SnapSync {
- if height <= uint64(fsMinFullBlocks) {
- origin = 0
- } else {
- pivotNumber := pivot.Number.Uint64()
- if pivotNumber <= origin {
- origin = pivotNumber - 1
- }
- // Write out the pivot into the database so a rollback beyond it will
- // reenable snap sync
- rawdb.WriteLastPivotNumber(d.stateDB, pivotNumber)
- }
- }
- d.committed.Store(true)
- if mode == SnapSync && pivot.Number.Uint64() != 0 {
- d.committed.Store(false)
- }
- if mode == SnapSync {
- // Set the ancient data limitation. If we are running snap sync, all block
- // data older than ancientLimit will be written to the ancient store. More
- // recent data will be written to the active database and will wait for the
- // freezer to migrate.
- //
- // If the network is post-merge, use either the last announced finalized
- // block as the ancient limit, or if we haven't yet received one, the head-
- // a max fork ancestry limit. One quirky case if we've already passed the
- // finalized block, in which case the skeleton.Bounds will return nil and
- // we'll revert to head - 90K. That's fine, we're finishing sync anyway.
- //
- // For non-merged networks, if there is a checkpoint available, then calculate
- // the ancientLimit through that. Otherwise calculate the ancient limit through
- // the advertised height of the remote peer. This most is mostly a fallback for
- // legacy networks, but should eventually be dropped. TODO(karalabe).
- if beaconMode {
- // Beacon sync, use the latest finalized block as the ancient limit
- // or a reasonable height if no finalized block is yet announced.
- if final != nil {
- d.ancientLimit = final.Number.Uint64()
- } else if height > fullMaxForkAncestry+1 {
- d.ancientLimit = height - fullMaxForkAncestry - 1
- } else {
- d.ancientLimit = 0
- }
- } else {
- // Legacy sync, use the best announcement we have from the remote peer.
- // TODO(karalabe): Drop this pathway.
- if height > fullMaxForkAncestry+1 {
- d.ancientLimit = height - fullMaxForkAncestry - 1
- } else {
- d.ancientLimit = 0
- }
- }
- frozen, _ := d.stateDB.Ancients() // Ignore the error here since light client can also hit here.
-
- // If a part of blockchain data has already been written into active store,
- // disable the ancient style insertion explicitly.
- if origin >= frozen && frozen != 0 {
- d.ancientLimit = 0
- log.Info("Disabling direct-ancient mode", "origin", origin, "ancient", frozen-1)
- } else if d.ancientLimit > 0 {
- log.Debug("Enabling direct-ancient mode", "ancient", d.ancientLimit)
- }
- // Rewind the ancient store and blockchain if reorg happens.
- if origin+1 < frozen {
- if err := d.lightchain.SetHead(origin); err != nil {
- return err
- }
- }
- }
- // Initiate the sync using a concurrent header and content retrieval algorithm
- d.queue.Prepare(origin+1, mode)
- if d.syncInitHook != nil {
- d.syncInitHook(origin, height)
- }
- var headerFetcher func() error
- if !beaconMode {
- // In legacy mode, headers are retrieved from the network
- headerFetcher = func() error { return d.fetchHeaders(p, origin+1, latest.Number.Uint64()) }
- } else {
- // In beacon mode, headers are served by the skeleton syncer
- headerFetcher = func() error { return d.fetchBeaconHeaders(origin + 1) }
- }
- fetchers := []func() error{
- headerFetcher, // Headers are always retrieved
- func() error { return d.fetchBodies(origin+1, beaconMode) }, // Bodies are retrieved during normal and snap sync
- func() error { return d.fetchReceipts(origin+1, beaconMode) }, // Receipts are retrieved during snap sync
- func() error { return d.processHeaders(origin+1, td, ttd, beaconMode) },
- }
- if mode == SnapSync {
- d.pivotLock.Lock()
- d.pivotHeader = pivot
- d.pivotLock.Unlock()
-
- fetchers = append(fetchers, func() error { return d.processSnapSyncContent() })
- } else if mode == FullSync {
- fetchers = append(fetchers, func() error { return d.processFullSyncContent(ttd, beaconMode) })
- }
- return d.spawnSync(fetchers)
-}
-
-// spawnSync runs d.process and all given fetcher functions to completion in
-// separate goroutines, returning the first error that appears.
-func (d *Downloader) spawnSync(fetchers []func() error) error {
- errc := make(chan error, len(fetchers))
- d.cancelWg.Add(len(fetchers))
- for _, fn := range fetchers {
- fn := fn
- go func() { defer d.cancelWg.Done(); errc <- fn() }()
- }
- // Wait for the first error, then terminate the others.
- var err error
- for i := 0; i < len(fetchers); i++ {
- if i == len(fetchers)-1 {
- // Close the queue when all fetchers have exited.
- // This will cause the block processor to end when
- // it has processed the queue.
- d.queue.Close()
- }
- if got := <-errc; got != nil {
- err = got
- if got != errCanceled {
- break // receive a meaningful error, bubble it up
- }
- }
- }
- d.queue.Close()
- d.Cancel()
- return err
-}
-
-// cancel aborts all of the operations and resets the queue. However, cancel does
-// not wait for the running download goroutines to finish. This method should be
-// used when cancelling the downloads from inside the downloader.
-func (d *Downloader) cancel() {
- // Close the current cancel channel
- d.cancelLock.Lock()
- defer d.cancelLock.Unlock()
-
- if d.cancelCh != nil {
- select {
- case <-d.cancelCh:
- // Channel was already closed
- default:
- close(d.cancelCh)
- }
- }
-}
-
-// Cancel aborts all of the operations and waits for all download goroutines to
-// finish before returning.
-func (d *Downloader) Cancel() {
- d.cancel()
- d.cancelWg.Wait()
-}
-
-// Terminate interrupts the downloader, canceling all pending operations.
-// The downloader cannot be reused after calling Terminate.
-func (d *Downloader) Terminate() {
- // Close the termination channel (make sure double close is allowed)
- d.quitLock.Lock()
- select {
- case <-d.quitCh:
- default:
- close(d.quitCh)
-
- // Terminate the internal beacon syncer
- d.skeleton.Terminate()
- }
- d.quitLock.Unlock()
-
- // Cancel any pending download requests
- d.Cancel()
-}
-
-// fetchHead retrieves the head header and prior pivot block (if available) from
-// a remote peer.
-func (d *Downloader) fetchHead(p *peerConnection) (head *types.Header, pivot *types.Header, err error) {
- p.log.Debug("Retrieving remote chain head")
- mode := d.getMode()
-
- // Request the advertised remote head block and wait for the response
- latest, _ := p.peer.Head()
- fetch := 1
- if mode == SnapSync {
- fetch = 2 // head + pivot headers
- }
- headers, hashes, err := d.fetchHeadersByHash(p, latest, fetch, fsMinFullBlocks-1, true)
- if err != nil {
- return nil, nil, err
- }
- // Make sure the peer gave us at least one and at most the requested headers
- if len(headers) == 0 || len(headers) > fetch {
- return nil, nil, fmt.Errorf("%w: returned headers %d != requested %d", errBadPeer, len(headers), fetch)
- }
- // The first header needs to be the head, validate against the request. If
- // only 1 header was returned, make sure there's no pivot or there was not
- // one requested.
- head = headers[0]
- if len(headers) == 1 {
- if mode == SnapSync && head.Number.Uint64() > uint64(fsMinFullBlocks) {
- return nil, nil, fmt.Errorf("%w: no pivot included along head header", errBadPeer)
- }
- p.log.Debug("Remote head identified, no pivot", "number", head.Number, "hash", hashes[0])
- return head, nil, nil
- }
- // At this point we have 2 headers in total and the first is the
- // validated head of the chain. Check the pivot number and return,
- pivot = headers[1]
- if pivot.Number.Uint64() != head.Number.Uint64()-uint64(fsMinFullBlocks) {
- return nil, nil, fmt.Errorf("%w: remote pivot %d != requested %d", errInvalidChain, pivot.Number, head.Number.Uint64()-uint64(fsMinFullBlocks))
- }
- return head, pivot, nil
-}
-
-// calculateRequestSpan calculates what headers to request from a peer when trying to determine the
-// common ancestor.
-// It returns parameters to be used for peer.RequestHeadersByNumber:
-//
-// from - starting block number
-// count - number of headers to request
-// skip - number of headers to skip
-//
-// and also returns 'max', the last block which is expected to be returned by the remote peers,
-// given the (from,count,skip)
-func calculateRequestSpan(remoteHeight, localHeight uint64) (int64, int, int, uint64) {
- var (
- from int
- count int
- MaxCount = MaxHeaderFetch / 16
- )
- // requestHead is the highest block that we will ask for. If requestHead is not offset,
- // the highest block that we will get is 16 blocks back from head, which means we
- // will fetch 14 or 15 blocks unnecessarily in the case the height difference
- // between us and the peer is 1-2 blocks, which is most common
- requestHead := int(remoteHeight) - 1
- if requestHead < 0 {
- requestHead = 0
- }
- // requestBottom is the lowest block we want included in the query
- // Ideally, we want to include the one just below our own head
- requestBottom := int(localHeight - 1)
- if requestBottom < 0 {
- requestBottom = 0
- }
- totalSpan := requestHead - requestBottom
- span := 1 + totalSpan/MaxCount
- if span < 2 {
- span = 2
- }
- if span > 16 {
- span = 16
- }
-
- count = 1 + totalSpan/span
- if count > MaxCount {
- count = MaxCount
- }
- if count < 2 {
- count = 2
- }
- from = requestHead - (count-1)*span
- if from < 0 {
- from = 0
- }
- max := from + (count-1)*span
- return int64(from), count, span - 1, uint64(max)
-}
-
-// findAncestor tries to locate the common ancestor link of the local chain and
-// a remote peers blockchain. In the general case when our node was in sync and
-// on the correct chain, checking the top N links should already get us a match.
-// In the rare scenario when we ended up on a long reorganisation (i.e. none of
-// the head links match), we do a binary search to find the common ancestor.
-func (d *Downloader) findAncestor(p *peerConnection, remoteHeader *types.Header) (uint64, error) {
- // Figure out the valid ancestor range to prevent rewrite attacks
- var (
- floor = int64(-1)
- localHeight uint64
- remoteHeight = remoteHeader.Number.Uint64()
- )
- mode := d.getMode()
- switch mode {
- case FullSync:
- localHeight = d.blockchain.CurrentBlock().Number.Uint64()
- case SnapSync:
- localHeight = d.blockchain.CurrentSnapBlock().Number.Uint64()
- default:
- localHeight = d.lightchain.CurrentHeader().Number.Uint64()
- }
- p.log.Debug("Looking for common ancestor", "local", localHeight, "remote", remoteHeight)
-
- // Recap floor value for binary search
- maxForkAncestry := fullMaxForkAncestry
- if d.getMode() == LightSync {
- maxForkAncestry = lightMaxForkAncestry
- }
- if localHeight >= maxForkAncestry {
- // We're above the max reorg threshold, find the earliest fork point
- floor = int64(localHeight - maxForkAncestry)
- }
- // If we're doing a light sync, ensure the floor doesn't go below the CHT, as
- // all headers before that point will be missing.
- if mode == LightSync {
- // If we don't know the current CHT position, find it
- if d.genesis == 0 {
- header := d.lightchain.CurrentHeader()
- for header != nil {
- d.genesis = header.Number.Uint64()
- if floor >= int64(d.genesis)-1 {
- break
- }
- header = d.lightchain.GetHeaderByHash(header.ParentHash)
- }
- }
- // We already know the "genesis" block number, cap floor to that
- if floor < int64(d.genesis)-1 {
- floor = int64(d.genesis) - 1
- }
- }
-
- ancestor, err := d.findAncestorSpanSearch(p, mode, remoteHeight, localHeight, floor)
- if err == nil {
- return ancestor, nil
- }
- // The returned error was not nil.
- // If the error returned does not reflect that a common ancestor was not found, return it.
- // If the error reflects that a common ancestor was not found, continue to binary search,
- // where the error value will be reassigned.
- if !errors.Is(err, errNoAncestorFound) {
- return 0, err
- }
-
- ancestor, err = d.findAncestorBinarySearch(p, mode, remoteHeight, floor)
- if err != nil {
- return 0, err
- }
- return ancestor, nil
-}
-
-func (d *Downloader) findAncestorSpanSearch(p *peerConnection, mode SyncMode, remoteHeight, localHeight uint64, floor int64) (uint64, error) {
- from, count, skip, max := calculateRequestSpan(remoteHeight, localHeight)
-
- p.log.Trace("Span searching for common ancestor", "count", count, "from", from, "skip", skip)
- headers, hashes, err := d.fetchHeadersByNumber(p, uint64(from), count, skip, false)
- if err != nil {
- return 0, err
- }
- // Wait for the remote response to the head fetch
- number, hash := uint64(0), common.Hash{}
-
- // Make sure the peer actually gave something valid
- if len(headers) == 0 {
- p.log.Warn("Empty head header set")
- return 0, errEmptyHeaderSet
- }
- // Make sure the peer's reply conforms to the request
- for i, header := range headers {
- expectNumber := from + int64(i)*int64(skip+1)
- if number := header.Number.Int64(); number != expectNumber {
- p.log.Warn("Head headers broke chain ordering", "index", i, "requested", expectNumber, "received", number)
- return 0, fmt.Errorf("%w: %v", errInvalidChain, errors.New("head headers broke chain ordering"))
- }
- }
- // Check if a common ancestor was found
- for i := len(headers) - 1; i >= 0; i-- {
- // Skip any headers that underflow/overflow our requested set
- if headers[i].Number.Int64() < from || headers[i].Number.Uint64() > max {
- continue
- }
- // Otherwise check if we already know the header or not
- h := hashes[i]
- n := headers[i].Number.Uint64()
-
- var known bool
- switch mode {
- case FullSync:
- known = d.blockchain.HasBlock(h, n)
- case SnapSync:
- known = d.blockchain.HasFastBlock(h, n)
- default:
- known = d.lightchain.HasHeader(h, n)
- }
- if known {
- number, hash = n, h
- break
- }
- }
- // If the head fetch already found an ancestor, return
- if hash != (common.Hash{}) {
- if int64(number) <= floor {
- p.log.Warn("Ancestor below allowance", "number", number, "hash", hash, "allowance", floor)
- return 0, errInvalidAncestor
- }
- p.log.Debug("Found common ancestor", "number", number, "hash", hash)
- return number, nil
- }
- return 0, errNoAncestorFound
-}
-
-func (d *Downloader) findAncestorBinarySearch(p *peerConnection, mode SyncMode, remoteHeight uint64, floor int64) (uint64, error) {
- hash := common.Hash{}
-
- // Ancestor not found, we need to binary search over our chain
- start, end := uint64(0), remoteHeight
- if floor > 0 {
- start = uint64(floor)
- }
- p.log.Trace("Binary searching for common ancestor", "start", start, "end", end)
-
- for start+1 < end {
- // Split our chain interval in two, and request the hash to cross check
- check := (start + end) / 2
-
- headers, hashes, err := d.fetchHeadersByNumber(p, check, 1, 0, false)
- if err != nil {
- return 0, err
- }
- // Make sure the peer actually gave something valid
- if len(headers) != 1 {
- p.log.Warn("Multiple headers for single request", "headers", len(headers))
- return 0, fmt.Errorf("%w: multiple headers (%d) for single request", errBadPeer, len(headers))
- }
- // Modify the search interval based on the response
- h := hashes[0]
- n := headers[0].Number.Uint64()
-
- var known bool
- switch mode {
- case FullSync:
- known = d.blockchain.HasBlock(h, n)
- case SnapSync:
- known = d.blockchain.HasFastBlock(h, n)
- default:
- known = d.lightchain.HasHeader(h, n)
- }
- if !known {
- end = check
- continue
- }
- header := d.lightchain.GetHeaderByHash(h) // Independent of sync mode, header surely exists
- if header.Number.Uint64() != check {
- p.log.Warn("Received non requested header", "number", header.Number, "hash", header.Hash(), "request", check)
- return 0, fmt.Errorf("%w: non-requested header (%d)", errBadPeer, header.Number)
- }
- start = check
- hash = h
- }
- // Ensure valid ancestry and return
- if int64(start) <= floor {
- p.log.Warn("Ancestor below allowance", "number", start, "hash", hash, "allowance", floor)
- return 0, errInvalidAncestor
- }
- p.log.Debug("Found common ancestor", "number", start, "hash", hash)
- return start, nil
-}
-
-// fetchHeaders keeps retrieving headers concurrently from the number
-// requested, until no more are returned, potentially throttling on the way. To
-// facilitate concurrency but still protect against malicious nodes sending bad
-// headers, we construct a header chain skeleton using the "origin" peer we are
-// syncing with, and fill in the missing headers using anyone else. Headers from
-// other peers are only accepted if they map cleanly to the skeleton. If no one
-// can fill in the skeleton - not even the origin peer - it's assumed invalid and
-// the origin is dropped.
-func (d *Downloader) fetchHeaders(p *peerConnection, from uint64, head uint64) error {
- p.log.Debug("Directing header downloads", "origin", from)
- defer p.log.Debug("Header download terminated")
-
- // Start pulling the header chain skeleton until all is done
- var (
- skeleton = true // Skeleton assembly phase or finishing up
- pivoting = false // Whether the next request is pivot verification
- ancestor = from
- mode = d.getMode()
- )
- for {
- // Pull the next batch of headers, it either:
- // - Pivot check to see if the chain moved too far
- // - Skeleton retrieval to permit concurrent header fetches
- // - Full header retrieval if we're near the chain head
- var (
- headers []*types.Header
- hashes []common.Hash
- err error
- )
- switch {
- case pivoting:
- d.pivotLock.RLock()
- pivot := d.pivotHeader.Number.Uint64()
- d.pivotLock.RUnlock()
-
- p.log.Trace("Fetching next pivot header", "number", pivot+uint64(fsMinFullBlocks))
- headers, hashes, err = d.fetchHeadersByNumber(p, pivot+uint64(fsMinFullBlocks), 2, fsMinFullBlocks-9, false) // move +64 when it's 2x64-8 deep
-
- case skeleton:
- p.log.Trace("Fetching skeleton headers", "count", MaxHeaderFetch, "from", from)
- headers, hashes, err = d.fetchHeadersByNumber(p, from+uint64(MaxHeaderFetch)-1, MaxSkeletonSize, MaxHeaderFetch-1, false)
-
- default:
- p.log.Trace("Fetching full headers", "count", MaxHeaderFetch, "from", from)
- headers, hashes, err = d.fetchHeadersByNumber(p, from, MaxHeaderFetch, 0, false)
- }
- switch err {
- case nil:
- // Headers retrieved, continue with processing
-
- case errCanceled:
- // Sync cancelled, no issue, propagate up
- return err
-
- default:
- // Header retrieval either timed out, or the peer failed in some strange way
- // (e.g. disconnect). Consider the master peer bad and drop
- d.dropPeer(p.id)
-
- // Finish the sync gracefully instead of dumping the gathered data though
- for _, ch := range []chan bool{d.queue.blockWakeCh, d.queue.receiptWakeCh} {
- select {
- case ch <- false:
- case <-d.cancelCh:
- }
- }
- select {
- case d.headerProcCh <- nil:
- case <-d.cancelCh:
- }
- return fmt.Errorf("%w: header request failed: %v", errBadPeer, err)
- }
- // If the pivot is being checked, move if it became stale and run the real retrieval
- var pivot uint64
-
- d.pivotLock.RLock()
- if d.pivotHeader != nil {
- pivot = d.pivotHeader.Number.Uint64()
- }
- d.pivotLock.RUnlock()
-
- if pivoting {
- if len(headers) == 2 {
- if have, want := headers[0].Number.Uint64(), pivot+uint64(fsMinFullBlocks); have != want {
- log.Warn("Peer sent invalid next pivot", "have", have, "want", want)
- return fmt.Errorf("%w: next pivot number %d != requested %d", errInvalidChain, have, want)
- }
- if have, want := headers[1].Number.Uint64(), pivot+2*uint64(fsMinFullBlocks)-8; have != want {
- log.Warn("Peer sent invalid pivot confirmer", "have", have, "want", want)
- return fmt.Errorf("%w: next pivot confirmer number %d != requested %d", errInvalidChain, have, want)
- }
- log.Warn("Pivot seemingly stale, moving", "old", pivot, "new", headers[0].Number)
- pivot = headers[0].Number.Uint64()
-
- d.pivotLock.Lock()
- d.pivotHeader = headers[0]
- d.pivotLock.Unlock()
-
- // Write out the pivot into the database so a rollback beyond
- // it will reenable snap sync and update the state root that
- // the state syncer will be downloading.
- rawdb.WriteLastPivotNumber(d.stateDB, pivot)
- }
- // Disable the pivot check and fetch the next batch of headers
- pivoting = false
- continue
- }
- // If the skeleton's finished, pull any remaining head headers directly from the origin
- if skeleton && len(headers) == 0 {
- // A malicious node might withhold advertised headers indefinitely
- if from+uint64(MaxHeaderFetch)-1 <= head {
- p.log.Warn("Peer withheld skeleton headers", "advertised", head, "withheld", from+uint64(MaxHeaderFetch)-1)
- return fmt.Errorf("%w: withheld skeleton headers: advertised %d, withheld #%d", errStallingPeer, head, from+uint64(MaxHeaderFetch)-1)
- }
- p.log.Debug("No skeleton, fetching headers directly")
- skeleton = false
- continue
- }
- // If no more headers are inbound, notify the content fetchers and return
- if len(headers) == 0 {
- // Don't abort header fetches while the pivot is downloading
- if !d.committed.Load() && pivot <= from {
- p.log.Debug("No headers, waiting for pivot commit")
- select {
- case <-time.After(fsHeaderContCheck):
- continue
- case <-d.cancelCh:
- return errCanceled
- }
- }
- // Pivot done (or not in snap sync) and no more headers, terminate the process
- p.log.Debug("No more headers available")
- select {
- case d.headerProcCh <- nil:
- return nil
- case <-d.cancelCh:
- return errCanceled
- }
- }
- // If we received a skeleton batch, resolve internals concurrently
- var progressed bool
- if skeleton {
- filled, hashset, proced, err := d.fillHeaderSkeleton(from, headers)
- if err != nil {
- p.log.Debug("Skeleton chain invalid", "err", err)
- return fmt.Errorf("%w: %v", errInvalidChain, err)
- }
- headers = filled[proced:]
- hashes = hashset[proced:]
-
- progressed = proced > 0
- from += uint64(proced)
- } else {
- // A malicious node might withhold advertised headers indefinitely
- if n := len(headers); n < MaxHeaderFetch && headers[n-1].Number.Uint64() < head {
- p.log.Warn("Peer withheld headers", "advertised", head, "delivered", headers[n-1].Number.Uint64())
- return fmt.Errorf("%w: withheld headers: advertised %d, delivered %d", errStallingPeer, head, headers[n-1].Number.Uint64())
- }
- // If we're closing in on the chain head, but haven't yet reached it, delay
- // the last few headers so mini reorgs on the head don't cause invalid hash
- // chain errors.
- if n := len(headers); n > 0 {
- // Retrieve the current head we're at
- var head uint64
- if mode == LightSync {
- head = d.lightchain.CurrentHeader().Number.Uint64()
- } else {
- head = d.blockchain.CurrentSnapBlock().Number.Uint64()
- if full := d.blockchain.CurrentBlock().Number.Uint64(); head < full {
- head = full
- }
- }
- // If the head is below the common ancestor, we're actually deduplicating
- // already existing chain segments, so use the ancestor as the fake head.
- // Otherwise, we might end up delaying header deliveries pointlessly.
- if head < ancestor {
- head = ancestor
- }
- // If the head is way older than this batch, delay the last few headers
- if head+uint64(reorgProtThreshold) < headers[n-1].Number.Uint64() {
- delay := reorgProtHeaderDelay
- if delay > n {
- delay = n
- }
- headers = headers[:n-delay]
- hashes = hashes[:n-delay]
- }
- }
- }
- // If no headers have been delivered, or all of them have been delayed,
- // sleep a bit and retry. Take care with headers already consumed during
- // skeleton filling
- if len(headers) == 0 && !progressed {
- p.log.Trace("All headers delayed, waiting")
- select {
- case <-time.After(fsHeaderContCheck):
- continue
- case <-d.cancelCh:
- return errCanceled
- }
- }
- // Insert any remaining new headers and fetch the next batch
- if len(headers) > 0 {
- p.log.Trace("Scheduling new headers", "count", len(headers), "from", from)
- select {
- case d.headerProcCh <- &headerTask{
- headers: headers,
- hashes: hashes,
- }:
- case <-d.cancelCh:
- return errCanceled
- }
- from += uint64(len(headers))
- }
- // If we're still skeleton filling snap sync, check pivot staleness
- // before continuing to the next skeleton filling
- if skeleton && pivot > 0 {
- pivoting = true
- }
- }
-}
-
-// fillHeaderSkeleton concurrently retrieves headers from all our available peers
-// and maps them to the provided skeleton header chain.
-//
-// Any partial results from the beginning of the skeleton is (if possible) forwarded
-// immediately to the header processor to keep the rest of the pipeline full even
-// in the case of header stalls.
-//
-// The method returns the entire filled skeleton and also the number of headers
-// already forwarded for processing.
-func (d *Downloader) fillHeaderSkeleton(from uint64, skeleton []*types.Header) ([]*types.Header, []common.Hash, int, error) {
- log.Debug("Filling up skeleton", "from", from)
- d.queue.ScheduleSkeleton(from, skeleton)
-
- err := d.concurrentFetch((*headerQueue)(d), false)
- if err != nil {
- log.Debug("Skeleton fill failed", "err", err)
- }
- filled, hashes, proced := d.queue.RetrieveHeaders()
- if err == nil {
- log.Debug("Skeleton fill succeeded", "filled", len(filled), "processed", proced)
- }
- return filled, hashes, proced, err
-}
-
-// fetchBodies iteratively downloads the scheduled block bodies, taking any
-// available peers, reserving a chunk of blocks for each, waiting for delivery
-// and also periodically checking for timeouts.
-func (d *Downloader) fetchBodies(from uint64, beaconMode bool) error {
- log.Debug("Downloading block bodies", "origin", from)
- err := d.concurrentFetch((*bodyQueue)(d), beaconMode)
-
- log.Debug("Block body download terminated", "err", err)
- return err
-}
-
-// fetchReceipts iteratively downloads the scheduled block receipts, taking any
-// available peers, reserving a chunk of receipts for each, waiting for delivery
-// and also periodically checking for timeouts.
-func (d *Downloader) fetchReceipts(from uint64, beaconMode bool) error {
- log.Debug("Downloading receipts", "origin", from)
- err := d.concurrentFetch((*receiptQueue)(d), beaconMode)
-
- log.Debug("Receipt download terminated", "err", err)
- return err
-}
-
-// processHeaders takes batches of retrieved headers from an input channel and
-// keeps processing and scheduling them into the header chain and downloader's
-// queue until the stream ends or a failure occurs.
-func (d *Downloader) processHeaders(origin uint64, td, ttd *big.Int, beaconMode bool) error {
- var (
- mode = d.getMode()
- gotHeaders = false // Wait for batches of headers to process
- )
- for {
- select {
- case <-d.cancelCh:
- return errCanceled
-
- case task := <-d.headerProcCh:
- // Terminate header processing if we synced up
- if task == nil || len(task.headers) == 0 {
- // Notify everyone that headers are fully processed
- for _, ch := range []chan bool{d.queue.blockWakeCh, d.queue.receiptWakeCh} {
- select {
- case ch <- false:
- case <-d.cancelCh:
- }
- }
- // If we're in legacy sync mode, we need to check total difficulty
- // violations from malicious peers. That is not needed in beacon
- // mode and we can skip to terminating sync.
- if !beaconMode {
- // If no headers were retrieved at all, the peer violated its TD promise that it had a
- // better chain compared to ours. The only exception is if its promised blocks were
- // already imported by other means (e.g. fetcher):
- //
- // R , L : Both at block 10
- // R: Mine block 11, and propagate it to L
- // L: Queue block 11 for import
- // L: Notice that R's head and TD increased compared to ours, start sync
- // L: Import of block 11 finishes
- // L: Sync begins, and finds common ancestor at 11
- // L: Request new headers up from 11 (R's TD was higher, it must have something)
- // R: Nothing to give
- if mode != LightSync {
- head := d.blockchain.CurrentBlock()
- if !gotHeaders && td.Cmp(d.blockchain.GetTd(head.Hash(), head.Number.Uint64())) > 0 {
- return errStallingPeer
- }
- }
- // If snap or light syncing, ensure promised headers are indeed delivered. This is
- // needed to detect scenarios where an attacker feeds a bad pivot and then bails out
- // of delivering the post-pivot blocks that would flag the invalid content.
- //
- // This check cannot be executed "as is" for full imports, since blocks may still be
- // queued for processing when the header download completes. However, as long as the
- // peer gave us something useful, we're already happy/progressed (above check).
- if mode == SnapSync || mode == LightSync {
- head := d.lightchain.CurrentHeader()
- if td.Cmp(d.lightchain.GetTd(head.Hash(), head.Number.Uint64())) > 0 {
- return errStallingPeer
- }
- }
- }
- return nil
- }
- // Otherwise split the chunk of headers into batches and process them
- headers, hashes := task.headers, task.hashes
-
- gotHeaders = true
- for len(headers) > 0 {
- // Terminate if something failed in between processing chunks
- select {
- case <-d.cancelCh:
- return errCanceled
- default:
- }
- // Select the next chunk of headers to import
- limit := maxHeadersProcess
- if limit > len(headers) {
- limit = len(headers)
- }
- chunkHeaders := headers[:limit]
- chunkHashes := hashes[:limit]
-
- // In case of header only syncing, validate the chunk immediately
- if mode == SnapSync || mode == LightSync {
- // Although the received headers might be all valid, a legacy
- // PoW/PoA sync must not accept post-merge headers. Make sure
- // that any transition is rejected at this point.
- var (
- rejected []*types.Header
- td *big.Int
- )
- if !beaconMode && ttd != nil {
- td = d.blockchain.GetTd(chunkHeaders[0].ParentHash, chunkHeaders[0].Number.Uint64()-1)
- if td == nil {
- // This should never really happen, but handle gracefully for now
- log.Error("Failed to retrieve parent header TD", "number", chunkHeaders[0].Number.Uint64()-1, "hash", chunkHeaders[0].ParentHash)
- return fmt.Errorf("%w: parent TD missing", errInvalidChain)
- }
- for i, header := range chunkHeaders {
- td = new(big.Int).Add(td, header.Difficulty)
- if td.Cmp(ttd) >= 0 {
- // Terminal total difficulty reached, allow the last header in
- if new(big.Int).Sub(td, header.Difficulty).Cmp(ttd) < 0 {
- chunkHeaders, rejected = chunkHeaders[:i+1], chunkHeaders[i+1:]
- if len(rejected) > 0 {
- // Make a nicer user log as to the first TD truly rejected
- td = new(big.Int).Add(td, rejected[0].Difficulty)
- }
- } else {
- chunkHeaders, rejected = chunkHeaders[:i], chunkHeaders[i:]
- }
- break
- }
- }
- }
- if len(chunkHeaders) > 0 {
- if n, err := d.lightchain.InsertHeaderChain(chunkHeaders); err != nil {
- log.Warn("Invalid header encountered", "number", chunkHeaders[n].Number, "hash", chunkHashes[n], "parent", chunkHeaders[n].ParentHash, "err", err)
- return fmt.Errorf("%w: %v", errInvalidChain, err)
- }
- }
- if len(rejected) != 0 {
- log.Info("Legacy sync reached merge threshold", "number", rejected[0].Number, "hash", rejected[0].Hash(), "td", td, "ttd", ttd)
- return ErrMergeTransition
- }
- }
- // Unless we're doing light chains, schedule the headers for associated content retrieval
- if mode == FullSync || mode == SnapSync {
- // If we've reached the allowed number of pending headers, stall a bit
- for d.queue.PendingBodies() >= maxQueuedHeaders || d.queue.PendingReceipts() >= maxQueuedHeaders {
- select {
- case <-d.cancelCh:
- return errCanceled
- case <-time.After(time.Second):
- }
- }
- // Otherwise insert the headers for content retrieval
- inserts := d.queue.Schedule(chunkHeaders, chunkHashes, origin)
- if len(inserts) != len(chunkHeaders) {
- return fmt.Errorf("%w: stale headers", errBadPeer)
- }
- }
- headers = headers[limit:]
- hashes = hashes[limit:]
- origin += uint64(limit)
- }
- // Update the highest block number we know if a higher one is found.
- d.syncStatsLock.Lock()
- if d.syncStatsChainHeight < origin {
- d.syncStatsChainHeight = origin - 1
- }
- d.syncStatsLock.Unlock()
-
- // Signal the content downloaders of the availability of new tasks
- for _, ch := range []chan bool{d.queue.blockWakeCh, d.queue.receiptWakeCh} {
- select {
- case ch <- true:
- default:
- }
- }
- }
- }
-}
-
-// processFullSyncContent takes fetch results from the queue and imports them into the chain.
-func (d *Downloader) processFullSyncContent(ttd *big.Int, beaconMode bool) error {
- for {
- results := d.queue.Results(true)
- if len(results) == 0 {
- return nil
- }
- if d.chainInsertHook != nil {
- d.chainInsertHook(results)
- }
- // Although the received blocks might be all valid, a legacy PoW/PoA sync
- // must not accept post-merge blocks. Make sure that pre-merge blocks are
- // imported, but post-merge ones are rejected.
- var (
- rejected []*fetchResult
- td *big.Int
- )
- if !beaconMode && ttd != nil {
- td = d.blockchain.GetTd(results[0].Header.ParentHash, results[0].Header.Number.Uint64()-1)
- if td == nil {
- // This should never really happen, but handle gracefully for now
- log.Error("Failed to retrieve parent block TD", "number", results[0].Header.Number.Uint64()-1, "hash", results[0].Header.ParentHash)
- return fmt.Errorf("%w: parent TD missing", errInvalidChain)
- }
- for i, result := range results {
- td = new(big.Int).Add(td, result.Header.Difficulty)
- if td.Cmp(ttd) >= 0 {
- // Terminal total difficulty reached, allow the last block in
- if new(big.Int).Sub(td, result.Header.Difficulty).Cmp(ttd) < 0 {
- results, rejected = results[:i+1], results[i+1:]
- if len(rejected) > 0 {
- // Make a nicer user log as to the first TD truly rejected
- td = new(big.Int).Add(td, rejected[0].Header.Difficulty)
- }
- } else {
- results, rejected = results[:i], results[i:]
- }
- break
- }
- }
- }
- if err := d.importBlockResults(results); err != nil {
- return err
- }
- if len(rejected) != 0 {
- log.Info("Legacy sync reached merge threshold", "number", rejected[0].Header.Number, "hash", rejected[0].Header.Hash(), "td", td, "ttd", ttd)
- return ErrMergeTransition
- }
- }
-}
-
-func (d *Downloader) importBlockResults(results []*fetchResult) error {
- // Check for any early termination requests
- if len(results) == 0 {
- return nil
- }
- select {
- case <-d.quitCh:
- return errCancelContentProcessing
- default:
- }
- // Retrieve a batch of results to import
- first, last := results[0].Header, results[len(results)-1].Header
- log.Debug("Inserting downloaded chain", "items", len(results),
- "firstnum", first.Number, "firsthash", first.Hash(),
- "lastnum", last.Number, "lasthash", last.Hash(),
- )
- blocks := make([]*types.Block, len(results))
- for i, result := range results {
- blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals)
- }
- // Downloaded blocks are always regarded as trusted after the
- // transition. Because the downloaded chain is guided by the
- // consensus-layer.
- if index, err := d.blockchain.InsertChain(blocks); err != nil {
- if index < len(results) {
- log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err)
-
- // In post-merge, notify the engine API of encountered bad chains
- if d.badBlock != nil {
- head, _, _, err := d.skeleton.Bounds()
- if err != nil {
- log.Error("Failed to retrieve beacon bounds for bad block reporting", "err", err)
- } else {
- d.badBlock(blocks[index].Header(), head)
- }
- }
- } else {
- // The InsertChain method in blockchain.go will sometimes return an out-of-bounds index,
- // when it needs to preprocess blocks to import a sidechain.
- // The importer will put together a new list of blocks to import, which is a superset
- // of the blocks delivered from the downloader, and the indexing will be off.
- log.Debug("Downloaded item processing failed on sidechain import", "index", index, "err", err)
- }
- return fmt.Errorf("%w: %v", errInvalidChain, err)
- }
- return nil
-}
-
-// processSnapSyncContent takes fetch results from the queue and writes them to the
-// database. It also controls the synchronisation of state nodes of the pivot block.
-func (d *Downloader) processSnapSyncContent() error {
- // Start syncing state of the reported head block. This should get us most of
- // the state of the pivot block.
- d.pivotLock.RLock()
- sync := d.syncState(d.pivotHeader.Root)
- d.pivotLock.RUnlock()
-
- defer func() {
- // The `sync` object is replaced every time the pivot moves. We need to
- // defer close the very last active one, hence the lazy evaluation vs.
- // calling defer sync.Cancel() !!!
- sync.Cancel()
- }()
-
- closeOnErr := func(s *stateSync) {
- if err := s.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled && err != snap.ErrCancelled {
- d.queue.Close() // wake up Results
- }
- }
- go closeOnErr(sync)
-
- // To cater for moving pivot points, track the pivot block and subsequently
- // accumulated download results separately.
- //
- // These will be nil up to the point where we reach the pivot, and will only
- // be set temporarily if the synced blocks are piling up, but the pivot is
- // still busy downloading. In that case, we need to occasionally check for
- // pivot moves, so need to unblock the loop. These fields will accumulate
- // the results in the meantime.
- //
- // Note, there's no issue with memory piling up since after 64 blocks the
- // pivot will forcefully move so these accumulators will be dropped.
- var (
- oldPivot *fetchResult // Locked in pivot block, might change eventually
- oldTail []*fetchResult // Downloaded content after the pivot
- )
- for {
- // Wait for the next batch of downloaded data to be available. If we have
- // not yet reached the pivot point, wait blockingly as there's no need to
- // spin-loop check for pivot moves. If we reached the pivot but have not
- // yet processed it, check for results async, so we might notice pivot
- // moves while state syncing. If the pivot was passed fully, block again
- // as there's no more reason to check for pivot moves at all.
- results := d.queue.Results(oldPivot == nil)
- if len(results) == 0 {
- // If pivot sync is done, stop
- if d.committed.Load() {
- d.reportSnapSyncProgress(true)
- return sync.Cancel()
- }
- // If sync failed, stop
- select {
- case <-d.cancelCh:
- sync.Cancel()
- return errCanceled
- default:
- }
- }
- if d.chainInsertHook != nil {
- d.chainInsertHook(results)
- }
- d.reportSnapSyncProgress(false)
-
- // If we haven't downloaded the pivot block yet, check pivot staleness
- // notifications from the header downloader
- d.pivotLock.RLock()
- pivot := d.pivotHeader
- d.pivotLock.RUnlock()
-
- if oldPivot == nil { // no results piling up, we can move the pivot
- if !d.committed.Load() { // not yet passed the pivot, we can move the pivot
- if pivot.Root != sync.root { // pivot position changed, we can move the pivot
- sync.Cancel()
- sync = d.syncState(pivot.Root)
-
- go closeOnErr(sync)
- }
- }
- } else { // results already piled up, consume before handling pivot move
- results = append(append([]*fetchResult{oldPivot}, oldTail...), results...)
- }
- // Split around the pivot block and process the two sides via snap/full sync
- if !d.committed.Load() {
- latest := results[len(results)-1].Header
- // If the height is above the pivot block by 2 sets, it means the pivot
- // become stale in the network, and it was garbage collected, move to a
- // new pivot.
- //
- // Note, we have `reorgProtHeaderDelay` number of blocks withheld, Those
- // need to be taken into account, otherwise we're detecting the pivot move
- // late and will drop peers due to unavailable state!!!
- if height := latest.Number.Uint64(); height >= pivot.Number.Uint64()+2*uint64(fsMinFullBlocks)-uint64(reorgProtHeaderDelay) {
- log.Warn("Pivot became stale, moving", "old", pivot.Number.Uint64(), "new", height-uint64(fsMinFullBlocks)+uint64(reorgProtHeaderDelay))
- pivot = results[len(results)-1-fsMinFullBlocks+reorgProtHeaderDelay].Header // must exist as lower old pivot is uncommitted
-
- d.pivotLock.Lock()
- d.pivotHeader = pivot
- d.pivotLock.Unlock()
-
- // Write out the pivot into the database so a rollback beyond it will
- // reenable snap sync
- rawdb.WriteLastPivotNumber(d.stateDB, pivot.Number.Uint64())
- }
- }
- P, beforeP, afterP := splitAroundPivot(pivot.Number.Uint64(), results)
- if err := d.commitSnapSyncData(beforeP, sync); err != nil {
- return err
- }
- if P != nil {
- // If new pivot block found, cancel old state retrieval and restart
- if oldPivot != P {
- sync.Cancel()
- sync = d.syncState(P.Header.Root)
-
- go closeOnErr(sync)
- oldPivot = P
- }
- // Wait for completion, occasionally checking for pivot staleness
- select {
- case <-sync.done:
- if sync.err != nil {
- return sync.err
- }
- if err := d.commitPivotBlock(P); err != nil {
- return err
- }
- oldPivot = nil
-
- case <-time.After(time.Second):
- oldTail = afterP
- continue
- }
- }
- // Fast sync done, pivot commit done, full import
- if err := d.importBlockResults(afterP); err != nil {
- return err
- }
- }
-}
-
-func splitAroundPivot(pivot uint64, results []*fetchResult) (p *fetchResult, before, after []*fetchResult) {
- if len(results) == 0 {
- return nil, nil, nil
- }
- if lastNum := results[len(results)-1].Header.Number.Uint64(); lastNum < pivot {
- // the pivot is somewhere in the future
- return nil, results, nil
- }
- // This can also be optimized, but only happens very seldom
- for _, result := range results {
- num := result.Header.Number.Uint64()
- switch {
- case num < pivot:
- before = append(before, result)
- case num == pivot:
- p = result
- default:
- after = append(after, result)
- }
- }
- return p, before, after
-}
-
-func (d *Downloader) commitSnapSyncData(results []*fetchResult, stateSync *stateSync) error {
- // Check for any early termination requests
- if len(results) == 0 {
- return nil
- }
- select {
- case <-d.quitCh:
- return errCancelContentProcessing
- case <-stateSync.done:
- if err := stateSync.Wait(); err != nil {
- return err
- }
- default:
- }
- // Retrieve the batch of results to import
- first, last := results[0].Header, results[len(results)-1].Header
- log.Debug("Inserting snap-sync blocks", "items", len(results),
- "firstnum", first.Number, "firsthash", first.Hash(),
- "lastnumn", last.Number, "lasthash", last.Hash(),
- )
- blocks := make([]*types.Block, len(results))
- receipts := make([]types.Receipts, len(results))
- for i, result := range results {
- blocks[i] = types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals)
- receipts[i] = result.Receipts
- }
- if index, err := d.blockchain.InsertReceiptChain(blocks, receipts, d.ancientLimit); err != nil {
- log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err)
- return fmt.Errorf("%w: %v", errInvalidChain, err)
- }
- return nil
-}
-
-func (d *Downloader) commitPivotBlock(result *fetchResult) error {
- block := types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles).WithWithdrawals(result.Withdrawals)
- log.Debug("Committing snap sync pivot as new head", "number", block.Number(), "hash", block.Hash())
-
- // Commit the pivot block as the new head, will require full sync from here on
- if _, err := d.blockchain.InsertReceiptChain([]*types.Block{block}, []types.Receipts{result.Receipts}, d.ancientLimit); err != nil {
- return err
- }
- if err := d.blockchain.SnapSyncCommitHead(block.Hash()); err != nil {
- return err
- }
- d.committed.Store(true)
- return nil
-}
-
-// DeliverSnapPacket is invoked from a peer's message handler when it transmits a
-// data packet for the local node to consume.
-func (d *Downloader) DeliverSnapPacket(peer *snap.Peer, packet snap.Packet) error {
- switch packet := packet.(type) {
- case *snap.AccountRangePacket:
- hashes, accounts, err := packet.Unpack()
- if err != nil {
- return err
- }
- return d.SnapSyncer.OnAccounts(peer, packet.ID, hashes, accounts, packet.Proof)
-
- case *snap.StorageRangesPacket:
- hashset, slotset := packet.Unpack()
- return d.SnapSyncer.OnStorage(peer, packet.ID, hashset, slotset, packet.Proof)
-
- case *snap.ByteCodesPacket:
- return d.SnapSyncer.OnByteCodes(peer, packet.ID, packet.Codes)
-
- case *snap.TrieNodesPacket:
- return d.SnapSyncer.OnTrieNodes(peer, packet.ID, packet.Nodes)
-
- default:
- return fmt.Errorf("unexpected snap packet type: %T", packet)
- }
-}
-
-// readHeaderRange returns a list of headers, using the given last header as the base,
-// and going backwards towards genesis. This method assumes that the caller already has
-// placed a reasonable cap on count.
-func (d *Downloader) readHeaderRange(last *types.Header, count int) []*types.Header {
- var (
- current = last
- headers []*types.Header
- )
- for {
- parent := d.lightchain.GetHeaderByHash(current.ParentHash)
- if parent == nil {
- break // The chain is not continuous, or the chain is exhausted
- }
- headers = append(headers, parent)
- if len(headers) >= count {
- break
- }
- current = parent
- }
- return headers
-}
-
-// reportSnapSyncProgress calculates various status reports and provides it to the user.
-func (d *Downloader) reportSnapSyncProgress(force bool) {
- // Initialize the sync start time if it's the first time we're reporting
- if d.syncStartTime.IsZero() {
- d.syncStartTime = time.Now().Add(-time.Millisecond) // -1ms offset to avoid division by zero
- }
- // Don't report all the events, just occasionally
- if !force && time.Since(d.syncLogTime) < 8*time.Second {
- return
- }
- // Don't report anything until we have a meaningful progress
- var (
- headerBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerHeaderTable)
- bodyBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerBodiesTable)
- receiptBytes, _ = d.stateDB.AncientSize(rawdb.ChainFreezerReceiptTable)
- )
- syncedBytes := common.StorageSize(headerBytes + bodyBytes + receiptBytes)
- if syncedBytes == 0 {
- return
- }
- var (
- header = d.blockchain.CurrentHeader()
- block = d.blockchain.CurrentSnapBlock()
- )
- syncedBlocks := block.Number.Uint64() - d.syncStartBlock
- if syncedBlocks == 0 {
- return
- }
- // Retrieve the current chain head and calculate the ETA
- latest, _, _, err := d.skeleton.Bounds()
- if err != nil {
- // We're going to cheat for non-merged networks, but that's fine
- latest = d.pivotHeader
- }
- if latest == nil {
- // This should really never happen, but add some defensive code for now.
- // TODO(karalabe): Remove it eventually if we don't see it blow.
- log.Error("Nil latest block in sync progress report")
- return
- }
- var (
- left = latest.Number.Uint64() - block.Number.Uint64()
- eta = time.Since(d.syncStartTime) / time.Duration(syncedBlocks) * time.Duration(left)
-
- progress = fmt.Sprintf("%.2f%%", float64(block.Number.Uint64())*100/float64(latest.Number.Uint64()))
- headers = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(header.Number.Uint64()), common.StorageSize(headerBytes).TerminalString())
- bodies = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(block.Number.Uint64()), common.StorageSize(bodyBytes).TerminalString())
- receipts = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(block.Number.Uint64()), common.StorageSize(receiptBytes).TerminalString())
- )
- log.Info("Syncing: chain download in progress", "synced", progress, "chain", syncedBytes, "headers", headers, "bodies", bodies, "receipts", receipts, "eta", common.PrettyDuration(eta))
- d.syncLogTime = time.Now()
-}
diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go
deleted file mode 100644
index e4875b959a..0000000000
--- a/eth/downloader/downloader_test.go
+++ /dev/null
@@ -1,1379 +0,0 @@
-// Copyright 2015 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 downloader
-
-import (
- "fmt"
- "math/big"
- "os"
- "strings"
- "sync"
- "sync/atomic"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum"
- "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/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/eth/protocols/snap"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-// downloadTester is a test simulator for mocking out local block chain.
-type downloadTester struct {
- freezer string
- chain *core.BlockChain
- downloader *Downloader
-
- peers map[string]*downloadTesterPeer
- lock sync.RWMutex
-}
-
-// newTester creates a new downloader test mocker.
-func newTester(t *testing.T) *downloadTester {
- return newTesterWithNotification(t, nil)
-}
-
-// newTester creates a new downloader test mocker.
-func newTesterWithNotification(t *testing.T, success func()) *downloadTester {
- freezer := t.TempDir()
- db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false)
- if err != nil {
- panic(err)
- }
- t.Cleanup(func() {
- db.Close()
- })
- gspec := &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{testAddress: {Balance: big.NewInt(1000000000000000)}},
- BaseFee: big.NewInt(params.InitialBaseFee),
- }
- chain, err := core.NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
- if err != nil {
- panic(err)
- }
- tester := &downloadTester{
- freezer: freezer,
- chain: chain,
- peers: make(map[string]*downloadTesterPeer),
- }
- tester.downloader = New(db, new(event.TypeMux), tester.chain, nil, tester.dropPeer, success)
- return tester
-}
-
-// terminate aborts any operations on the embedded downloader and releases all
-// held resources.
-func (dl *downloadTester) terminate() {
- dl.downloader.Terminate()
- dl.chain.Stop()
-
- os.RemoveAll(dl.freezer)
-}
-
-// sync starts synchronizing with a remote peer, blocking until it completes.
-func (dl *downloadTester) sync(id string, td *big.Int, mode SyncMode) error {
- head := dl.peers[id].chain.CurrentBlock()
- if td == nil {
- // If no particular TD was requested, load from the peer's blockchain
- td = dl.peers[id].chain.GetTd(head.Hash(), head.Number.Uint64())
- }
- // Synchronise with the chosen peer and ensure proper cleanup afterwards
- err := dl.downloader.synchronise(id, head.Hash(), td, nil, mode, false, nil)
- select {
- case <-dl.downloader.cancelCh:
- // Ok, downloader fully cancelled after sync cycle
- default:
- // Downloader is still accepting packets, can block a peer up
- panic("downloader active post sync cycle") // panic will be caught by tester
- }
- return err
-}
-
-// newPeer registers a new block download source into the downloader.
-func (dl *downloadTester) newPeer(id string, version uint, blocks []*types.Block) *downloadTesterPeer {
- dl.lock.Lock()
- defer dl.lock.Unlock()
-
- peer := &downloadTesterPeer{
- dl: dl,
- id: id,
- chain: newTestBlockchain(blocks),
- withholdHeaders: make(map[common.Hash]struct{}),
- }
- dl.peers[id] = peer
-
- if err := dl.downloader.RegisterPeer(id, version, peer); err != nil {
- panic(err)
- }
- if err := dl.downloader.SnapSyncer.Register(peer); err != nil {
- panic(err)
- }
- return peer
-}
-
-// dropPeer simulates a hard peer removal from the connection pool.
-func (dl *downloadTester) dropPeer(id string) {
- dl.lock.Lock()
- defer dl.lock.Unlock()
-
- delete(dl.peers, id)
- dl.downloader.SnapSyncer.Unregister(id)
- dl.downloader.UnregisterPeer(id)
-}
-
-type downloadTesterPeer struct {
- dl *downloadTester
- id string
- chain *core.BlockChain
-
- withholdHeaders map[common.Hash]struct{}
-}
-
-// Head constructs a function to retrieve a peer's current head hash
-// and total difficulty.
-func (dlp *downloadTesterPeer) Head() (common.Hash, *big.Int) {
- head := dlp.chain.CurrentBlock()
- return head.Hash(), dlp.chain.GetTd(head.Hash(), head.Number.Uint64())
-}
-
-func unmarshalRlpHeaders(rlpdata []rlp.RawValue) []*types.Header {
- var headers = make([]*types.Header, len(rlpdata))
- for i, data := range rlpdata {
- var h types.Header
- if err := rlp.DecodeBytes(data, &h); err != nil {
- panic(err)
- }
- headers[i] = &h
- }
- return headers
-}
-
-// RequestHeadersByHash constructs a GetBlockHeaders function based on a hashed
-// origin; associated with a particular peer in the download tester. The returned
-// function can be used to retrieve batches of headers from the particular peer.
-func (dlp *downloadTesterPeer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool, sink chan *eth.Response) (*eth.Request, error) {
- // Service the header query via the live handler code
- rlpHeaders := eth.ServiceGetBlockHeadersQuery(dlp.chain, ð.GetBlockHeadersRequest{
- Origin: eth.HashOrNumber{
- Hash: origin,
- },
- Amount: uint64(amount),
- Skip: uint64(skip),
- Reverse: reverse,
- }, nil)
- headers := unmarshalRlpHeaders(rlpHeaders)
- // If a malicious peer is simulated withholding headers, delete them
- for hash := range dlp.withholdHeaders {
- for i, header := range headers {
- if header.Hash() == hash {
- headers = append(headers[:i], headers[i+1:]...)
- break
- }
- }
- }
- hashes := make([]common.Hash, len(headers))
- for i, header := range headers {
- hashes[i] = header.Hash()
- }
- // Deliver the headers to the downloader
- req := ð.Request{
- Peer: dlp.id,
- }
- res := ð.Response{
- Req: req,
- Res: (*eth.BlockHeadersRequest)(&headers),
- Meta: hashes,
- Time: 1,
- Done: make(chan error, 1), // Ignore the returned status
- }
- go func() {
- sink <- res
- }()
- return req, nil
-}
-
-// RequestHeadersByNumber constructs a GetBlockHeaders function based on a numbered
-// origin; associated with a particular peer in the download tester. The returned
-// function can be used to retrieve batches of headers from the particular peer.
-func (dlp *downloadTesterPeer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool, sink chan *eth.Response) (*eth.Request, error) {
- // Service the header query via the live handler code
- rlpHeaders := eth.ServiceGetBlockHeadersQuery(dlp.chain, ð.GetBlockHeadersRequest{
- Origin: eth.HashOrNumber{
- Number: origin,
- },
- Amount: uint64(amount),
- Skip: uint64(skip),
- Reverse: reverse,
- }, nil)
- headers := unmarshalRlpHeaders(rlpHeaders)
- // If a malicious peer is simulated withholding headers, delete them
- for hash := range dlp.withholdHeaders {
- for i, header := range headers {
- if header.Hash() == hash {
- headers = append(headers[:i], headers[i+1:]...)
- break
- }
- }
- }
- hashes := make([]common.Hash, len(headers))
- for i, header := range headers {
- hashes[i] = header.Hash()
- }
- // Deliver the headers to the downloader
- req := ð.Request{
- Peer: dlp.id,
- }
- res := ð.Response{
- Req: req,
- Res: (*eth.BlockHeadersRequest)(&headers),
- Meta: hashes,
- Time: 1,
- Done: make(chan error, 1), // Ignore the returned status
- }
- go func() {
- sink <- res
- }()
- return req, nil
-}
-
-// RequestBodies constructs a getBlockBodies method associated with a particular
-// peer in the download tester. The returned function can be used to retrieve
-// batches of block bodies from the particularly requested peer.
-func (dlp *downloadTesterPeer) RequestBodies(hashes []common.Hash, sink chan *eth.Response) (*eth.Request, error) {
- blobs := eth.ServiceGetBlockBodiesQuery(dlp.chain, hashes)
-
- bodies := make([]*eth.BlockBody, len(blobs))
- for i, blob := range blobs {
- bodies[i] = new(eth.BlockBody)
- rlp.DecodeBytes(blob, bodies[i])
- }
- var (
- txsHashes = make([]common.Hash, len(bodies))
- uncleHashes = make([]common.Hash, len(bodies))
- withdrawalHashes = make([]common.Hash, len(bodies))
- )
- hasher := trie.NewStackTrie(nil)
- for i, body := range bodies {
- txsHashes[i] = types.DeriveSha(types.Transactions(body.Transactions), hasher)
- uncleHashes[i] = types.CalcUncleHash(body.Uncles)
- }
- req := ð.Request{
- Peer: dlp.id,
- }
- res := ð.Response{
- Req: req,
- Res: (*eth.BlockBodiesResponse)(&bodies),
- Meta: [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes},
- Time: 1,
- Done: make(chan error, 1), // Ignore the returned status
- }
- go func() {
- sink <- res
- }()
- return req, nil
-}
-
-// RequestReceipts constructs a getReceipts method associated with a particular
-// peer in the download tester. The returned function can be used to retrieve
-// batches of block receipts from the particularly requested peer.
-func (dlp *downloadTesterPeer) RequestReceipts(hashes []common.Hash, sink chan *eth.Response) (*eth.Request, error) {
- blobs := eth.ServiceGetReceiptsQuery(dlp.chain, hashes)
-
- receipts := make([][]*types.Receipt, len(blobs))
- for i, blob := range blobs {
- rlp.DecodeBytes(blob, &receipts[i])
- }
- hasher := trie.NewStackTrie(nil)
- hashes = make([]common.Hash, len(receipts))
- for i, receipt := range receipts {
- hashes[i] = types.DeriveSha(types.Receipts(receipt), hasher)
- }
- req := ð.Request{
- Peer: dlp.id,
- }
- res := ð.Response{
- Req: req,
- Res: (*eth.ReceiptsResponse)(&receipts),
- Meta: hashes,
- Time: 1,
- Done: make(chan error, 1), // Ignore the returned status
- }
- go func() {
- sink <- res
- }()
- return req, nil
-}
-
-// ID retrieves the peer's unique identifier.
-func (dlp *downloadTesterPeer) ID() string {
- return dlp.id
-}
-
-// RequestAccountRange fetches a batch of accounts rooted in a specific account
-// trie, starting with the origin.
-func (dlp *downloadTesterPeer) RequestAccountRange(id uint64, root, origin, limit common.Hash, bytes uint64) error {
- // Create the request and service it
- req := &snap.GetAccountRangePacket{
- ID: id,
- Root: root,
- Origin: origin,
- Limit: limit,
- Bytes: bytes,
- }
- slimaccs, proofs := snap.ServiceGetAccountRangeQuery(dlp.chain, req)
-
- // We need to convert to non-slim format, delegate to the packet code
- res := &snap.AccountRangePacket{
- ID: id,
- Accounts: slimaccs,
- Proof: proofs,
- }
- hashes, accounts, _ := res.Unpack()
-
- go dlp.dl.downloader.SnapSyncer.OnAccounts(dlp, id, hashes, accounts, proofs)
- return nil
-}
-
-// RequestStorageRanges fetches a batch of storage slots belonging to one or
-// more accounts. If slots from only one account is requested, an origin marker
-// may also be used to retrieve from there.
-func (dlp *downloadTesterPeer) RequestStorageRanges(id uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, bytes uint64) error {
- // Create the request and service it
- req := &snap.GetStorageRangesPacket{
- ID: id,
- Accounts: accounts,
- Root: root,
- Origin: origin,
- Limit: limit,
- Bytes: bytes,
- }
- storage, proofs := snap.ServiceGetStorageRangesQuery(dlp.chain, req)
-
- // We need to convert to demultiplex, delegate to the packet code
- res := &snap.StorageRangesPacket{
- ID: id,
- Slots: storage,
- Proof: proofs,
- }
- hashes, slots := res.Unpack()
-
- go dlp.dl.downloader.SnapSyncer.OnStorage(dlp, id, hashes, slots, proofs)
- return nil
-}
-
-// RequestByteCodes fetches a batch of bytecodes by hash.
-func (dlp *downloadTesterPeer) RequestByteCodes(id uint64, hashes []common.Hash, bytes uint64) error {
- req := &snap.GetByteCodesPacket{
- ID: id,
- Hashes: hashes,
- Bytes: bytes,
- }
- codes := snap.ServiceGetByteCodesQuery(dlp.chain, req)
- go dlp.dl.downloader.SnapSyncer.OnByteCodes(dlp, id, codes)
- return nil
-}
-
-// RequestTrieNodes fetches a batch of account or storage trie nodes rooted in
-// a specific state trie.
-func (dlp *downloadTesterPeer) RequestTrieNodes(id uint64, root common.Hash, paths []snap.TrieNodePathSet, bytes uint64) error {
- req := &snap.GetTrieNodesPacket{
- ID: id,
- Root: root,
- Paths: paths,
- Bytes: bytes,
- }
- nodes, _ := snap.ServiceGetTrieNodesQuery(dlp.chain, req, time.Now())
- go dlp.dl.downloader.SnapSyncer.OnTrieNodes(dlp, id, nodes)
- return nil
-}
-
-// Log retrieves the peer's own contextual logger.
-func (dlp *downloadTesterPeer) Log() log.Logger {
- return log.New("peer", dlp.id)
-}
-
-// assertOwnChain checks if the local chain contains the correct number of items
-// of the various chain components.
-func assertOwnChain(t *testing.T, tester *downloadTester, length int) {
- // Mark this method as a helper to report errors at callsite, not in here
- t.Helper()
-
- headers, blocks, receipts := length, length, length
- if tester.downloader.getMode() == LightSync {
- blocks, receipts = 1, 1
- }
- if hs := int(tester.chain.CurrentHeader().Number.Uint64()) + 1; hs != headers {
- t.Fatalf("synchronised headers mismatch: have %v, want %v", hs, headers)
- }
- if bs := int(tester.chain.CurrentBlock().Number.Uint64()) + 1; bs != blocks {
- t.Fatalf("synchronised blocks mismatch: have %v, want %v", bs, blocks)
- }
- if rs := int(tester.chain.CurrentSnapBlock().Number.Uint64()) + 1; rs != receipts {
- t.Fatalf("synchronised receipts mismatch: have %v, want %v", rs, receipts)
- }
-}
-
-func TestCanonicalSynchronisation68Full(t *testing.T) { testCanonSync(t, eth.ETH68, FullSync) }
-func TestCanonicalSynchronisation68Snap(t *testing.T) { testCanonSync(t, eth.ETH68, SnapSync) }
-func TestCanonicalSynchronisation68Light(t *testing.T) { testCanonSync(t, eth.ETH68, LightSync) }
-func TestCanonicalSynchronisation67Full(t *testing.T) { testCanonSync(t, eth.ETH67, FullSync) }
-func TestCanonicalSynchronisation67Snap(t *testing.T) { testCanonSync(t, eth.ETH67, SnapSync) }
-func TestCanonicalSynchronisation67Light(t *testing.T) { testCanonSync(t, eth.ETH67, LightSync) }
-
-func testCanonSync(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- // Create a small enough block chain to download
- chain := testChainBase.shorten(blockCacheMaxItems - 15)
- tester.newPeer("peer", protocol, chain.blocks[1:])
-
- // Synchronise with the peer and make sure all relevant data was retrieved
- if err := tester.sync("peer", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chain.blocks))
-}
-
-// Tests that if a large batch of blocks are being downloaded, it is throttled
-// until the cached blocks are retrieved.
-func TestThrottling68Full(t *testing.T) { testThrottling(t, eth.ETH68, FullSync) }
-func TestThrottling68Snap(t *testing.T) { testThrottling(t, eth.ETH68, SnapSync) }
-func TestThrottling67Full(t *testing.T) { testThrottling(t, eth.ETH67, FullSync) }
-func TestThrottling67Snap(t *testing.T) { testThrottling(t, eth.ETH67, SnapSync) }
-
-func testThrottling(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- // Create a long block chain to download and the tester
- targetBlocks := len(testChainBase.blocks) - 1
- tester.newPeer("peer", protocol, testChainBase.blocks[1:])
-
- // Wrap the importer to allow stepping
- var blocked atomic.Uint32
- proceed := make(chan struct{})
- tester.downloader.chainInsertHook = func(results []*fetchResult) {
- blocked.Store(uint32(len(results)))
- <-proceed
- }
- // Start a synchronisation concurrently
- errc := make(chan error, 1)
- go func() {
- errc <- tester.sync("peer", nil, mode)
- }()
- // Iteratively take some blocks, always checking the retrieval count
- for {
- // Check the retrieval count synchronously (! reason for this ugly block)
- tester.lock.RLock()
- retrieved := int(tester.chain.CurrentSnapBlock().Number.Uint64()) + 1
- tester.lock.RUnlock()
- if retrieved >= targetBlocks+1 {
- break
- }
- // Wait a bit for sync to throttle itself
- var cached, frozen int
- for start := time.Now(); time.Since(start) < 3*time.Second; {
- time.Sleep(25 * time.Millisecond)
-
- tester.lock.Lock()
- tester.downloader.queue.lock.Lock()
- tester.downloader.queue.resultCache.lock.Lock()
- {
- cached = tester.downloader.queue.resultCache.countCompleted()
- frozen = int(blocked.Load())
- retrieved = int(tester.chain.CurrentSnapBlock().Number.Uint64()) + 1
- }
- tester.downloader.queue.resultCache.lock.Unlock()
- tester.downloader.queue.lock.Unlock()
- tester.lock.Unlock()
-
- if cached == blockCacheMaxItems ||
- cached == blockCacheMaxItems-reorgProtHeaderDelay ||
- retrieved+cached+frozen == targetBlocks+1 ||
- retrieved+cached+frozen == targetBlocks+1-reorgProtHeaderDelay {
- break
- }
- }
- // Make sure we filled up the cache, then exhaust it
- time.Sleep(25 * time.Millisecond) // give it a chance to screw up
- tester.lock.RLock()
- retrieved = int(tester.chain.CurrentSnapBlock().Number.Uint64()) + 1
- tester.lock.RUnlock()
- if cached != blockCacheMaxItems && cached != blockCacheMaxItems-reorgProtHeaderDelay && retrieved+cached+frozen != targetBlocks+1 && retrieved+cached+frozen != targetBlocks+1-reorgProtHeaderDelay {
- t.Fatalf("block count mismatch: have %v, want %v (owned %v, blocked %v, target %v)", cached, blockCacheMaxItems, retrieved, frozen, targetBlocks+1)
- }
- // Permit the blocked blocks to import
- if blocked.Load() > 0 {
- blocked.Store(uint32(0))
- proceed <- struct{}{}
- }
- }
- // Check that we haven't pulled more blocks than available
- assertOwnChain(t, tester, targetBlocks+1)
- if err := <-errc; err != nil {
- t.Fatalf("block synchronization failed: %v", err)
- }
-}
-
-// Tests that simple synchronization against a forked chain works correctly. In
-// this test common ancestor lookup should *not* be short circuited, and a full
-// binary search should be executed.
-func TestForkedSync68Full(t *testing.T) { testForkedSync(t, eth.ETH68, FullSync) }
-func TestForkedSync68Snap(t *testing.T) { testForkedSync(t, eth.ETH68, SnapSync) }
-func TestForkedSync68Light(t *testing.T) { testForkedSync(t, eth.ETH68, LightSync) }
-func TestForkedSync67Full(t *testing.T) { testForkedSync(t, eth.ETH67, FullSync) }
-func TestForkedSync67Snap(t *testing.T) { testForkedSync(t, eth.ETH67, SnapSync) }
-func TestForkedSync67Light(t *testing.T) { testForkedSync(t, eth.ETH67, LightSync) }
-
-func testForkedSync(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chainA := testChainForkLightA.shorten(len(testChainBase.blocks) + 80)
- chainB := testChainForkLightB.shorten(len(testChainBase.blocks) + 81)
- tester.newPeer("fork A", protocol, chainA.blocks[1:])
- tester.newPeer("fork B", protocol, chainB.blocks[1:])
- // Synchronise with the peer and make sure all blocks were retrieved
- if err := tester.sync("fork A", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chainA.blocks))
-
- // Synchronise with the second peer and make sure that fork is pulled too
- if err := tester.sync("fork B", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chainB.blocks))
-}
-
-// Tests that synchronising against a much shorter but much heavier fork works
-// currently and is not dropped.
-func TestHeavyForkedSync68Full(t *testing.T) { testHeavyForkedSync(t, eth.ETH68, FullSync) }
-func TestHeavyForkedSync68Snap(t *testing.T) { testHeavyForkedSync(t, eth.ETH68, SnapSync) }
-func TestHeavyForkedSync68Light(t *testing.T) { testHeavyForkedSync(t, eth.ETH68, LightSync) }
-func TestHeavyForkedSync67Full(t *testing.T) { testHeavyForkedSync(t, eth.ETH67, FullSync) }
-func TestHeavyForkedSync67Snap(t *testing.T) { testHeavyForkedSync(t, eth.ETH67, SnapSync) }
-func TestHeavyForkedSync67Light(t *testing.T) { testHeavyForkedSync(t, eth.ETH67, LightSync) }
-
-func testHeavyForkedSync(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chainA := testChainForkLightA.shorten(len(testChainBase.blocks) + 80)
- chainB := testChainForkHeavy.shorten(len(testChainBase.blocks) + 79)
- tester.newPeer("light", protocol, chainA.blocks[1:])
- tester.newPeer("heavy", protocol, chainB.blocks[1:])
-
- // Synchronise with the peer and make sure all blocks were retrieved
- if err := tester.sync("light", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chainA.blocks))
-
- // Synchronise with the second peer and make sure that fork is pulled too
- if err := tester.sync("heavy", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chainB.blocks))
-}
-
-// Tests that chain forks are contained within a certain interval of the current
-// chain head, ensuring that malicious peers cannot waste resources by feeding
-// long dead chains.
-func TestBoundedForkedSync68Full(t *testing.T) { testBoundedForkedSync(t, eth.ETH68, FullSync) }
-func TestBoundedForkedSync68Snap(t *testing.T) { testBoundedForkedSync(t, eth.ETH68, SnapSync) }
-func TestBoundedForkedSync68Light(t *testing.T) { testBoundedForkedSync(t, eth.ETH68, LightSync) }
-func TestBoundedForkedSync67Full(t *testing.T) { testBoundedForkedSync(t, eth.ETH67, FullSync) }
-func TestBoundedForkedSync67Snap(t *testing.T) { testBoundedForkedSync(t, eth.ETH67, SnapSync) }
-func TestBoundedForkedSync67Light(t *testing.T) { testBoundedForkedSync(t, eth.ETH67, LightSync) }
-
-func testBoundedForkedSync(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chainA := testChainForkLightA
- chainB := testChainForkLightB
- tester.newPeer("original", protocol, chainA.blocks[1:])
- tester.newPeer("rewriter", protocol, chainB.blocks[1:])
-
- // Synchronise with the peer and make sure all blocks were retrieved
- if err := tester.sync("original", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chainA.blocks))
-
- // Synchronise with the second peer and ensure that the fork is rejected to being too old
- if err := tester.sync("rewriter", nil, mode); err != errInvalidAncestor {
- t.Fatalf("sync failure mismatch: have %v, want %v", err, errInvalidAncestor)
- }
-}
-
-// Tests that chain forks are contained within a certain interval of the current
-// chain head for short but heavy forks too. These are a bit special because they
-// take different ancestor lookup paths.
-func TestBoundedHeavyForkedSync68Full(t *testing.T) {
- testBoundedHeavyForkedSync(t, eth.ETH68, FullSync)
-}
-func TestBoundedHeavyForkedSync68Snap(t *testing.T) {
- testBoundedHeavyForkedSync(t, eth.ETH68, SnapSync)
-}
-func TestBoundedHeavyForkedSync68Light(t *testing.T) {
- testBoundedHeavyForkedSync(t, eth.ETH68, LightSync)
-}
-func TestBoundedHeavyForkedSync67Full(t *testing.T) {
- testBoundedHeavyForkedSync(t, eth.ETH67, FullSync)
-}
-func TestBoundedHeavyForkedSync67Snap(t *testing.T) {
- testBoundedHeavyForkedSync(t, eth.ETH67, SnapSync)
-}
-func TestBoundedHeavyForkedSync67Light(t *testing.T) {
- testBoundedHeavyForkedSync(t, eth.ETH67, LightSync)
-}
-
-func testBoundedHeavyForkedSync(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- // Create a long enough forked chain
- chainA := testChainForkLightA
- chainB := testChainForkHeavy
- tester.newPeer("original", protocol, chainA.blocks[1:])
-
- // Synchronise with the peer and make sure all blocks were retrieved
- if err := tester.sync("original", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chainA.blocks))
-
- tester.newPeer("heavy-rewriter", protocol, chainB.blocks[1:])
- // Synchronise with the second peer and ensure that the fork is rejected to being too old
- if err := tester.sync("heavy-rewriter", nil, mode); err != errInvalidAncestor {
- t.Fatalf("sync failure mismatch: have %v, want %v", err, errInvalidAncestor)
- }
-}
-
-// Tests that a canceled download wipes all previously accumulated state.
-func TestCancel68Full(t *testing.T) { testCancel(t, eth.ETH68, FullSync) }
-func TestCancel68Snap(t *testing.T) { testCancel(t, eth.ETH68, SnapSync) }
-func TestCancel68Light(t *testing.T) { testCancel(t, eth.ETH68, LightSync) }
-func TestCancel67Full(t *testing.T) { testCancel(t, eth.ETH67, FullSync) }
-func TestCancel67Snap(t *testing.T) { testCancel(t, eth.ETH67, SnapSync) }
-func TestCancel67Light(t *testing.T) { testCancel(t, eth.ETH67, LightSync) }
-
-func testCancel(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chain := testChainBase.shorten(MaxHeaderFetch)
- tester.newPeer("peer", protocol, chain.blocks[1:])
-
- // Make sure canceling works with a pristine downloader
- tester.downloader.Cancel()
- if !tester.downloader.queue.Idle() {
- t.Errorf("download queue not idle")
- }
- // Synchronise with the peer, but cancel afterwards
- if err := tester.sync("peer", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- tester.downloader.Cancel()
- if !tester.downloader.queue.Idle() {
- t.Errorf("download queue not idle")
- }
-}
-
-// Tests that synchronisation from multiple peers works as intended (multi thread sanity test).
-func TestMultiSynchronisation68Full(t *testing.T) { testMultiSynchronisation(t, eth.ETH68, FullSync) }
-func TestMultiSynchronisation68Snap(t *testing.T) { testMultiSynchronisation(t, eth.ETH68, SnapSync) }
-func TestMultiSynchronisation68Light(t *testing.T) { testMultiSynchronisation(t, eth.ETH68, LightSync) }
-func TestMultiSynchronisation67Full(t *testing.T) { testMultiSynchronisation(t, eth.ETH67, FullSync) }
-func TestMultiSynchronisation67Snap(t *testing.T) { testMultiSynchronisation(t, eth.ETH67, SnapSync) }
-func TestMultiSynchronisation67Light(t *testing.T) { testMultiSynchronisation(t, eth.ETH67, LightSync) }
-
-func testMultiSynchronisation(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- // Create various peers with various parts of the chain
- targetPeers := 8
- chain := testChainBase.shorten(targetPeers * 100)
-
- for i := 0; i < targetPeers; i++ {
- id := fmt.Sprintf("peer #%d", i)
- tester.newPeer(id, protocol, chain.shorten(len(chain.blocks) / (i + 1)).blocks[1:])
- }
- if err := tester.sync("peer #0", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chain.blocks))
-}
-
-// Tests that synchronisations behave well in multi-version protocol environments
-// and not wreak havoc on other nodes in the network.
-func TestMultiProtoSynchronisation68Full(t *testing.T) { testMultiProtoSync(t, eth.ETH68, FullSync) }
-func TestMultiProtoSynchronisation68Snap(t *testing.T) { testMultiProtoSync(t, eth.ETH68, SnapSync) }
-func TestMultiProtoSynchronisation68Light(t *testing.T) { testMultiProtoSync(t, eth.ETH68, LightSync) }
-func TestMultiProtoSynchronisation67Full(t *testing.T) { testMultiProtoSync(t, eth.ETH67, FullSync) }
-func TestMultiProtoSynchronisation67Snap(t *testing.T) { testMultiProtoSync(t, eth.ETH67, SnapSync) }
-func TestMultiProtoSynchronisation67Light(t *testing.T) { testMultiProtoSync(t, eth.ETH67, LightSync) }
-
-func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- // Create a small enough block chain to download
- chain := testChainBase.shorten(blockCacheMaxItems - 15)
-
- // Create peers of every type
- tester.newPeer("peer 68", eth.ETH68, chain.blocks[1:])
- tester.newPeer("peer 67", eth.ETH67, chain.blocks[1:])
-
- // Synchronise with the requested peer and make sure all blocks were retrieved
- if err := tester.sync(fmt.Sprintf("peer %d", protocol), nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chain.blocks))
-
- // Check that no peers have been dropped off
- for _, version := range []int{68, 67} {
- peer := fmt.Sprintf("peer %d", version)
- if _, ok := tester.peers[peer]; !ok {
- t.Errorf("%s dropped", peer)
- }
- }
-}
-
-// Tests that if a block is empty (e.g. header only), no body request should be
-// made, and instead the header should be assembled into a whole block in itself.
-func TestEmptyShortCircuit68Full(t *testing.T) { testEmptyShortCircuit(t, eth.ETH68, FullSync) }
-func TestEmptyShortCircuit68Snap(t *testing.T) { testEmptyShortCircuit(t, eth.ETH68, SnapSync) }
-func TestEmptyShortCircuit68Light(t *testing.T) { testEmptyShortCircuit(t, eth.ETH68, LightSync) }
-func TestEmptyShortCircuit67Full(t *testing.T) { testEmptyShortCircuit(t, eth.ETH67, FullSync) }
-func TestEmptyShortCircuit67Snap(t *testing.T) { testEmptyShortCircuit(t, eth.ETH67, SnapSync) }
-func TestEmptyShortCircuit67Light(t *testing.T) { testEmptyShortCircuit(t, eth.ETH67, LightSync) }
-
-func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- // Create a block chain to download
- chain := testChainBase
- tester.newPeer("peer", protocol, chain.blocks[1:])
-
- // Instrument the downloader to signal body requests
- var bodiesHave, receiptsHave atomic.Int32
- tester.downloader.bodyFetchHook = func(headers []*types.Header) {
- bodiesHave.Add(int32(len(headers)))
- }
- tester.downloader.receiptFetchHook = func(headers []*types.Header) {
- receiptsHave.Add(int32(len(headers)))
- }
- // Synchronise with the peer and make sure all blocks were retrieved
- if err := tester.sync("peer", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chain.blocks))
-
- // Validate the number of block bodies that should have been requested
- bodiesNeeded, receiptsNeeded := 0, 0
- for _, block := range chain.blocks[1:] {
- if mode != LightSync && (len(block.Transactions()) > 0 || len(block.Uncles()) > 0) {
- bodiesNeeded++
- }
- }
- for _, block := range chain.blocks[1:] {
- if mode == SnapSync && len(block.Transactions()) > 0 {
- receiptsNeeded++
- }
- }
- if int(bodiesHave.Load()) != bodiesNeeded {
- t.Errorf("body retrieval count mismatch: have %v, want %v", bodiesHave.Load(), bodiesNeeded)
- }
- if int(receiptsHave.Load()) != receiptsNeeded {
- t.Errorf("receipt retrieval count mismatch: have %v, want %v", receiptsHave.Load(), receiptsNeeded)
- }
-}
-
-// Tests that headers are enqueued continuously, preventing malicious nodes from
-// stalling the downloader by feeding gapped header chains.
-func TestMissingHeaderAttack68Full(t *testing.T) { testMissingHeaderAttack(t, eth.ETH68, FullSync) }
-func TestMissingHeaderAttack68Snap(t *testing.T) { testMissingHeaderAttack(t, eth.ETH68, SnapSync) }
-func TestMissingHeaderAttack68Light(t *testing.T) { testMissingHeaderAttack(t, eth.ETH68, LightSync) }
-func TestMissingHeaderAttack67Full(t *testing.T) { testMissingHeaderAttack(t, eth.ETH67, FullSync) }
-func TestMissingHeaderAttack67Snap(t *testing.T) { testMissingHeaderAttack(t, eth.ETH67, SnapSync) }
-func TestMissingHeaderAttack67Light(t *testing.T) { testMissingHeaderAttack(t, eth.ETH67, LightSync) }
-
-func testMissingHeaderAttack(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chain := testChainBase.shorten(blockCacheMaxItems - 15)
-
- attacker := tester.newPeer("attack", protocol, chain.blocks[1:])
- attacker.withholdHeaders[chain.blocks[len(chain.blocks)/2-1].Hash()] = struct{}{}
-
- if err := tester.sync("attack", nil, mode); err == nil {
- t.Fatalf("succeeded attacker synchronisation")
- }
- // Synchronise with the valid peer and make sure sync succeeds
- tester.newPeer("valid", protocol, chain.blocks[1:])
- if err := tester.sync("valid", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chain.blocks))
-}
-
-// Tests that if requested headers are shifted (i.e. first is missing), the queue
-// detects the invalid numbering.
-func TestShiftedHeaderAttack68Full(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH68, FullSync) }
-func TestShiftedHeaderAttack68Snap(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH68, SnapSync) }
-func TestShiftedHeaderAttack68Light(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH68, LightSync) }
-func TestShiftedHeaderAttack67Full(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH67, FullSync) }
-func TestShiftedHeaderAttack67Snap(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH67, SnapSync) }
-func TestShiftedHeaderAttack67Light(t *testing.T) { testShiftedHeaderAttack(t, eth.ETH67, LightSync) }
-
-func testShiftedHeaderAttack(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chain := testChainBase.shorten(blockCacheMaxItems - 15)
-
- // Attempt a full sync with an attacker feeding shifted headers
- attacker := tester.newPeer("attack", protocol, chain.blocks[1:])
- attacker.withholdHeaders[chain.blocks[1].Hash()] = struct{}{}
-
- if err := tester.sync("attack", nil, mode); err == nil {
- t.Fatalf("succeeded attacker synchronisation")
- }
- // Synchronise with the valid peer and make sure sync succeeds
- tester.newPeer("valid", protocol, chain.blocks[1:])
- if err := tester.sync("valid", nil, mode); err != nil {
- t.Fatalf("failed to synchronise blocks: %v", err)
- }
- assertOwnChain(t, tester, len(chain.blocks))
-}
-
-// Tests that a peer advertising a high TD doesn't get to stall the downloader
-// afterwards by not sending any useful hashes.
-func TestHighTDStarvationAttack68Full(t *testing.T) {
- testHighTDStarvationAttack(t, eth.ETH68, FullSync)
-}
-func TestHighTDStarvationAttack68Snap(t *testing.T) {
- testHighTDStarvationAttack(t, eth.ETH68, SnapSync)
-}
-func TestHighTDStarvationAttack68Light(t *testing.T) {
- testHighTDStarvationAttack(t, eth.ETH68, LightSync)
-}
-func TestHighTDStarvationAttack67Full(t *testing.T) {
- testHighTDStarvationAttack(t, eth.ETH67, FullSync)
-}
-func TestHighTDStarvationAttack67Snap(t *testing.T) {
- testHighTDStarvationAttack(t, eth.ETH67, SnapSync)
-}
-func TestHighTDStarvationAttack67Light(t *testing.T) {
- testHighTDStarvationAttack(t, eth.ETH67, LightSync)
-}
-
-func testHighTDStarvationAttack(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chain := testChainBase.shorten(1)
- tester.newPeer("attack", protocol, chain.blocks[1:])
- if err := tester.sync("attack", big.NewInt(1000000), mode); err != errStallingPeer {
- t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errStallingPeer)
- }
-}
-
-// Tests that misbehaving peers are disconnected, whilst behaving ones are not.
-func TestBlockHeaderAttackerDropping68(t *testing.T) { testBlockHeaderAttackerDropping(t, eth.ETH68) }
-func TestBlockHeaderAttackerDropping67(t *testing.T) { testBlockHeaderAttackerDropping(t, eth.ETH67) }
-
-func testBlockHeaderAttackerDropping(t *testing.T, protocol uint) {
- // Define the disconnection requirement for individual hash fetch errors
- tests := []struct {
- result error
- drop bool
- }{
- {nil, false}, // Sync succeeded, all is well
- {errBusy, false}, // Sync is already in progress, no problem
- {errUnknownPeer, false}, // Peer is unknown, was already dropped, don't double drop
- {errBadPeer, true}, // Peer was deemed bad for some reason, drop it
- {errStallingPeer, true}, // Peer was detected to be stalling, drop it
- {errUnsyncedPeer, true}, // Peer was detected to be unsynced, drop it
- {errNoPeers, false}, // No peers to download from, soft race, no issue
- {errTimeout, true}, // No hashes received in due time, drop the peer
- {errEmptyHeaderSet, true}, // No headers were returned as a response, drop as it's a dead end
- {errPeersUnavailable, true}, // Nobody had the advertised blocks, drop the advertiser
- {errInvalidAncestor, true}, // Agreed upon ancestor is not acceptable, drop the chain rewriter
- {errInvalidChain, true}, // Hash chain was detected as invalid, definitely drop
- {errInvalidBody, false}, // A bad peer was detected, but not the sync origin
- {errInvalidReceipt, false}, // A bad peer was detected, but not the sync origin
- {errCancelContentProcessing, false}, // Synchronisation was canceled, origin may be innocent, don't drop
- }
- // Run the tests and check disconnection status
- tester := newTester(t)
- defer tester.terminate()
- chain := testChainBase.shorten(1)
-
- for i, tt := range tests {
- // Register a new peer and ensure its presence
- id := fmt.Sprintf("test %d", i)
- tester.newPeer(id, protocol, chain.blocks[1:])
- if _, ok := tester.peers[id]; !ok {
- t.Fatalf("test %d: registered peer not found", i)
- }
- // Simulate a synchronisation and check the required result
- tester.downloader.synchroniseMock = func(string, common.Hash) error { return tt.result }
-
- tester.downloader.LegacySync(id, tester.chain.Genesis().Hash(), big.NewInt(1000), nil, FullSync)
- if _, ok := tester.peers[id]; !ok != tt.drop {
- t.Errorf("test %d: peer drop mismatch for %v: have %v, want %v", i, tt.result, !ok, tt.drop)
- }
- }
-}
-
-// Tests that synchronisation progress (origin block number, current block number
-// and highest block number) is tracked and updated correctly.
-func TestSyncProgress68Full(t *testing.T) { testSyncProgress(t, eth.ETH68, FullSync) }
-func TestSyncProgress68Snap(t *testing.T) { testSyncProgress(t, eth.ETH68, SnapSync) }
-func TestSyncProgress68Light(t *testing.T) { testSyncProgress(t, eth.ETH68, LightSync) }
-func TestSyncProgress67Full(t *testing.T) { testSyncProgress(t, eth.ETH67, FullSync) }
-func TestSyncProgress67Snap(t *testing.T) { testSyncProgress(t, eth.ETH67, SnapSync) }
-func TestSyncProgress67Light(t *testing.T) { testSyncProgress(t, eth.ETH67, LightSync) }
-
-func testSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chain := testChainBase.shorten(blockCacheMaxItems - 15)
-
- // Set a sync init hook to catch progress changes
- starting := make(chan struct{})
- progress := make(chan struct{})
-
- tester.downloader.syncInitHook = func(origin, latest uint64) {
- starting <- struct{}{}
- <-progress
- }
- checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{})
-
- // Synchronise half the blocks and check initial progress
- tester.newPeer("peer-half", protocol, chain.shorten(len(chain.blocks) / 2).blocks[1:])
- pending := new(sync.WaitGroup)
- pending.Add(1)
-
- go func() {
- defer pending.Done()
- if err := tester.sync("peer-half", nil, mode); err != nil {
- panic(fmt.Sprintf("failed to synchronise blocks: %v", err))
- }
- }()
- <-starting
- checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{
- HighestBlock: uint64(len(chain.blocks)/2 - 1),
- })
- progress <- struct{}{}
- pending.Wait()
-
- // Synchronise all the blocks and check continuation progress
- tester.newPeer("peer-full", protocol, chain.blocks[1:])
- pending.Add(1)
- go func() {
- defer pending.Done()
- if err := tester.sync("peer-full", nil, mode); err != nil {
- panic(fmt.Sprintf("failed to synchronise blocks: %v", err))
- }
- }()
- <-starting
- checkProgress(t, tester.downloader, "completing", ethereum.SyncProgress{
- StartingBlock: uint64(len(chain.blocks)/2 - 1),
- CurrentBlock: uint64(len(chain.blocks)/2 - 1),
- HighestBlock: uint64(len(chain.blocks) - 1),
- })
-
- // Check final progress after successful sync
- progress <- struct{}{}
- pending.Wait()
- checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{
- StartingBlock: uint64(len(chain.blocks)/2 - 1),
- CurrentBlock: uint64(len(chain.blocks) - 1),
- HighestBlock: uint64(len(chain.blocks) - 1),
- })
-}
-
-func checkProgress(t *testing.T, d *Downloader, stage string, want ethereum.SyncProgress) {
- // Mark this method as a helper to report errors at callsite, not in here
- t.Helper()
-
- p := d.Progress()
- if p.StartingBlock != want.StartingBlock || p.CurrentBlock != want.CurrentBlock || p.HighestBlock != want.HighestBlock {
- t.Fatalf("%s progress mismatch:\nhave %+v\nwant %+v", stage, p, want)
- }
-}
-
-// Tests that synchronisation progress (origin block number and highest block
-// number) is tracked and updated correctly in case of a fork (or manual head
-// revertal).
-func TestForkedSyncProgress68Full(t *testing.T) { testForkedSyncProgress(t, eth.ETH68, FullSync) }
-func TestForkedSyncProgress68Snap(t *testing.T) { testForkedSyncProgress(t, eth.ETH68, SnapSync) }
-func TestForkedSyncProgress68Light(t *testing.T) { testForkedSyncProgress(t, eth.ETH68, LightSync) }
-func TestForkedSyncProgress67Full(t *testing.T) { testForkedSyncProgress(t, eth.ETH67, FullSync) }
-func TestForkedSyncProgress67Snap(t *testing.T) { testForkedSyncProgress(t, eth.ETH67, SnapSync) }
-func TestForkedSyncProgress67Light(t *testing.T) { testForkedSyncProgress(t, eth.ETH67, LightSync) }
-
-func testForkedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chainA := testChainForkLightA.shorten(len(testChainBase.blocks) + MaxHeaderFetch)
- chainB := testChainForkLightB.shorten(len(testChainBase.blocks) + MaxHeaderFetch)
-
- // Set a sync init hook to catch progress changes
- starting := make(chan struct{})
- progress := make(chan struct{})
-
- tester.downloader.syncInitHook = func(origin, latest uint64) {
- starting <- struct{}{}
- <-progress
- }
- checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{})
-
- // Synchronise with one of the forks and check progress
- tester.newPeer("fork A", protocol, chainA.blocks[1:])
- pending := new(sync.WaitGroup)
- pending.Add(1)
- go func() {
- defer pending.Done()
- if err := tester.sync("fork A", nil, mode); err != nil {
- panic(fmt.Sprintf("failed to synchronise blocks: %v", err))
- }
- }()
- <-starting
-
- checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{
- HighestBlock: uint64(len(chainA.blocks) - 1),
- })
- progress <- struct{}{}
- pending.Wait()
-
- // Simulate a successful sync above the fork
- tester.downloader.syncStatsChainOrigin = tester.downloader.syncStatsChainHeight
-
- // Synchronise with the second fork and check progress resets
- tester.newPeer("fork B", protocol, chainB.blocks[1:])
- pending.Add(1)
- go func() {
- defer pending.Done()
- if err := tester.sync("fork B", nil, mode); err != nil {
- panic(fmt.Sprintf("failed to synchronise blocks: %v", err))
- }
- }()
- <-starting
- checkProgress(t, tester.downloader, "forking", ethereum.SyncProgress{
- StartingBlock: uint64(len(testChainBase.blocks)) - 1,
- CurrentBlock: uint64(len(chainA.blocks) - 1),
- HighestBlock: uint64(len(chainB.blocks) - 1),
- })
-
- // Check final progress after successful sync
- progress <- struct{}{}
- pending.Wait()
- checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{
- StartingBlock: uint64(len(testChainBase.blocks)) - 1,
- CurrentBlock: uint64(len(chainB.blocks) - 1),
- HighestBlock: uint64(len(chainB.blocks) - 1),
- })
-}
-
-// Tests that if synchronisation is aborted due to some failure, then the progress
-// origin is not updated in the next sync cycle, as it should be considered the
-// continuation of the previous sync and not a new instance.
-func TestFailedSyncProgress68Full(t *testing.T) { testFailedSyncProgress(t, eth.ETH68, FullSync) }
-func TestFailedSyncProgress68Snap(t *testing.T) { testFailedSyncProgress(t, eth.ETH68, SnapSync) }
-func TestFailedSyncProgress68Light(t *testing.T) { testFailedSyncProgress(t, eth.ETH68, LightSync) }
-func TestFailedSyncProgress67Full(t *testing.T) { testFailedSyncProgress(t, eth.ETH67, FullSync) }
-func TestFailedSyncProgress67Snap(t *testing.T) { testFailedSyncProgress(t, eth.ETH67, SnapSync) }
-func TestFailedSyncProgress67Light(t *testing.T) { testFailedSyncProgress(t, eth.ETH67, LightSync) }
-
-func testFailedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chain := testChainBase.shorten(blockCacheMaxItems - 15)
-
- // Set a sync init hook to catch progress changes
- starting := make(chan struct{})
- progress := make(chan struct{})
-
- tester.downloader.syncInitHook = func(origin, latest uint64) {
- starting <- struct{}{}
- <-progress
- }
- checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{})
-
- // Attempt a full sync with a faulty peer
- missing := len(chain.blocks)/2 - 1
-
- faulter := tester.newPeer("faulty", protocol, chain.blocks[1:])
- faulter.withholdHeaders[chain.blocks[missing].Hash()] = struct{}{}
-
- pending := new(sync.WaitGroup)
- pending.Add(1)
- go func() {
- defer pending.Done()
- if err := tester.sync("faulty", nil, mode); err == nil {
- panic("succeeded faulty synchronisation")
- }
- }()
- <-starting
- checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{
- HighestBlock: uint64(len(chain.blocks) - 1),
- })
- progress <- struct{}{}
- pending.Wait()
- afterFailedSync := tester.downloader.Progress()
-
- // Synchronise with a good peer and check that the progress origin remind the same
- // after a failure
- tester.newPeer("valid", protocol, chain.blocks[1:])
- pending.Add(1)
- go func() {
- defer pending.Done()
- if err := tester.sync("valid", nil, mode); err != nil {
- panic(fmt.Sprintf("failed to synchronise blocks: %v", err))
- }
- }()
- <-starting
- checkProgress(t, tester.downloader, "completing", afterFailedSync)
-
- // Check final progress after successful sync
- progress <- struct{}{}
- pending.Wait()
- checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{
- CurrentBlock: uint64(len(chain.blocks) - 1),
- HighestBlock: uint64(len(chain.blocks) - 1),
- })
-}
-
-// Tests that if an attacker fakes a chain height, after the attack is detected,
-// the progress height is successfully reduced at the next sync invocation.
-func TestFakedSyncProgress68Full(t *testing.T) { testFakedSyncProgress(t, eth.ETH68, FullSync) }
-func TestFakedSyncProgress68Snap(t *testing.T) { testFakedSyncProgress(t, eth.ETH68, SnapSync) }
-func TestFakedSyncProgress68Light(t *testing.T) { testFakedSyncProgress(t, eth.ETH68, LightSync) }
-func TestFakedSyncProgress67Full(t *testing.T) { testFakedSyncProgress(t, eth.ETH67, FullSync) }
-func TestFakedSyncProgress67Snap(t *testing.T) { testFakedSyncProgress(t, eth.ETH67, SnapSync) }
-func TestFakedSyncProgress67Light(t *testing.T) { testFakedSyncProgress(t, eth.ETH67, LightSync) }
-
-func testFakedSyncProgress(t *testing.T, protocol uint, mode SyncMode) {
- tester := newTester(t)
- defer tester.terminate()
-
- chain := testChainBase.shorten(blockCacheMaxItems - 15)
-
- // Set a sync init hook to catch progress changes
- starting := make(chan struct{})
- progress := make(chan struct{})
- tester.downloader.syncInitHook = func(origin, latest uint64) {
- starting <- struct{}{}
- <-progress
- }
- checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{})
-
- // Create and sync with an attacker that promises a higher chain than available.
- attacker := tester.newPeer("attack", protocol, chain.blocks[1:])
- numMissing := 5
- for i := len(chain.blocks) - 2; i > len(chain.blocks)-numMissing; i-- {
- attacker.withholdHeaders[chain.blocks[i].Hash()] = struct{}{}
- }
- pending := new(sync.WaitGroup)
- pending.Add(1)
- go func() {
- defer pending.Done()
- if err := tester.sync("attack", nil, mode); err == nil {
- panic("succeeded attacker synchronisation")
- }
- }()
- <-starting
- checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{
- HighestBlock: uint64(len(chain.blocks) - 1),
- })
- progress <- struct{}{}
- pending.Wait()
- afterFailedSync := tester.downloader.Progress()
-
- // Synchronise with a good peer and check that the progress height has been reduced to
- // the true value.
- validChain := chain.shorten(len(chain.blocks) - numMissing)
- tester.newPeer("valid", protocol, validChain.blocks[1:])
- pending.Add(1)
-
- go func() {
- defer pending.Done()
- if err := tester.sync("valid", nil, mode); err != nil {
- panic(fmt.Sprintf("failed to synchronise blocks: %v", err))
- }
- }()
- <-starting
- checkProgress(t, tester.downloader, "completing", ethereum.SyncProgress{
- CurrentBlock: afterFailedSync.CurrentBlock,
- HighestBlock: uint64(len(validChain.blocks) - 1),
- })
- // Check final progress after successful sync.
- progress <- struct{}{}
- pending.Wait()
- checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{
- CurrentBlock: uint64(len(validChain.blocks) - 1),
- HighestBlock: uint64(len(validChain.blocks) - 1),
- })
-}
-
-func TestRemoteHeaderRequestSpan(t *testing.T) {
- testCases := []struct {
- remoteHeight uint64
- localHeight uint64
- expected []int
- }{
- // Remote is way higher. We should ask for the remote head and go backwards
- {1500, 1000,
- []int{1323, 1339, 1355, 1371, 1387, 1403, 1419, 1435, 1451, 1467, 1483, 1499},
- },
- {15000, 13006,
- []int{14823, 14839, 14855, 14871, 14887, 14903, 14919, 14935, 14951, 14967, 14983, 14999},
- },
- // Remote is pretty close to us. We don't have to fetch as many
- {1200, 1150,
- []int{1149, 1154, 1159, 1164, 1169, 1174, 1179, 1184, 1189, 1194, 1199},
- },
- // Remote is equal to us (so on a fork with higher td)
- // We should get the closest couple of ancestors
- {1500, 1500,
- []int{1497, 1499},
- },
- // We're higher than the remote! Odd
- {1000, 1500,
- []int{997, 999},
- },
- // Check some weird edgecases that it behaves somewhat rationally
- {0, 1500,
- []int{0, 2},
- },
- {6000000, 0,
- []int{5999823, 5999839, 5999855, 5999871, 5999887, 5999903, 5999919, 5999935, 5999951, 5999967, 5999983, 5999999},
- },
- {0, 0,
- []int{0, 2},
- },
- }
- reqs := func(from, count, span int) []int {
- var r []int
- num := from
- for len(r) < count {
- r = append(r, num)
- num += span + 1
- }
- return r
- }
- for i, tt := range testCases {
- from, count, span, max := calculateRequestSpan(tt.remoteHeight, tt.localHeight)
- data := reqs(int(from), count, span)
-
- if max != uint64(data[len(data)-1]) {
- t.Errorf("test %d: wrong last value %d != %d", i, data[len(data)-1], max)
- }
- failed := false
- if len(data) != len(tt.expected) {
- failed = true
- t.Errorf("test %d: length wrong, expected %d got %d", i, len(tt.expected), len(data))
- } else {
- for j, n := range data {
- if n != tt.expected[j] {
- failed = true
- break
- }
- }
- }
- if failed {
- res := strings.ReplaceAll(fmt.Sprint(data), " ", ",")
- exp := strings.ReplaceAll(fmt.Sprint(tt.expected), " ", ",")
- t.Logf("got: %v\n", res)
- t.Logf("exp: %v\n", exp)
- t.Errorf("test %d: wrong values", i)
- }
- }
-}
-
-// Tests that peers below a pre-configured checkpoint block are prevented from
-// being fast-synced from, avoiding potential cheap eclipse attacks.
-func TestBeaconSync68Full(t *testing.T) { testBeaconSync(t, eth.ETH68, FullSync) }
-func TestBeaconSync68Snap(t *testing.T) { testBeaconSync(t, eth.ETH68, SnapSync) }
-func TestBeaconSync67Full(t *testing.T) { testBeaconSync(t, eth.ETH67, FullSync) }
-func TestBeaconSync67Snap(t *testing.T) { testBeaconSync(t, eth.ETH67, SnapSync) }
-
-func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) {
- //log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
-
- var cases = []struct {
- name string // The name of testing scenario
- local int // The length of local chain(canonical chain assumed), 0 means genesis is the head
- }{
- {name: "Beacon sync since genesis", local: 0},
- {name: "Beacon sync with short local chain", local: 1},
- {name: "Beacon sync with long local chain", local: blockCacheMaxItems - 15 - fsMinFullBlocks/2},
- {name: "Beacon sync with full local chain", local: blockCacheMaxItems - 15 - 1},
- }
- for _, c := range cases {
- t.Run(c.name, func(t *testing.T) {
- success := make(chan struct{})
- tester := newTesterWithNotification(t, func() {
- close(success)
- })
- defer tester.terminate()
-
- chain := testChainBase.shorten(blockCacheMaxItems - 15)
- tester.newPeer("peer", protocol, chain.blocks[1:])
-
- // Build the local chain segment if it's required
- if c.local > 0 {
- tester.chain.InsertChain(chain.blocks[1 : c.local+1])
- }
- if err := tester.downloader.BeaconSync(mode, chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil {
- t.Fatalf("Failed to beacon sync chain %v %v", c.name, err)
- }
- select {
- case <-success:
- // Ok, downloader fully cancelled after sync cycle
- if bs := int(tester.chain.CurrentBlock().Number.Uint64()) + 1; bs != len(chain.blocks) {
- t.Fatalf("synchronised blocks mismatch: have %v, want %v", bs, len(chain.blocks))
- }
- case <-time.NewTimer(time.Second * 3).C:
- t.Fatalf("Failed to sync chain in three seconds")
- }
- })
- }
-}
diff --git a/eth/downloader/events.go b/eth/downloader/events.go
deleted file mode 100644
index 25255a3a72..0000000000
--- a/eth/downloader/events.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2015 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 downloader
-
-import "github.com/ethereum/go-ethereum/core/types"
-
-type DoneEvent struct {
- Latest *types.Header
-}
-type StartEvent struct{}
-type FailedEvent struct{ Err error }
diff --git a/eth/downloader/fetchers.go b/eth/downloader/fetchers.go
deleted file mode 100644
index cc4279b0da..0000000000
--- a/eth/downloader/fetchers.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2021 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 downloader
-
-import (
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
-)
-
-// fetchHeadersByHash is a blocking version of Peer.RequestHeadersByHash which
-// handles all the cancellation, interruption and timeout mechanisms of a data
-// retrieval to allow blocking API calls.
-func (d *Downloader) fetchHeadersByHash(p *peerConnection, hash common.Hash, amount int, skip int, reverse bool) ([]*types.Header, []common.Hash, error) {
- // Create the response sink and send the network request
- start := time.Now()
- resCh := make(chan *eth.Response)
-
- req, err := p.peer.RequestHeadersByHash(hash, amount, skip, reverse, resCh)
- if err != nil {
- return nil, nil, err
- }
- defer req.Close()
-
- // Wait until the response arrives, the request is cancelled or times out
- ttl := d.peers.rates.TargetTimeout()
-
- timeoutTimer := time.NewTimer(ttl)
- defer timeoutTimer.Stop()
-
- select {
- case <-d.cancelCh:
- return nil, nil, errCanceled
-
- case <-timeoutTimer.C:
- // Header retrieval timed out, update the metrics
- p.log.Debug("Header request timed out", "elapsed", ttl)
- headerTimeoutMeter.Mark(1)
-
- return nil, nil, errTimeout
-
- case res := <-resCh:
- // Headers successfully retrieved, update the metrics
- headerReqTimer.Update(time.Since(start))
- headerInMeter.Mark(int64(len(*res.Res.(*eth.BlockHeadersRequest))))
-
- // Don't reject the packet even if it turns out to be bad, downloader will
- // disconnect the peer on its own terms. Simply delivery the headers to
- // be processed by the caller
- res.Done <- nil
-
- return *res.Res.(*eth.BlockHeadersRequest), res.Meta.([]common.Hash), nil
- }
-}
-
-// fetchHeadersByNumber is a blocking version of Peer.RequestHeadersByNumber which
-// handles all the cancellation, interruption and timeout mechanisms of a data
-// retrieval to allow blocking API calls.
-func (d *Downloader) fetchHeadersByNumber(p *peerConnection, number uint64, amount int, skip int, reverse bool) ([]*types.Header, []common.Hash, error) {
- // Create the response sink and send the network request
- start := time.Now()
- resCh := make(chan *eth.Response)
-
- req, err := p.peer.RequestHeadersByNumber(number, amount, skip, reverse, resCh)
- if err != nil {
- return nil, nil, err
- }
- defer req.Close()
-
- // Wait until the response arrives, the request is cancelled or times out
- ttl := d.peers.rates.TargetTimeout()
-
- timeoutTimer := time.NewTimer(ttl)
- defer timeoutTimer.Stop()
-
- select {
- case <-d.cancelCh:
- return nil, nil, errCanceled
-
- case <-timeoutTimer.C:
- // Header retrieval timed out, update the metrics
- p.log.Debug("Header request timed out", "elapsed", ttl)
- headerTimeoutMeter.Mark(1)
-
- return nil, nil, errTimeout
-
- case res := <-resCh:
- // Headers successfully retrieved, update the metrics
- headerReqTimer.Update(time.Since(start))
- headerInMeter.Mark(int64(len(*res.Res.(*eth.BlockHeadersRequest))))
-
- // Don't reject the packet even if it turns out to be bad, downloader will
- // disconnect the peer on its own terms. Simply delivery the headers to
- // be processed by the caller
- res.Done <- nil
-
- return *res.Res.(*eth.BlockHeadersRequest), res.Meta.([]common.Hash), nil
- }
-}
diff --git a/eth/downloader/fetchers_concurrent.go b/eth/downloader/fetchers_concurrent.go
deleted file mode 100644
index 649aa27615..0000000000
--- a/eth/downloader/fetchers_concurrent.go
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright 2021 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 downloader
-
-import (
- "errors"
- "sort"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/prque"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// timeoutGracePeriod is the amount of time to allow for a peer to deliver a
-// response to a locally already timed out request. Timeouts are not penalized
-// as a peer might be temporarily overloaded, however, they still must reply
-// to each request. Failing to do so is considered a protocol violation.
-var timeoutGracePeriod = 2 * time.Minute
-
-// typedQueue is an interface defining the adaptor needed to translate the type
-// specific downloader/queue schedulers into the type-agnostic general concurrent
-// fetcher algorithm calls.
-type typedQueue interface {
- // waker returns a notification channel that gets pinged in case more fetches
- // have been queued up, so the fetcher might assign it to idle peers.
- waker() chan bool
-
- // pending returns the number of wrapped items that are currently queued for
- // fetching by the concurrent downloader.
- pending() int
-
- // capacity is responsible for calculating how many items of the abstracted
- // type a particular peer is estimated to be able to retrieve within the
- // allotted round trip time.
- capacity(peer *peerConnection, rtt time.Duration) int
-
- // updateCapacity is responsible for updating how many items of the abstracted
- // type a particular peer is estimated to be able to retrieve in a unit time.
- updateCapacity(peer *peerConnection, items int, elapsed time.Duration)
-
- // reserve is responsible for allocating a requested number of pending items
- // from the download queue to the specified peer.
- reserve(peer *peerConnection, items int) (*fetchRequest, bool, bool)
-
- // unreserve is responsible for removing the current retrieval allocation
- // assigned to a specific peer and placing it back into the pool to allow
- // reassigning to some other peer.
- unreserve(peer string) int
-
- // request is responsible for converting a generic fetch request into a typed
- // one and sending it to the remote peer for fulfillment.
- request(peer *peerConnection, req *fetchRequest, resCh chan *eth.Response) (*eth.Request, error)
-
- // deliver is responsible for taking a generic response packet from the
- // concurrent fetcher, unpacking the type specific data and delivering
- // it to the downloader's queue.
- deliver(peer *peerConnection, packet *eth.Response) (int, error)
-}
-
-// concurrentFetch iteratively downloads scheduled block parts, taking available
-// peers, reserving a chunk of fetch requests for each and waiting for delivery
-// or timeouts.
-func (d *Downloader) concurrentFetch(queue typedQueue, beaconMode bool) error {
- // Create a delivery channel to accept responses from all peers
- responses := make(chan *eth.Response)
-
- // Track the currently active requests and their timeout order
- pending := make(map[string]*eth.Request)
- defer func() {
- // Abort all requests on sync cycle cancellation. The requests may still
- // be fulfilled by the remote side, but the dispatcher will not wait to
- // deliver them since nobody's going to be listening.
- for _, req := range pending {
- req.Close()
- }
- }()
- ordering := make(map[*eth.Request]int)
- timeouts := prque.New[int64, *eth.Request](func(data *eth.Request, index int) {
- ordering[data] = index
- })
-
- timeout := time.NewTimer(0)
- if !timeout.Stop() {
- <-timeout.C
- }
- defer timeout.Stop()
-
- // Track the timed-out but not-yet-answered requests separately. We want to
- // keep tracking which peers are busy (potentially overloaded), so removing
- // all trace of a timed out request is not good. We also can't just cancel
- // the pending request altogether as that would prevent a late response from
- // being delivered, thus never unblocking the peer.
- stales := make(map[string]*eth.Request)
- defer func() {
- // Abort all requests on sync cycle cancellation. The requests may still
- // be fulfilled by the remote side, but the dispatcher will not wait to
- // deliver them since nobody's going to be listening.
- for _, req := range stales {
- req.Close()
- }
- }()
- // Subscribe to peer lifecycle events to schedule tasks to new joiners and
- // reschedule tasks upon disconnections. We don't care which event happened
- // for simplicity, so just use a single channel.
- peering := make(chan *peeringEvent, 64) // arbitrary buffer, just some burst protection
-
- peeringSub := d.peers.SubscribeEvents(peering)
- defer peeringSub.Unsubscribe()
-
- // Prepare the queue and fetch block parts until the block header fetcher's done
- finished := false
- for {
- // Short circuit if we lost all our peers
- if d.peers.Len() == 0 && !beaconMode {
- return errNoPeers
- }
- // If there's nothing more to fetch, wait or terminate
- if queue.pending() == 0 {
- if len(pending) == 0 && finished {
- return nil
- }
- } else {
- // Send a download request to all idle peers, until throttled
- var (
- idles []*peerConnection
- caps []int
- )
- for _, peer := range d.peers.AllPeers() {
- pending, stale := pending[peer.id], stales[peer.id]
- if pending == nil && stale == nil {
- idles = append(idles, peer)
- caps = append(caps, queue.capacity(peer, time.Second))
- } else if stale != nil {
- if waited := time.Since(stale.Sent); waited > timeoutGracePeriod {
- // Request has been in flight longer than the grace period
- // permitted it, consider the peer malicious attempting to
- // stall the sync.
- peer.log.Warn("Peer stalling, dropping", "waited", common.PrettyDuration(waited))
- d.dropPeer(peer.id)
- }
- }
- }
- sort.Sort(&peerCapacitySort{idles, caps})
-
- var (
- progressed bool
- throttled bool
- queued = queue.pending()
- )
- for _, peer := range idles {
- // Short circuit if throttling activated or there are no more
- // queued tasks to be retrieved
- if throttled {
- break
- }
- if queued = queue.pending(); queued == 0 {
- break
- }
- // Reserve a chunk of fetches for a peer. A nil can mean either that
- // no more headers are available, or that the peer is known not to
- // have them.
- request, progress, throttle := queue.reserve(peer, queue.capacity(peer, d.peers.rates.TargetRoundTrip()))
- if progress {
- progressed = true
- }
- if throttle {
- throttled = true
- throttleCounter.Inc(1)
- }
- if request == nil {
- continue
- }
- // Fetch the chunk and make sure any errors return the hashes to the queue
- req, err := queue.request(peer, request, responses)
- if err != nil {
- // Sending the request failed, which generally means the peer
- // was disconnected in between assignment and network send.
- // Although all peer removal operations return allocated tasks
- // to the queue, that is async, and we can do better here by
- // immediately pushing the unfulfilled requests.
- queue.unreserve(peer.id) // TODO(karalabe): This needs a non-expiration method
- continue
- }
- pending[peer.id] = req
-
- ttl := d.peers.rates.TargetTimeout()
- ordering[req] = timeouts.Size()
-
- timeouts.Push(req, -time.Now().Add(ttl).UnixNano())
- if timeouts.Size() == 1 {
- timeout.Reset(ttl)
- }
- }
- // Make sure that we have peers available for fetching. If all peers have been tried
- // and all failed throw an error
- if !progressed && !throttled && len(pending) == 0 && len(idles) == d.peers.Len() && queued > 0 && !beaconMode {
- return errPeersUnavailable
- }
- }
- // Wait for something to happen
- select {
- case <-d.cancelCh:
- // If sync was cancelled, tear down the parallel retriever. Pending
- // requests will be cancelled locally, and the remote responses will
- // be dropped when they arrive
- return errCanceled
-
- case event := <-peering:
- // A peer joined or left, the tasks queue and allocations need to be
- // checked for potential assignment or reassignment
- peerid := event.peer.id
-
- if event.join {
- // Sanity check the internal state; this can be dropped later
- if _, ok := pending[peerid]; ok {
- event.peer.log.Error("Pending request exists for joining peer")
- }
- if _, ok := stales[peerid]; ok {
- event.peer.log.Error("Stale request exists for joining peer")
- }
- // Loop back to the entry point for task assignment
- continue
- }
- // A peer left, any existing requests need to be untracked, pending
- // tasks returned and possible reassignment checked
- if req, ok := pending[peerid]; ok {
- queue.unreserve(peerid) // TODO(karalabe): This needs a non-expiration method
- delete(pending, peerid)
- req.Close()
-
- if index, live := ordering[req]; live {
- timeouts.Remove(index)
- if index == 0 {
- if !timeout.Stop() {
- <-timeout.C
- }
- if timeouts.Size() > 0 {
- _, exp := timeouts.Peek()
- timeout.Reset(time.Until(time.Unix(0, -exp)))
- }
- }
- delete(ordering, req)
- }
- }
- if req, ok := stales[peerid]; ok {
- delete(stales, peerid)
- req.Close()
- }
-
- case <-timeout.C:
- // Retrieve the next request which should have timed out. The check
- // below is purely for to catch programming errors, given the correct
- // code, there's no possible order of events that should result in a
- // timeout firing for a non-existent event.
- req, exp := timeouts.Peek()
- if now, at := time.Now(), time.Unix(0, -exp); now.Before(at) {
- log.Error("Timeout triggered but not reached", "left", at.Sub(now))
- timeout.Reset(at.Sub(now))
- continue
- }
- // Stop tracking the timed out request from a timing perspective,
- // cancel it, so it's not considered in-flight anymore, but keep
- // the peer marked busy to prevent assigning a second request and
- // overloading it further.
- delete(pending, req.Peer)
- stales[req.Peer] = req
-
- timeouts.Pop() // Popping an item will reorder indices in `ordering`, delete after, otherwise will resurrect!
- if timeouts.Size() > 0 {
- _, exp := timeouts.Peek()
- timeout.Reset(time.Until(time.Unix(0, -exp)))
- }
- delete(ordering, req)
-
- // New timeout potentially set if there are more requests pending,
- // reschedule the failed one to a free peer
- fails := queue.unreserve(req.Peer)
-
- // Finally, update the peer's retrieval capacity, or if it's already
- // below the minimum allowance, drop the peer. If a lot of retrieval
- // elements expired, we might have overestimated the remote peer or
- // perhaps ourselves. Only reset to minimal throughput but don't drop
- // just yet.
- //
- // The reason the minimum threshold is 2 is that the downloader tries
- // to estimate the bandwidth and latency of a peer separately, which
- // requires pushing the measured capacity a bit and seeing how response
- // times reacts, to it always requests one more than the minimum (i.e.
- // min 2).
- peer := d.peers.Peer(req.Peer)
- if peer == nil {
- // If the peer got disconnected in between, we should really have
- // short-circuited it already. Just in case there's some strange
- // codepath, leave this check in not to crash.
- log.Error("Delivery timeout from unknown peer", "peer", req.Peer)
- continue
- }
- if fails > 2 {
- queue.updateCapacity(peer, 0, 0)
- } else {
- d.dropPeer(peer.id)
-
- // If this peer was the master peer, abort sync immediately
- d.cancelLock.RLock()
- master := peer.id == d.cancelPeer
- d.cancelLock.RUnlock()
-
- if master {
- d.cancel()
- return errTimeout
- }
- }
-
- case res := <-responses:
- // Response arrived, it may be for an existing or an already timed
- // out request. If the former, update the timeout heap and perhaps
- // reschedule the timeout timer.
- index, live := ordering[res.Req]
- if live {
- timeouts.Remove(index)
- if index == 0 {
- if !timeout.Stop() {
- <-timeout.C
- }
- if timeouts.Size() > 0 {
- _, exp := timeouts.Peek()
- timeout.Reset(time.Until(time.Unix(0, -exp)))
- }
- }
- delete(ordering, res.Req)
- }
- // Delete the pending request (if it still exists) and mark the peer idle
- delete(pending, res.Req.Peer)
- delete(stales, res.Req.Peer)
-
- // Signal the dispatcher that the round trip is done. We'll drop the
- // peer if the data turns out to be junk.
- res.Done <- nil
- res.Req.Close()
-
- // If the peer was previously banned and failed to deliver its pack
- // in a reasonable time frame, ignore its message.
- if peer := d.peers.Peer(res.Req.Peer); peer != nil {
- // Deliver the received chunk of data and check chain validity
- accepted, err := queue.deliver(peer, res)
- if errors.Is(err, errInvalidChain) {
- return err
- }
- // Unless a peer delivered something completely else than requested (usually
- // caused by a timed out request which came through in the end), set it to
- // idle. If the delivery's stale, the peer should have already been idled.
- if !errors.Is(err, errStaleDelivery) {
- queue.updateCapacity(peer, accepted, res.Time)
- }
- }
-
- case cont := <-queue.waker():
- // The header fetcher sent a continuation flag, check if it's done
- if !cont {
- finished = true
- }
- }
- }
-}
diff --git a/eth/downloader/fetchers_concurrent_bodies.go b/eth/downloader/fetchers_concurrent_bodies.go
deleted file mode 100644
index 5105fda66b..0000000000
--- a/eth/downloader/fetchers_concurrent_bodies.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2021 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 downloader
-
-import (
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// bodyQueue implements typedQueue and is a type adapter between the generic
-// concurrent fetcher and the downloader.
-type bodyQueue Downloader
-
-// waker returns a notification channel that gets pinged in case more body
-// fetches have been queued up, so the fetcher might assign it to idle peers.
-func (q *bodyQueue) waker() chan bool {
- return q.queue.blockWakeCh
-}
-
-// pending returns the number of bodies that are currently queued for fetching
-// by the concurrent downloader.
-func (q *bodyQueue) pending() int {
- return q.queue.PendingBodies()
-}
-
-// capacity is responsible for calculating how many bodies a particular peer is
-// estimated to be able to retrieve within the allotted round trip time.
-func (q *bodyQueue) capacity(peer *peerConnection, rtt time.Duration) int {
- return peer.BodyCapacity(rtt)
-}
-
-// updateCapacity is responsible for updating how many bodies a particular peer
-// is estimated to be able to retrieve in a unit time.
-func (q *bodyQueue) updateCapacity(peer *peerConnection, items int, span time.Duration) {
- peer.UpdateBodyRate(items, span)
-}
-
-// reserve is responsible for allocating a requested number of pending bodies
-// from the download queue to the specified peer.
-func (q *bodyQueue) reserve(peer *peerConnection, items int) (*fetchRequest, bool, bool) {
- return q.queue.ReserveBodies(peer, items)
-}
-
-// unreserve is responsible for removing the current body retrieval allocation
-// assigned to a specific peer and placing it back into the pool to allow
-// reassigning to some other peer.
-func (q *bodyQueue) unreserve(peer string) int {
- fails := q.queue.ExpireBodies(peer)
- if fails > 2 {
- log.Trace("Body delivery timed out", "peer", peer)
- } else {
- log.Debug("Body delivery stalling", "peer", peer)
- }
- return fails
-}
-
-// request is responsible for converting a generic fetch request into a body
-// one and sending it to the remote peer for fulfillment.
-func (q *bodyQueue) request(peer *peerConnection, req *fetchRequest, resCh chan *eth.Response) (*eth.Request, error) {
- peer.log.Trace("Requesting new batch of bodies", "count", len(req.Headers), "from", req.Headers[0].Number)
- if q.bodyFetchHook != nil {
- q.bodyFetchHook(req.Headers)
- }
-
- hashes := make([]common.Hash, 0, len(req.Headers))
- for _, header := range req.Headers {
- hashes = append(hashes, header.Hash())
- }
- return peer.peer.RequestBodies(hashes, resCh)
-}
-
-// deliver is responsible for taking a generic response packet from the concurrent
-// fetcher, unpacking the body data and delivering it to the downloader's queue.
-func (q *bodyQueue) deliver(peer *peerConnection, packet *eth.Response) (int, error) {
- txs, uncles, withdrawals := packet.Res.(*eth.BlockBodiesResponse).Unpack()
- hashsets := packet.Meta.([][]common.Hash) // {txs hashes, uncle hashes, withdrawal hashes}
-
- accepted, err := q.queue.DeliverBodies(peer.id, txs, hashsets[0], uncles, hashsets[1], withdrawals, hashsets[2])
- switch {
- case err == nil && len(txs) == 0:
- peer.log.Trace("Requested bodies delivered")
- case err == nil:
- peer.log.Trace("Delivered new batch of bodies", "count", len(txs), "accepted", accepted)
- default:
- peer.log.Debug("Failed to deliver retrieved bodies", "err", err)
- }
- return accepted, err
-}
diff --git a/eth/downloader/fetchers_concurrent_headers.go b/eth/downloader/fetchers_concurrent_headers.go
deleted file mode 100644
index 8201f4ca74..0000000000
--- a/eth/downloader/fetchers_concurrent_headers.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2021 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 downloader
-
-import (
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// headerQueue implements typedQueue and is a type adapter between the generic
-// concurrent fetcher and the downloader.
-type headerQueue Downloader
-
-// waker returns a notification channel that gets pinged in case more header
-// fetches have been queued up, so the fetcher might assign it to idle peers.
-func (q *headerQueue) waker() chan bool {
- return q.queue.headerContCh
-}
-
-// pending returns the number of headers that are currently queued for fetching
-// by the concurrent downloader.
-func (q *headerQueue) pending() int {
- return q.queue.PendingHeaders()
-}
-
-// capacity is responsible for calculating how many headers a particular peer is
-// estimated to be able to retrieve within the allotted round trip time.
-func (q *headerQueue) capacity(peer *peerConnection, rtt time.Duration) int {
- return peer.HeaderCapacity(rtt)
-}
-
-// updateCapacity is responsible for updating how many headers a particular peer
-// is estimated to be able to retrieve in a unit time.
-func (q *headerQueue) updateCapacity(peer *peerConnection, items int, span time.Duration) {
- peer.UpdateHeaderRate(items, span)
-}
-
-// reserve is responsible for allocating a requested number of pending headers
-// from the download queue to the specified peer.
-func (q *headerQueue) reserve(peer *peerConnection, items int) (*fetchRequest, bool, bool) {
- return q.queue.ReserveHeaders(peer, items), false, false
-}
-
-// unreserve is responsible for removing the current header retrieval allocation
-// assigned to a specific peer and placing it back into the pool to allow
-// reassigning to some other peer.
-func (q *headerQueue) unreserve(peer string) int {
- fails := q.queue.ExpireHeaders(peer)
- if fails > 2 {
- log.Trace("Header delivery timed out", "peer", peer)
- } else {
- log.Debug("Header delivery stalling", "peer", peer)
- }
- return fails
-}
-
-// request is responsible for converting a generic fetch request into a header
-// one and sending it to the remote peer for fulfillment.
-func (q *headerQueue) request(peer *peerConnection, req *fetchRequest, resCh chan *eth.Response) (*eth.Request, error) {
- peer.log.Trace("Requesting new batch of headers", "from", req.From)
- return peer.peer.RequestHeadersByNumber(req.From, MaxHeaderFetch, 0, false, resCh)
-}
-
-// deliver is responsible for taking a generic response packet from the concurrent
-// fetcher, unpacking the header data and delivering it to the downloader's queue.
-func (q *headerQueue) deliver(peer *peerConnection, packet *eth.Response) (int, error) {
- headers := *packet.Res.(*eth.BlockHeadersRequest)
- hashes := packet.Meta.([]common.Hash)
-
- accepted, err := q.queue.DeliverHeaders(peer.id, headers, hashes, q.headerProcCh)
- switch {
- case err == nil && len(headers) == 0:
- peer.log.Trace("Requested headers delivered")
- case err == nil:
- peer.log.Trace("Delivered new batch of headers", "count", len(headers), "accepted", accepted)
- default:
- peer.log.Debug("Failed to deliver retrieved headers", "err", err)
- }
- return accepted, err
-}
diff --git a/eth/downloader/fetchers_concurrent_receipts.go b/eth/downloader/fetchers_concurrent_receipts.go
deleted file mode 100644
index 3169f030ba..0000000000
--- a/eth/downloader/fetchers_concurrent_receipts.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2021 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 downloader
-
-import (
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// receiptQueue implements typedQueue and is a type adapter between the generic
-// concurrent fetcher and the downloader.
-type receiptQueue Downloader
-
-// waker returns a notification channel that gets pinged in case more receipt
-// fetches have been queued up, so the fetcher might assign it to idle peers.
-func (q *receiptQueue) waker() chan bool {
- return q.queue.receiptWakeCh
-}
-
-// pending returns the number of receipt that are currently queued for fetching
-// by the concurrent downloader.
-func (q *receiptQueue) pending() int {
- return q.queue.PendingReceipts()
-}
-
-// capacity is responsible for calculating how many receipts a particular peer is
-// estimated to be able to retrieve within the allotted round trip time.
-func (q *receiptQueue) capacity(peer *peerConnection, rtt time.Duration) int {
- return peer.ReceiptCapacity(rtt)
-}
-
-// updateCapacity is responsible for updating how many receipts a particular peer
-// is estimated to be able to retrieve in a unit time.
-func (q *receiptQueue) updateCapacity(peer *peerConnection, items int, span time.Duration) {
- peer.UpdateReceiptRate(items, span)
-}
-
-// reserve is responsible for allocating a requested number of pending receipts
-// from the download queue to the specified peer.
-func (q *receiptQueue) reserve(peer *peerConnection, items int) (*fetchRequest, bool, bool) {
- return q.queue.ReserveReceipts(peer, items)
-}
-
-// unreserve is responsible for removing the current receipt retrieval allocation
-// assigned to a specific peer and placing it back into the pool to allow
-// reassigning to some other peer.
-func (q *receiptQueue) unreserve(peer string) int {
- fails := q.queue.ExpireReceipts(peer)
- if fails > 2 {
- log.Trace("Receipt delivery timed out", "peer", peer)
- } else {
- log.Debug("Receipt delivery stalling", "peer", peer)
- }
- return fails
-}
-
-// request is responsible for converting a generic fetch request into a receipt
-// one and sending it to the remote peer for fulfillment.
-func (q *receiptQueue) request(peer *peerConnection, req *fetchRequest, resCh chan *eth.Response) (*eth.Request, error) {
- peer.log.Trace("Requesting new batch of receipts", "count", len(req.Headers), "from", req.Headers[0].Number)
- if q.receiptFetchHook != nil {
- q.receiptFetchHook(req.Headers)
- }
- hashes := make([]common.Hash, 0, len(req.Headers))
- for _, header := range req.Headers {
- hashes = append(hashes, header.Hash())
- }
- return peer.peer.RequestReceipts(hashes, resCh)
-}
-
-// deliver is responsible for taking a generic response packet from the concurrent
-// fetcher, unpacking the receipt data and delivering it to the downloader's queue.
-func (q *receiptQueue) deliver(peer *peerConnection, packet *eth.Response) (int, error) {
- receipts := *packet.Res.(*eth.ReceiptsResponse)
- hashes := packet.Meta.([]common.Hash) // {receipt hashes}
-
- accepted, err := q.queue.DeliverReceipts(peer.id, receipts, hashes)
- switch {
- case err == nil && len(receipts) == 0:
- peer.log.Trace("Requested receipts delivered")
- case err == nil:
- peer.log.Trace("Delivered new batch of receipts", "count", len(receipts), "accepted", accepted)
- default:
- peer.log.Debug("Failed to deliver retrieved receipts", "err", err)
- }
- return accepted, err
-}
diff --git a/eth/downloader/metrics.go b/eth/downloader/metrics.go
deleted file mode 100644
index 23c033a8ad..0000000000
--- a/eth/downloader/metrics.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2015 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 the metrics collected by the downloader.
-
-package downloader
-
-import (
- "github.com/ethereum/go-ethereum/metrics"
-)
-
-var (
- headerInMeter = metrics.NewRegisteredMeter("eth/downloader/headers/in", nil)
- headerReqTimer = metrics.NewRegisteredTimer("eth/downloader/headers/req", nil)
- headerDropMeter = metrics.NewRegisteredMeter("eth/downloader/headers/drop", nil)
- headerTimeoutMeter = metrics.NewRegisteredMeter("eth/downloader/headers/timeout", nil)
-
- bodyInMeter = metrics.NewRegisteredMeter("eth/downloader/bodies/in", nil)
- bodyReqTimer = metrics.NewRegisteredTimer("eth/downloader/bodies/req", nil)
- bodyDropMeter = metrics.NewRegisteredMeter("eth/downloader/bodies/drop", nil)
- bodyTimeoutMeter = metrics.NewRegisteredMeter("eth/downloader/bodies/timeout", nil)
-
- receiptInMeter = metrics.NewRegisteredMeter("eth/downloader/receipts/in", nil)
- receiptReqTimer = metrics.NewRegisteredTimer("eth/downloader/receipts/req", nil)
- receiptDropMeter = metrics.NewRegisteredMeter("eth/downloader/receipts/drop", nil)
- receiptTimeoutMeter = metrics.NewRegisteredMeter("eth/downloader/receipts/timeout", nil)
-
- throttleCounter = metrics.NewRegisteredCounter("eth/downloader/throttle", nil)
-)
diff --git a/eth/downloader/modes.go b/eth/downloader/modes.go
deleted file mode 100644
index d388b9ee4d..0000000000
--- a/eth/downloader/modes.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2015 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 downloader
-
-import "fmt"
-
-// SyncMode represents the synchronisation mode of the downloader.
-// It is a uint32 as it is used with atomic operations.
-type SyncMode uint32
-
-const (
- FullSync SyncMode = iota // Synchronise the entire blockchain history from full blocks
- SnapSync // Download the chain and the state via compact snapshots
- LightSync // Download only the headers and terminate afterwards
-)
-
-func (mode SyncMode) IsValid() bool {
- return mode >= FullSync && mode <= LightSync
-}
-
-// String implements the stringer interface.
-func (mode SyncMode) String() string {
- switch mode {
- case FullSync:
- return "full"
- case SnapSync:
- return "snap"
- case LightSync:
- return "light"
- default:
- return "unknown"
- }
-}
-
-func (mode SyncMode) MarshalText() ([]byte, error) {
- switch mode {
- case FullSync:
- return []byte("full"), nil
- case SnapSync:
- return []byte("snap"), nil
- case LightSync:
- return []byte("light"), nil
- default:
- return nil, fmt.Errorf("unknown sync mode %d", mode)
- }
-}
-
-func (mode *SyncMode) UnmarshalText(text []byte) error {
- switch string(text) {
- case "full":
- *mode = FullSync
- case "snap":
- *mode = SnapSync
- case "light":
- *mode = LightSync
- default:
- return fmt.Errorf(`unknown sync mode %q, want "full", "snap" or "light"`, text)
- }
- return nil
-}
diff --git a/eth/downloader/peer.go b/eth/downloader/peer.go
deleted file mode 100644
index 4c43af5270..0000000000
--- a/eth/downloader/peer.go
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2015 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 the active peer-set of the downloader, maintaining both failures
-// as well as reputation metrics to prioritize the block retrievals.
-
-package downloader
-
-import (
- "errors"
- "math/big"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/msgrate"
-)
-
-const (
- maxLackingHashes = 4096 // Maximum number of entries allowed on the list or lacking items
-)
-
-var (
- errAlreadyRegistered = errors.New("peer is already registered")
- errNotRegistered = errors.New("peer is not registered")
-)
-
-// peerConnection represents an active peer from which hashes and blocks are retrieved.
-type peerConnection struct {
- id string // Unique identifier of the peer
-
- rates *msgrate.Tracker // Tracker to hone in on the number of items retrievable per second
- lacking map[common.Hash]struct{} // Set of hashes not to request (didn't have previously)
-
- peer Peer
-
- version uint // Eth protocol version number to switch strategies
- log log.Logger // Contextual logger to add extra infos to peer logs
- lock sync.RWMutex
-}
-
-// Peer encapsulates the methods required to synchronise with a remote full peer.
-type Peer interface {
- Head() (common.Hash, *big.Int)
- RequestHeadersByHash(common.Hash, int, int, bool, chan *eth.Response) (*eth.Request, error)
- RequestHeadersByNumber(uint64, int, int, bool, chan *eth.Response) (*eth.Request, error)
-
- RequestBodies([]common.Hash, chan *eth.Response) (*eth.Request, error)
- RequestReceipts([]common.Hash, chan *eth.Response) (*eth.Request, error)
-}
-
-// newPeerConnection creates a new downloader peer.
-func newPeerConnection(id string, version uint, peer Peer, logger log.Logger) *peerConnection {
- return &peerConnection{
- id: id,
- lacking: make(map[common.Hash]struct{}),
- peer: peer,
- version: version,
- log: logger,
- }
-}
-
-// Reset clears the internal state of a peer entity.
-func (p *peerConnection) Reset() {
- p.lock.Lock()
- defer p.lock.Unlock()
-
- p.lacking = make(map[common.Hash]struct{})
-}
-
-// UpdateHeaderRate updates the peer's estimated header retrieval throughput with
-// the current measurement.
-func (p *peerConnection) UpdateHeaderRate(delivered int, elapsed time.Duration) {
- p.rates.Update(eth.BlockHeadersMsg, elapsed, delivered)
-}
-
-// UpdateBodyRate updates the peer's estimated body retrieval throughput with the
-// current measurement.
-func (p *peerConnection) UpdateBodyRate(delivered int, elapsed time.Duration) {
- p.rates.Update(eth.BlockBodiesMsg, elapsed, delivered)
-}
-
-// UpdateReceiptRate updates the peer's estimated receipt retrieval throughput
-// with the current measurement.
-func (p *peerConnection) UpdateReceiptRate(delivered int, elapsed time.Duration) {
- p.rates.Update(eth.ReceiptsMsg, elapsed, delivered)
-}
-
-// HeaderCapacity retrieves the peer's header download allowance based on its
-// previously discovered throughput.
-func (p *peerConnection) HeaderCapacity(targetRTT time.Duration) int {
- cap := p.rates.Capacity(eth.BlockHeadersMsg, targetRTT)
- if cap > MaxHeaderFetch {
- cap = MaxHeaderFetch
- }
- return cap
-}
-
-// BodyCapacity retrieves the peer's body download allowance based on its
-// previously discovered throughput.
-func (p *peerConnection) BodyCapacity(targetRTT time.Duration) int {
- cap := p.rates.Capacity(eth.BlockBodiesMsg, targetRTT)
- if cap > MaxBlockFetch {
- cap = MaxBlockFetch
- }
- return cap
-}
-
-// ReceiptCapacity retrieves the peers receipt download allowance based on its
-// previously discovered throughput.
-func (p *peerConnection) ReceiptCapacity(targetRTT time.Duration) int {
- cap := p.rates.Capacity(eth.ReceiptsMsg, targetRTT)
- if cap > MaxReceiptFetch {
- cap = MaxReceiptFetch
- }
- return cap
-}
-
-// MarkLacking appends a new entity to the set of items (blocks, receipts, states)
-// that a peer is known not to have (i.e. have been requested before). If the
-// set reaches its maximum allowed capacity, items are randomly dropped off.
-func (p *peerConnection) MarkLacking(hash common.Hash) {
- p.lock.Lock()
- defer p.lock.Unlock()
-
- for len(p.lacking) >= maxLackingHashes {
- for drop := range p.lacking {
- delete(p.lacking, drop)
- break
- }
- }
- p.lacking[hash] = struct{}{}
-}
-
-// Lacks retrieves whether the hash of a blockchain item is on the peers lacking
-// list (i.e. whether we know that the peer does not have it).
-func (p *peerConnection) Lacks(hash common.Hash) bool {
- p.lock.RLock()
- defer p.lock.RUnlock()
-
- _, ok := p.lacking[hash]
- return ok
-}
-
-// peeringEvent is sent on the peer event feed when a remote peer connects or
-// disconnects.
-type peeringEvent struct {
- peer *peerConnection
- join bool
-}
-
-// peerSet represents the collection of active peer participating in the chain
-// download procedure.
-type peerSet struct {
- peers map[string]*peerConnection
- rates *msgrate.Trackers // Set of rate trackers to give the sync a common beat
- events event.Feed // Feed to publish peer lifecycle events on
-
- lock sync.RWMutex
-}
-
-// newPeerSet creates a new peer set top track the active download sources.
-func newPeerSet() *peerSet {
- return &peerSet{
- peers: make(map[string]*peerConnection),
- rates: msgrate.NewTrackers(log.New("proto", "eth")),
- }
-}
-
-// SubscribeEvents subscribes to peer arrival and departure events.
-func (ps *peerSet) SubscribeEvents(ch chan<- *peeringEvent) event.Subscription {
- return ps.events.Subscribe(ch)
-}
-
-// Reset iterates over the current peer set, and resets each of the known peers
-// to prepare for a next batch of block retrieval.
-func (ps *peerSet) Reset() {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- for _, peer := range ps.peers {
- peer.Reset()
- }
-}
-
-// Register injects a new peer into the working set, or returns an error if the
-// peer is already known.
-//
-// The method also sets the starting throughput values of the new peer to the
-// average of all existing peers, to give it a realistic chance of being used
-// for data retrievals.
-func (ps *peerSet) Register(p *peerConnection) error {
- // Register the new peer with some meaningful defaults
- ps.lock.Lock()
- if _, ok := ps.peers[p.id]; ok {
- ps.lock.Unlock()
- return errAlreadyRegistered
- }
- p.rates = msgrate.NewTracker(ps.rates.MeanCapacities(), ps.rates.MedianRoundTrip())
- if err := ps.rates.Track(p.id, p.rates); err != nil {
- ps.lock.Unlock()
- return err
- }
- ps.peers[p.id] = p
- ps.lock.Unlock()
-
- ps.events.Send(&peeringEvent{peer: p, join: true})
- return nil
-}
-
-// Unregister removes a remote peer from the active set, disabling any further
-// actions to/from that particular entity.
-func (ps *peerSet) Unregister(id string) error {
- ps.lock.Lock()
- p, ok := ps.peers[id]
- if !ok {
- ps.lock.Unlock()
- return errNotRegistered
- }
- delete(ps.peers, id)
- ps.rates.Untrack(id)
- ps.lock.Unlock()
-
- ps.events.Send(&peeringEvent{peer: p, join: false})
- return nil
-}
-
-// Peer retrieves the registered peer with the given id.
-func (ps *peerSet) Peer(id string) *peerConnection {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- return ps.peers[id]
-}
-
-// Len returns if the current number of peers in the set.
-func (ps *peerSet) Len() int {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- return len(ps.peers)
-}
-
-// AllPeers retrieves a flat list of all the peers within the set.
-func (ps *peerSet) AllPeers() []*peerConnection {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- list := make([]*peerConnection, 0, len(ps.peers))
- for _, p := range ps.peers {
- list = append(list, p)
- }
- return list
-}
-
-// peerCapacitySort implements sort.Interface.
-// It sorts peer connections by capacity (descending).
-type peerCapacitySort struct {
- peers []*peerConnection
- caps []int
-}
-
-func (ps *peerCapacitySort) Len() int {
- return len(ps.peers)
-}
-
-func (ps *peerCapacitySort) Less(i, j int) bool {
- return ps.caps[i] > ps.caps[j]
-}
-
-func (ps *peerCapacitySort) Swap(i, j int) {
- ps.peers[i], ps.peers[j] = ps.peers[j], ps.peers[i]
- ps.caps[i], ps.caps[j] = ps.caps[j], ps.caps[i]
-}
diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go
deleted file mode 100644
index e557158797..0000000000
--- a/eth/downloader/queue.go
+++ /dev/null
@@ -1,956 +0,0 @@
-// Copyright 2015 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 the block download scheduler to collect download tasks and schedule
-// them in an ordered, and throttled way.
-
-package downloader
-
-import (
- "errors"
- "fmt"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/prque"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/params"
-)
-
-const (
- bodyType = uint(0)
- receiptType = uint(1)
-)
-
-var (
- blockCacheMaxItems = 8192 // Maximum number of blocks to cache before throttling the download
- blockCacheInitialItems = 2048 // Initial number of blocks to start fetching, before we know the sizes of the blocks
- blockCacheMemory = 256 * 1024 * 1024 // Maximum amount of memory to use for block caching
- blockCacheSizeWeight = 0.1 // Multiplier to approximate the average block size based on past ones
-)
-
-var (
- errNoFetchesPending = errors.New("no fetches pending")
- errStaleDelivery = errors.New("stale delivery")
-)
-
-// fetchRequest is a currently running data retrieval operation.
-type fetchRequest struct {
- Peer *peerConnection // Peer to which the request was sent
- From uint64 // Requested chain element index (used for skeleton fills only)
- Headers []*types.Header // Requested headers, sorted by request order
- Time time.Time // Time when the request was made
-}
-
-// fetchResult is a struct collecting partial results from data fetchers until
-// all outstanding pieces complete and the result as a whole can be processed.
-type fetchResult struct {
- pending atomic.Int32 // Flag telling what deliveries are outstanding
-
- Header *types.Header
- Uncles []*types.Header
- Transactions types.Transactions
- Receipts types.Receipts
- Withdrawals types.Withdrawals
-}
-
-func newFetchResult(header *types.Header, fastSync bool) *fetchResult {
- item := &fetchResult{
- Header: header,
- }
- if !header.EmptyBody() {
- item.pending.Store(item.pending.Load() | (1 << bodyType))
- } else if header.WithdrawalsHash != nil {
- item.Withdrawals = make(types.Withdrawals, 0)
- }
- if fastSync && !header.EmptyReceipts() {
- item.pending.Store(item.pending.Load() | (1 << receiptType))
- }
- return item
-}
-
-// SetBodyDone flags the body as finished.
-func (f *fetchResult) SetBodyDone() {
- if v := f.pending.Load(); (v & (1 << bodyType)) != 0 {
- f.pending.Add(-1)
- }
-}
-
-// AllDone checks if item is done.
-func (f *fetchResult) AllDone() bool {
- return f.pending.Load() == 0
-}
-
-// SetReceiptsDone flags the receipts as finished.
-func (f *fetchResult) SetReceiptsDone() {
- if v := f.pending.Load(); (v & (1 << receiptType)) != 0 {
- f.pending.Add(-2)
- }
-}
-
-// Done checks if the given type is done already
-func (f *fetchResult) Done(kind uint) bool {
- v := f.pending.Load()
- return v&(1< 0
-}
-
-// InFlightReceipts retrieves whether there are receipt fetch requests currently
-// in flight.
-func (q *queue) InFlightReceipts() bool {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- return len(q.receiptPendPool) > 0
-}
-
-// Idle returns if the queue is fully idle or has some data still inside.
-func (q *queue) Idle() bool {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- queued := q.blockTaskQueue.Size() + q.receiptTaskQueue.Size()
- pending := len(q.blockPendPool) + len(q.receiptPendPool)
-
- return (queued + pending) == 0
-}
-
-// ScheduleSkeleton adds a batch of header retrieval tasks to the queue to fill
-// up an already retrieved header skeleton.
-func (q *queue) ScheduleSkeleton(from uint64, skeleton []*types.Header) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- // No skeleton retrieval can be in progress, fail hard if so (huge implementation bug)
- if q.headerResults != nil {
- panic("skeleton assembly already in progress")
- }
- // Schedule all the header retrieval tasks for the skeleton assembly
- q.headerTaskPool = make(map[uint64]*types.Header)
- q.headerTaskQueue = prque.New[int64, uint64](nil)
- q.headerPeerMiss = make(map[string]map[uint64]struct{}) // Reset availability to correct invalid chains
- q.headerResults = make([]*types.Header, len(skeleton)*MaxHeaderFetch)
- q.headerHashes = make([]common.Hash, len(skeleton)*MaxHeaderFetch)
- q.headerProced = 0
- q.headerOffset = from
- q.headerContCh = make(chan bool, 1)
-
- for i, header := range skeleton {
- index := from + uint64(i*MaxHeaderFetch)
-
- q.headerTaskPool[index] = header
- q.headerTaskQueue.Push(index, -int64(index))
- }
-}
-
-// RetrieveHeaders retrieves the header chain assemble based on the scheduled
-// skeleton.
-func (q *queue) RetrieveHeaders() ([]*types.Header, []common.Hash, int) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- headers, hashes, proced := q.headerResults, q.headerHashes, q.headerProced
- q.headerResults, q.headerHashes, q.headerProced = nil, nil, 0
-
- return headers, hashes, proced
-}
-
-// Schedule adds a set of headers for the download queue for scheduling, returning
-// the new headers encountered.
-func (q *queue) Schedule(headers []*types.Header, hashes []common.Hash, from uint64) []*types.Header {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- // Insert all the headers prioritised by the contained block number
- inserts := make([]*types.Header, 0, len(headers))
- for i, header := range headers {
- // Make sure chain order is honoured and preserved throughout
- hash := hashes[i]
- if header.Number == nil || header.Number.Uint64() != from {
- log.Warn("Header broke chain ordering", "number", header.Number, "hash", hash, "expected", from)
- break
- }
- if q.headerHead != (common.Hash{}) && q.headerHead != header.ParentHash {
- log.Warn("Header broke chain ancestry", "number", header.Number, "hash", hash)
- break
- }
- // Make sure no duplicate requests are executed
- // We cannot skip this, even if the block is empty, since this is
- // what triggers the fetchResult creation.
- if _, ok := q.blockTaskPool[hash]; ok {
- log.Warn("Header already scheduled for block fetch", "number", header.Number, "hash", hash)
- } else {
- q.blockTaskPool[hash] = header
- q.blockTaskQueue.Push(header, -int64(header.Number.Uint64()))
- }
- // Queue for receipt retrieval
- if q.mode == SnapSync && !header.EmptyReceipts() {
- if _, ok := q.receiptTaskPool[hash]; ok {
- log.Warn("Header already scheduled for receipt fetch", "number", header.Number, "hash", hash)
- } else {
- q.receiptTaskPool[hash] = header
- q.receiptTaskQueue.Push(header, -int64(header.Number.Uint64()))
- }
- }
- inserts = append(inserts, header)
- q.headerHead = hash
- from++
- }
- return inserts
-}
-
-// Results retrieves and permanently removes a batch of fetch results from
-// the cache. the result slice will be empty if the queue has been closed.
-// Results can be called concurrently with Deliver and Schedule,
-// but assumes that there are not two simultaneous callers to Results
-func (q *queue) Results(block bool) []*fetchResult {
- // Abort early if there are no items and non-blocking requested
- if !block && !q.resultCache.HasCompletedItems() {
- return nil
- }
- closed := false
- for !closed && !q.resultCache.HasCompletedItems() {
- // In order to wait on 'active', we need to obtain the lock.
- // That may take a while, if someone is delivering at the same
- // time, so after obtaining the lock, we check again if there
- // are any results to fetch.
- // Also, in-between we ask for the lock and the lock is obtained,
- // someone can have closed the queue. In that case, we should
- // return the available results and stop blocking
- q.lock.Lock()
- if q.resultCache.HasCompletedItems() || q.closed {
- q.lock.Unlock()
- break
- }
- // No items available, and not closed
- q.active.Wait()
- closed = q.closed
- q.lock.Unlock()
- }
- // Regardless if closed or not, we can still deliver whatever we have
- results := q.resultCache.GetCompleted(maxResultsProcess)
- for _, result := range results {
- // Recalculate the result item weights to prevent memory exhaustion
- size := result.Header.Size()
- for _, uncle := range result.Uncles {
- size += uncle.Size()
- }
- for _, receipt := range result.Receipts {
- size += receipt.Size()
- }
- for _, tx := range result.Transactions {
- size += common.StorageSize(tx.Size())
- }
- q.resultSize = common.StorageSize(blockCacheSizeWeight)*size +
- (1-common.StorageSize(blockCacheSizeWeight))*q.resultSize
- }
- // Using the newly calibrated resultsize, figure out the new throttle limit
- // on the result cache
- throttleThreshold := uint64((common.StorageSize(blockCacheMemory) + q.resultSize - 1) / q.resultSize)
- throttleThreshold = q.resultCache.SetThrottleThreshold(throttleThreshold)
-
- // With results removed from the cache, wake throttled fetchers
- for _, ch := range []chan bool{q.blockWakeCh, q.receiptWakeCh} {
- select {
- case ch <- true:
- default:
- }
- }
- // Log some info at certain times
- if time.Since(q.logTime) >= 60*time.Second {
- q.logTime = time.Now()
-
- info := q.Stats()
- info = append(info, "throttle", throttleThreshold)
- log.Debug("Downloader queue stats", info...)
- }
- return results
-}
-
-func (q *queue) Stats() []interface{} {
- q.lock.RLock()
- defer q.lock.RUnlock()
-
- return q.stats()
-}
-
-func (q *queue) stats() []interface{} {
- return []interface{}{
- "receiptTasks", q.receiptTaskQueue.Size(),
- "blockTasks", q.blockTaskQueue.Size(),
- "itemSize", q.resultSize,
- }
-}
-
-// ReserveHeaders reserves a set of headers for the given peer, skipping any
-// previously failed batches.
-func (q *queue) ReserveHeaders(p *peerConnection, count int) *fetchRequest {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- // Short circuit if the peer's already downloading something (sanity check to
- // not corrupt state)
- if _, ok := q.headerPendPool[p.id]; ok {
- return nil
- }
- // Retrieve a batch of hashes, skipping previously failed ones
- send, skip := uint64(0), []uint64{}
- for send == 0 && !q.headerTaskQueue.Empty() {
- from, _ := q.headerTaskQueue.Pop()
- if q.headerPeerMiss[p.id] != nil {
- if _, ok := q.headerPeerMiss[p.id][from]; ok {
- skip = append(skip, from)
- continue
- }
- }
- send = from
- }
- // Merge all the skipped batches back
- for _, from := range skip {
- q.headerTaskQueue.Push(from, -int64(from))
- }
- // Assemble and return the block download request
- if send == 0 {
- return nil
- }
- request := &fetchRequest{
- Peer: p,
- From: send,
- Time: time.Now(),
- }
- q.headerPendPool[p.id] = request
- return request
-}
-
-// ReserveBodies reserves a set of body fetches for the given peer, skipping any
-// previously failed downloads. Beside the next batch of needed fetches, it also
-// returns a flag whether empty blocks were queued requiring processing.
-func (q *queue) ReserveBodies(p *peerConnection, count int) (*fetchRequest, bool, bool) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- return q.reserveHeaders(p, count, q.blockTaskPool, q.blockTaskQueue, q.blockPendPool, bodyType)
-}
-
-// ReserveReceipts reserves a set of receipt fetches for the given peer, skipping
-// any previously failed downloads. Beside the next batch of needed fetches, it
-// also returns a flag whether empty receipts were queued requiring importing.
-func (q *queue) ReserveReceipts(p *peerConnection, count int) (*fetchRequest, bool, bool) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- return q.reserveHeaders(p, count, q.receiptTaskPool, q.receiptTaskQueue, q.receiptPendPool, receiptType)
-}
-
-// reserveHeaders reserves a set of data download operations for a given peer,
-// skipping any previously failed ones. This method is a generic version used
-// by the individual special reservation functions.
-//
-// Note, this method expects the queue lock to be already held for writing. The
-// reason the lock is not obtained in here is because the parameters already need
-// to access the queue, so they already need a lock anyway.
-//
-// Returns:
-//
-// item - the fetchRequest
-// progress - whether any progress was made
-// throttle - if the caller should throttle for a while
-func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common.Hash]*types.Header, taskQueue *prque.Prque[int64, *types.Header],
- pendPool map[string]*fetchRequest, kind uint) (*fetchRequest, bool, bool) {
- // Short circuit if the pool has been depleted, or if the peer's already
- // downloading something (sanity check not to corrupt state)
- if taskQueue.Empty() {
- return nil, false, true
- }
- if _, ok := pendPool[p.id]; ok {
- return nil, false, false
- }
- // Retrieve a batch of tasks, skipping previously failed ones
- send := make([]*types.Header, 0, count)
- skip := make([]*types.Header, 0)
- progress := false
- throttled := false
- for proc := 0; len(send) < count && !taskQueue.Empty(); proc++ {
- // the task queue will pop items in order, so the highest prio block
- // is also the lowest block number.
- header, _ := taskQueue.Peek()
-
- // we can ask the resultcache if this header is within the
- // "prioritized" segment of blocks. If it is not, we need to throttle
-
- stale, throttle, item, err := q.resultCache.AddFetch(header, q.mode == SnapSync)
- if stale {
- // Don't put back in the task queue, this item has already been
- // delivered upstream
- taskQueue.PopItem()
- progress = true
- delete(taskPool, header.Hash())
- proc = proc - 1
- log.Error("Fetch reservation already delivered", "number", header.Number.Uint64())
- continue
- }
- if throttle {
- // There are no resultslots available. Leave it in the task queue
- // However, if there are any left as 'skipped', we should not tell
- // the caller to throttle, since we still want some other
- // peer to fetch those for us
- throttled = len(skip) == 0
- break
- }
- if err != nil {
- // this most definitely should _not_ happen
- log.Warn("Failed to reserve headers", "err", err)
- // There are no resultslots available. Leave it in the task queue
- break
- }
- if item.Done(kind) {
- // If it's a noop, we can skip this task
- delete(taskPool, header.Hash())
- taskQueue.PopItem()
- proc = proc - 1
- progress = true
- continue
- }
- // Remove it from the task queue
- taskQueue.PopItem()
- // Otherwise unless the peer is known not to have the data, add to the retrieve list
- if p.Lacks(header.Hash()) {
- skip = append(skip, header)
- } else {
- send = append(send, header)
- }
- }
- // Merge all the skipped headers back
- for _, header := range skip {
- taskQueue.Push(header, -int64(header.Number.Uint64()))
- }
- if q.resultCache.HasCompletedItems() {
- // Wake Results, resultCache was modified
- q.active.Signal()
- }
- // Assemble and return the block download request
- if len(send) == 0 {
- return nil, progress, throttled
- }
- request := &fetchRequest{
- Peer: p,
- Headers: send,
- Time: time.Now(),
- }
- pendPool[p.id] = request
- return request, progress, throttled
-}
-
-// Revoke cancels all pending requests belonging to a given peer. This method is
-// meant to be called during a peer drop to quickly reassign owned data fetches
-// to remaining nodes.
-func (q *queue) Revoke(peerID string) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- if request, ok := q.headerPendPool[peerID]; ok {
- q.headerTaskQueue.Push(request.From, -int64(request.From))
- delete(q.headerPendPool, peerID)
- }
- if request, ok := q.blockPendPool[peerID]; ok {
- for _, header := range request.Headers {
- q.blockTaskQueue.Push(header, -int64(header.Number.Uint64()))
- }
- delete(q.blockPendPool, peerID)
- }
- if request, ok := q.receiptPendPool[peerID]; ok {
- for _, header := range request.Headers {
- q.receiptTaskQueue.Push(header, -int64(header.Number.Uint64()))
- }
- delete(q.receiptPendPool, peerID)
- }
-}
-
-// ExpireHeaders cancels a request that timed out and moves the pending fetch
-// task back into the queue for rescheduling.
-func (q *queue) ExpireHeaders(peer string) int {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- headerTimeoutMeter.Mark(1)
- return q.expire(peer, q.headerPendPool, q.headerTaskQueue)
-}
-
-// ExpireBodies checks for in flight block body requests that exceeded a timeout
-// allowance, canceling them and returning the responsible peers for penalisation.
-func (q *queue) ExpireBodies(peer string) int {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- bodyTimeoutMeter.Mark(1)
- return q.expire(peer, q.blockPendPool, q.blockTaskQueue)
-}
-
-// ExpireReceipts checks for in flight receipt requests that exceeded a timeout
-// allowance, canceling them and returning the responsible peers for penalisation.
-func (q *queue) ExpireReceipts(peer string) int {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- receiptTimeoutMeter.Mark(1)
- return q.expire(peer, q.receiptPendPool, q.receiptTaskQueue)
-}
-
-// expire is the generic check that moves a specific expired task from a pending
-// pool back into a task pool. The syntax on the passed taskQueue is a bit weird
-// as we would need a generic expire method to handle both types, but that is not
-// supported at the moment at least (Go 1.19).
-//
-// Note, this method expects the queue lock to be already held. The reason the
-// lock is not obtained in here is that the parameters already need to access
-// the queue, so they already need a lock anyway.
-func (q *queue) expire(peer string, pendPool map[string]*fetchRequest, taskQueue interface{}) int {
- // Retrieve the request being expired and log an error if it's non-existent,
- // as there's no order of events that should lead to such expirations.
- req := pendPool[peer]
- if req == nil {
- log.Error("Expired request does not exist", "peer", peer)
- return 0
- }
- delete(pendPool, peer)
-
- // Return any non-satisfied requests to the pool
- if req.From > 0 {
- taskQueue.(*prque.Prque[int64, uint64]).Push(req.From, -int64(req.From))
- }
- for _, header := range req.Headers {
- taskQueue.(*prque.Prque[int64, *types.Header]).Push(header, -int64(header.Number.Uint64()))
- }
- return len(req.Headers)
-}
-
-// DeliverHeaders injects a header retrieval response into the header results
-// cache. This method either accepts all headers it received, or none of them
-// if they do not map correctly to the skeleton.
-//
-// If the headers are accepted, the method makes an attempt to deliver the set
-// of ready headers to the processor to keep the pipeline full. However, it will
-// not block to prevent stalling other pending deliveries.
-func (q *queue) DeliverHeaders(id string, headers []*types.Header, hashes []common.Hash, headerProcCh chan *headerTask) (int, error) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- var logger log.Logger
- if len(id) < 16 {
- // Tests use short IDs, don't choke on them
- logger = log.New("peer", id)
- } else {
- logger = log.New("peer", id[:16])
- }
- // Short circuit if the data was never requested
- request := q.headerPendPool[id]
- if request == nil {
- headerDropMeter.Mark(int64(len(headers)))
- return 0, errNoFetchesPending
- }
- delete(q.headerPendPool, id)
-
- headerReqTimer.UpdateSince(request.Time)
- headerInMeter.Mark(int64(len(headers)))
-
- // Ensure headers can be mapped onto the skeleton chain
- target := q.headerTaskPool[request.From].Hash()
-
- accepted := len(headers) == MaxHeaderFetch
- if accepted {
- if headers[0].Number.Uint64() != request.From {
- logger.Trace("First header broke chain ordering", "number", headers[0].Number, "hash", hashes[0], "expected", request.From)
- accepted = false
- } else if hashes[len(headers)-1] != target {
- logger.Trace("Last header broke skeleton structure ", "number", headers[len(headers)-1].Number, "hash", hashes[len(headers)-1], "expected", target)
- accepted = false
- }
- }
- if accepted {
- parentHash := hashes[0]
- for i, header := range headers[1:] {
- hash := hashes[i+1]
- if want := request.From + 1 + uint64(i); header.Number.Uint64() != want {
- logger.Warn("Header broke chain ordering", "number", header.Number, "hash", hash, "expected", want)
- accepted = false
- break
- }
- if parentHash != header.ParentHash {
- logger.Warn("Header broke chain ancestry", "number", header.Number, "hash", hash)
- accepted = false
- break
- }
- // Set-up parent hash for next round
- parentHash = hash
- }
- }
- // If the batch of headers wasn't accepted, mark as unavailable
- if !accepted {
- logger.Trace("Skeleton filling not accepted", "from", request.From)
- headerDropMeter.Mark(int64(len(headers)))
-
- miss := q.headerPeerMiss[id]
- if miss == nil {
- q.headerPeerMiss[id] = make(map[uint64]struct{})
- miss = q.headerPeerMiss[id]
- }
- miss[request.From] = struct{}{}
-
- q.headerTaskQueue.Push(request.From, -int64(request.From))
- return 0, errors.New("delivery not accepted")
- }
- // Clean up a successful fetch and try to deliver any sub-results
- copy(q.headerResults[request.From-q.headerOffset:], headers)
- copy(q.headerHashes[request.From-q.headerOffset:], hashes)
-
- delete(q.headerTaskPool, request.From)
-
- ready := 0
- for q.headerProced+ready < len(q.headerResults) && q.headerResults[q.headerProced+ready] != nil {
- ready += MaxHeaderFetch
- }
- if ready > 0 {
- // Headers are ready for delivery, gather them and push forward (non blocking)
- processHeaders := make([]*types.Header, ready)
- copy(processHeaders, q.headerResults[q.headerProced:q.headerProced+ready])
-
- processHashes := make([]common.Hash, ready)
- copy(processHashes, q.headerHashes[q.headerProced:q.headerProced+ready])
-
- select {
- case headerProcCh <- &headerTask{
- headers: processHeaders,
- hashes: processHashes,
- }:
- logger.Trace("Pre-scheduled new headers", "count", len(processHeaders), "from", processHeaders[0].Number)
- q.headerProced += len(processHeaders)
- default:
- }
- }
- // Check for termination and return
- if len(q.headerTaskPool) == 0 {
- q.headerContCh <- false
- }
- return len(headers), nil
-}
-
-// DeliverBodies injects a block body retrieval response into the results queue.
-// The method returns the number of blocks bodies accepted from the delivery and
-// also wakes any threads waiting for data delivery.
-func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListHashes []common.Hash,
- uncleLists [][]*types.Header, uncleListHashes []common.Hash,
- withdrawalLists [][]*types.Withdrawal, withdrawalListHashes []common.Hash) (int, error) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- validate := func(index int, header *types.Header) error {
- if txListHashes[index] != header.TxHash {
- return errInvalidBody
- }
- if uncleListHashes[index] != header.UncleHash {
- return errInvalidBody
- }
- if header.WithdrawalsHash == nil {
- // nil hash means that withdrawals should not be present in body
- if withdrawalLists[index] != nil {
- return errInvalidBody
- }
- } else { // non-nil hash: body must have withdrawals
- if withdrawalLists[index] == nil {
- return errInvalidBody
- }
- if withdrawalListHashes[index] != *header.WithdrawalsHash {
- return errInvalidBody
- }
- }
- // Blocks must have a number of blobs corresponding to the header gas usage,
- // and zero before the Cancun hardfork.
- var blobs int
- for _, tx := range txLists[index] {
- // Count the number of blobs to validate against the header's blobGasUsed
- blobs += len(tx.BlobHashes())
-
- // Validate the data blobs individually too
- if tx.Type() == types.BlobTxType {
- if len(tx.BlobHashes()) == 0 {
- return errInvalidBody
- }
- for _, hash := range tx.BlobHashes() {
- if hash[0] != params.BlobTxHashVersion {
- return errInvalidBody
- }
- }
- if tx.BlobTxSidecar() != nil {
- return errInvalidBody
- }
- }
- }
- if header.BlobGasUsed != nil {
- if want := *header.BlobGasUsed / params.BlobTxBlobGasPerBlob; uint64(blobs) != want { // div because the header is surely good vs the body might be bloated
- return errInvalidBody
- }
- } else {
- if blobs != 0 {
- return errInvalidBody
- }
- }
- return nil
- }
-
- reconstruct := func(index int, result *fetchResult) {
- result.Transactions = txLists[index]
- result.Uncles = uncleLists[index]
- result.Withdrawals = withdrawalLists[index]
- result.SetBodyDone()
- }
- return q.deliver(id, q.blockTaskPool, q.blockTaskQueue, q.blockPendPool,
- bodyReqTimer, bodyInMeter, bodyDropMeter, len(txLists), validate, reconstruct)
-}
-
-// DeliverReceipts injects a receipt retrieval response into the results queue.
-// The method returns the number of transaction receipts accepted from the delivery
-// and also wakes any threads waiting for data delivery.
-func (q *queue) DeliverReceipts(id string, receiptList [][]*types.Receipt, receiptListHashes []common.Hash) (int, error) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- validate := func(index int, header *types.Header) error {
- if receiptListHashes[index] != header.ReceiptHash {
- return errInvalidReceipt
- }
- return nil
- }
- reconstruct := func(index int, result *fetchResult) {
- result.Receipts = receiptList[index]
- result.SetReceiptsDone()
- }
- return q.deliver(id, q.receiptTaskPool, q.receiptTaskQueue, q.receiptPendPool,
- receiptReqTimer, receiptInMeter, receiptDropMeter, len(receiptList), validate, reconstruct)
-}
-
-// deliver injects a data retrieval response into the results queue.
-//
-// Note, this method expects the queue lock to be already held for writing. The
-// reason this lock is not obtained in here is because the parameters already need
-// to access the queue, so they already need a lock anyway.
-func (q *queue) deliver(id string, taskPool map[common.Hash]*types.Header,
- taskQueue *prque.Prque[int64, *types.Header], pendPool map[string]*fetchRequest,
- reqTimer metrics.Timer, resInMeter metrics.Meter, resDropMeter metrics.Meter,
- results int, validate func(index int, header *types.Header) error,
- reconstruct func(index int, result *fetchResult)) (int, error) {
- // Short circuit if the data was never requested
- request := pendPool[id]
- if request == nil {
- resDropMeter.Mark(int64(results))
- return 0, errNoFetchesPending
- }
- delete(pendPool, id)
-
- reqTimer.UpdateSince(request.Time)
- resInMeter.Mark(int64(results))
-
- // If no data items were retrieved, mark them as unavailable for the origin peer
- if results == 0 {
- for _, header := range request.Headers {
- request.Peer.MarkLacking(header.Hash())
- }
- }
- // Assemble each of the results with their headers and retrieved data parts
- var (
- accepted int
- failure error
- i int
- hashes []common.Hash
- )
- for _, header := range request.Headers {
- // Short circuit assembly if no more fetch results are found
- if i >= results {
- break
- }
- // Validate the fields
- if err := validate(i, header); err != nil {
- failure = err
- break
- }
- hashes = append(hashes, header.Hash())
- i++
- }
-
- for _, header := range request.Headers[:i] {
- if res, stale, err := q.resultCache.GetDeliverySlot(header.Number.Uint64()); err == nil && !stale {
- reconstruct(accepted, res)
- } else {
- // else: between here and above, some other peer filled this result,
- // or it was indeed a no-op. This should not happen, but if it does it's
- // not something to panic about
- log.Error("Delivery stale", "stale", stale, "number", header.Number.Uint64(), "err", err)
- failure = errStaleDelivery
- }
- // Clean up a successful fetch
- delete(taskPool, hashes[accepted])
- accepted++
- }
- resDropMeter.Mark(int64(results - accepted))
-
- // Return all failed or missing fetches to the queue
- for _, header := range request.Headers[accepted:] {
- taskQueue.Push(header, -int64(header.Number.Uint64()))
- }
- // Wake up Results
- if accepted > 0 {
- q.active.Signal()
- }
- if failure == nil {
- return accepted, nil
- }
- // If none of the data was good, it's a stale delivery
- if accepted > 0 {
- return accepted, fmt.Errorf("partial failure: %v", failure)
- }
- return accepted, fmt.Errorf("%w: %v", failure, errStaleDelivery)
-}
-
-// Prepare configures the result cache to allow accepting and caching inbound
-// fetch results.
-func (q *queue) Prepare(offset uint64, mode SyncMode) {
- q.lock.Lock()
- defer q.lock.Unlock()
-
- // Prepare the queue for sync results
- q.resultCache.Prepare(offset)
- q.mode = mode
-}
diff --git a/eth/downloader/queue_test.go b/eth/downloader/queue_test.go
deleted file mode 100644
index 50b9031a27..0000000000
--- a/eth/downloader/queue_test.go
+++ /dev/null
@@ -1,474 +0,0 @@
-// Copyright 2015 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 downloader
-
-import (
- "fmt"
- "math/big"
- "math/rand"
- "os"
- "sync"
- "testing"
- "time"
-
- "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/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/trie"
- "golang.org/x/exp/slog"
-)
-
-// makeChain creates a chain of n blocks starting at and including parent.
-// the returned hash chain is ordered head->parent. In addition, every 3rd block
-// contains a transaction and every 5th an uncle to allow testing correct block
-// reassembly.
-func makeChain(n int, seed byte, parent *types.Block, empty bool) ([]*types.Block, []types.Receipts) {
- blocks, receipts := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), testDB, n, func(i int, block *core.BlockGen) {
- block.SetCoinbase(common.Address{seed})
- // Add one tx to every secondblock
- if !empty && i%2 == 0 {
- signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
- tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
- if err != nil {
- panic(err)
- }
- block.AddTx(tx)
- }
- })
- return blocks, receipts
-}
-
-type chainData struct {
- blocks []*types.Block
- offset int
-}
-
-var chain *chainData
-var emptyChain *chainData
-
-func init() {
- // Create a chain of blocks to import
- targetBlocks := 128
- blocks, _ := makeChain(targetBlocks, 0, testGenesis, false)
- chain = &chainData{blocks, 0}
-
- blocks, _ = makeChain(targetBlocks, 0, testGenesis, true)
- emptyChain = &chainData{blocks, 0}
-}
-
-func (chain *chainData) headers() []*types.Header {
- hdrs := make([]*types.Header, len(chain.blocks))
- for i, b := range chain.blocks {
- hdrs[i] = b.Header()
- }
- return hdrs
-}
-
-func (chain *chainData) Len() int {
- return len(chain.blocks)
-}
-
-func dummyPeer(id string) *peerConnection {
- p := &peerConnection{
- id: id,
- lacking: make(map[common.Hash]struct{}),
- }
- return p
-}
-
-func TestBasics(t *testing.T) {
- numOfBlocks := len(emptyChain.blocks)
- numOfReceipts := len(emptyChain.blocks) / 2
-
- q := newQueue(10, 10)
- if !q.Idle() {
- t.Errorf("new queue should be idle")
- }
- q.Prepare(1, SnapSync)
- if res := q.Results(false); len(res) != 0 {
- t.Fatal("new queue should have 0 results")
- }
-
- // Schedule a batch of headers
- headers := chain.headers()
- hashes := make([]common.Hash, len(headers))
- for i, header := range headers {
- hashes[i] = header.Hash()
- }
- q.Schedule(headers, hashes, 1)
- if q.Idle() {
- t.Errorf("queue should not be idle")
- }
- if got, exp := q.PendingBodies(), chain.Len(); got != exp {
- t.Errorf("wrong pending block count, got %d, exp %d", got, exp)
- }
- // Only non-empty receipts get added to task-queue
- if got, exp := q.PendingReceipts(), 64; got != exp {
- t.Errorf("wrong pending receipt count, got %d, exp %d", got, exp)
- }
- // Items are now queued for downloading, next step is that we tell the
- // queue that a certain peer will deliver them for us
- {
- peer := dummyPeer("peer-1")
- fetchReq, _, throttle := q.ReserveBodies(peer, 50)
- if !throttle {
- // queue size is only 10, so throttling should occur
- t.Fatal("should throttle")
- }
- // But we should still get the first things to fetch
- if got, exp := len(fetchReq.Headers), 5; got != exp {
- t.Fatalf("expected %d requests, got %d", exp, got)
- }
- if got, exp := fetchReq.Headers[0].Number.Uint64(), uint64(1); got != exp {
- t.Fatalf("expected header %d, got %d", exp, got)
- }
- }
- if exp, got := q.blockTaskQueue.Size(), numOfBlocks-10; exp != got {
- t.Errorf("expected block task queue to be %d, got %d", exp, got)
- }
- if exp, got := q.receiptTaskQueue.Size(), numOfReceipts; exp != got {
- t.Errorf("expected receipt task queue to be %d, got %d", exp, got)
- }
- {
- peer := dummyPeer("peer-2")
- fetchReq, _, throttle := q.ReserveBodies(peer, 50)
-
- // The second peer should hit throttling
- if !throttle {
- t.Fatalf("should throttle")
- }
- // And not get any fetches at all, since it was throttled to begin with
- if fetchReq != nil {
- t.Fatalf("should have no fetches, got %d", len(fetchReq.Headers))
- }
- }
- if exp, got := q.blockTaskQueue.Size(), numOfBlocks-10; exp != got {
- t.Errorf("expected block task queue to be %d, got %d", exp, got)
- }
- if exp, got := q.receiptTaskQueue.Size(), numOfReceipts; exp != got {
- t.Errorf("expected receipt task queue to be %d, got %d", exp, got)
- }
- {
- // The receipt delivering peer should not be affected
- // by the throttling of body deliveries
- peer := dummyPeer("peer-3")
- fetchReq, _, throttle := q.ReserveReceipts(peer, 50)
- if !throttle {
- // queue size is only 10, so throttling should occur
- t.Fatal("should throttle")
- }
- // But we should still get the first things to fetch
- if got, exp := len(fetchReq.Headers), 5; got != exp {
- t.Fatalf("expected %d requests, got %d", exp, got)
- }
- if got, exp := fetchReq.Headers[0].Number.Uint64(), uint64(1); got != exp {
- t.Fatalf("expected header %d, got %d", exp, got)
- }
- }
- if exp, got := q.blockTaskQueue.Size(), numOfBlocks-10; exp != got {
- t.Errorf("expected block task queue to be %d, got %d", exp, got)
- }
- if exp, got := q.receiptTaskQueue.Size(), numOfReceipts-5; exp != got {
- t.Errorf("expected receipt task queue to be %d, got %d", exp, got)
- }
- if got, exp := q.resultCache.countCompleted(), 0; got != exp {
- t.Errorf("wrong processable count, got %d, exp %d", got, exp)
- }
-}
-
-func TestEmptyBlocks(t *testing.T) {
- numOfBlocks := len(emptyChain.blocks)
-
- q := newQueue(10, 10)
-
- q.Prepare(1, SnapSync)
-
- // Schedule a batch of headers
- headers := emptyChain.headers()
- hashes := make([]common.Hash, len(headers))
- for i, header := range headers {
- hashes[i] = header.Hash()
- }
- q.Schedule(headers, hashes, 1)
- if q.Idle() {
- t.Errorf("queue should not be idle")
- }
- if got, exp := q.PendingBodies(), len(emptyChain.blocks); got != exp {
- t.Errorf("wrong pending block count, got %d, exp %d", got, exp)
- }
- if got, exp := q.PendingReceipts(), 0; got != exp {
- t.Errorf("wrong pending receipt count, got %d, exp %d", got, exp)
- }
- // They won't be processable, because the fetchresults haven't been
- // created yet
- if got, exp := q.resultCache.countCompleted(), 0; got != exp {
- t.Errorf("wrong processable count, got %d, exp %d", got, exp)
- }
-
- // Items are now queued for downloading, next step is that we tell the
- // queue that a certain peer will deliver them for us
- // That should trigger all of them to suddenly become 'done'
- {
- // Reserve blocks
- peer := dummyPeer("peer-1")
- fetchReq, _, _ := q.ReserveBodies(peer, 50)
-
- // there should be nothing to fetch, blocks are empty
- if fetchReq != nil {
- t.Fatal("there should be no body fetch tasks remaining")
- }
- }
- if q.blockTaskQueue.Size() != numOfBlocks-10 {
- t.Errorf("expected block task queue to be %d, got %d", numOfBlocks-10, q.blockTaskQueue.Size())
- }
- if q.receiptTaskQueue.Size() != 0 {
- t.Errorf("expected receipt task queue to be %d, got %d", 0, q.receiptTaskQueue.Size())
- }
- {
- peer := dummyPeer("peer-3")
- fetchReq, _, _ := q.ReserveReceipts(peer, 50)
-
- // there should be nothing to fetch, blocks are empty
- if fetchReq != nil {
- t.Fatal("there should be no receipt fetch tasks remaining")
- }
- }
- if q.blockTaskQueue.Size() != numOfBlocks-10 {
- t.Errorf("expected block task queue to be %d, got %d", numOfBlocks-10, q.blockTaskQueue.Size())
- }
- if q.receiptTaskQueue.Size() != 0 {
- t.Errorf("expected receipt task queue to be %d, got %d", 0, q.receiptTaskQueue.Size())
- }
- if got, exp := q.resultCache.countCompleted(), 10; got != exp {
- t.Errorf("wrong processable count, got %d, exp %d", got, exp)
- }
-}
-
-// XTestDelivery does some more extensive testing of events that happen,
-// blocks that become known and peers that make reservations and deliveries.
-// disabled since it's not really a unit-test, but can be executed to test
-// some more advanced scenarios
-func XTestDelivery(t *testing.T) {
- // the outside network, holding blocks
- blo, rec := makeChain(128, 0, testGenesis, false)
- world := newNetwork()
- world.receipts = rec
- world.chain = blo
- world.progress(10)
- if false {
- log.SetDefault(log.NewLogger(slog.NewTextHandler(os.Stdout, nil)))
- }
- q := newQueue(10, 10)
- var wg sync.WaitGroup
- q.Prepare(1, SnapSync)
- wg.Add(1)
- go func() {
- // deliver headers
- defer wg.Done()
- c := 1
- for {
- //fmt.Printf("getting headers from %d\n", c)
- headers := world.headers(c)
- hashes := make([]common.Hash, len(headers))
- for i, header := range headers {
- hashes[i] = header.Hash()
- }
- l := len(headers)
- //fmt.Printf("scheduling %d headers, first %d last %d\n",
- // l, headers[0].Number.Uint64(), headers[len(headers)-1].Number.Uint64())
- q.Schedule(headers, hashes, uint64(c))
- c += l
- }
- }()
- wg.Add(1)
- go func() {
- // collect results
- defer wg.Done()
- tot := 0
- for {
- res := q.Results(true)
- tot += len(res)
- fmt.Printf("got %d results, %d tot\n", len(res), tot)
- // Now we can forget about these
- world.forget(res[len(res)-1].Header.Number.Uint64())
- }
- }()
- wg.Add(1)
- go func() {
- defer wg.Done()
- // reserve body fetch
- i := 4
- for {
- peer := dummyPeer(fmt.Sprintf("peer-%d", i))
- f, _, _ := q.ReserveBodies(peer, rand.Intn(30))
- if f != nil {
- var (
- emptyList []*types.Header
- txset [][]*types.Transaction
- uncleset [][]*types.Header
- )
- numToSkip := rand.Intn(len(f.Headers))
- for _, hdr := range f.Headers[0 : len(f.Headers)-numToSkip] {
- txset = append(txset, world.getTransactions(hdr.Number.Uint64()))
- uncleset = append(uncleset, emptyList)
- }
- var (
- txsHashes = make([]common.Hash, len(txset))
- uncleHashes = make([]common.Hash, len(uncleset))
- )
- hasher := trie.NewStackTrie(nil)
- for i, txs := range txset {
- txsHashes[i] = types.DeriveSha(types.Transactions(txs), hasher)
- }
- for i, uncles := range uncleset {
- uncleHashes[i] = types.CalcUncleHash(uncles)
- }
- time.Sleep(100 * time.Millisecond)
- _, err := q.DeliverBodies(peer.id, txset, txsHashes, uncleset, uncleHashes, nil, nil)
- if err != nil {
- fmt.Printf("delivered %d bodies %v\n", len(txset), err)
- }
- } else {
- i++
- time.Sleep(200 * time.Millisecond)
- }
- }
- }()
- go func() {
- defer wg.Done()
- // reserve receiptfetch
- peer := dummyPeer("peer-3")
- for {
- f, _, _ := q.ReserveReceipts(peer, rand.Intn(50))
- if f != nil {
- var rcs [][]*types.Receipt
- for _, hdr := range f.Headers {
- rcs = append(rcs, world.getReceipts(hdr.Number.Uint64()))
- }
- hasher := trie.NewStackTrie(nil)
- hashes := make([]common.Hash, len(rcs))
- for i, receipt := range rcs {
- hashes[i] = types.DeriveSha(types.Receipts(receipt), hasher)
- }
- _, err := q.DeliverReceipts(peer.id, rcs, hashes)
- if err != nil {
- fmt.Printf("delivered %d receipts %v\n", len(rcs), err)
- }
- time.Sleep(100 * time.Millisecond)
- } else {
- time.Sleep(200 * time.Millisecond)
- }
- }
- }()
- wg.Add(1)
- go func() {
- defer wg.Done()
- for i := 0; i < 50; i++ {
- time.Sleep(300 * time.Millisecond)
- //world.tick()
- //fmt.Printf("trying to progress\n")
- world.progress(rand.Intn(100))
- }
- for i := 0; i < 50; i++ {
- time.Sleep(2990 * time.Millisecond)
- }
- }()
- wg.Add(1)
- go func() {
- defer wg.Done()
- for {
- time.Sleep(990 * time.Millisecond)
- fmt.Printf("world block tip is %d\n",
- world.chain[len(world.chain)-1].Header().Number.Uint64())
- fmt.Println(q.Stats())
- }
- }()
- wg.Wait()
-}
-
-func newNetwork() *network {
- var l sync.RWMutex
- return &network{
- cond: sync.NewCond(&l),
- offset: 1, // block 1 is at blocks[0]
- }
-}
-
-// represents the network
-type network struct {
- offset int
- chain []*types.Block
- receipts []types.Receipts
- lock sync.RWMutex
- cond *sync.Cond
-}
-
-func (n *network) getTransactions(blocknum uint64) types.Transactions {
- index := blocknum - uint64(n.offset)
- return n.chain[index].Transactions()
-}
-func (n *network) getReceipts(blocknum uint64) types.Receipts {
- index := blocknum - uint64(n.offset)
- if got := n.chain[index].Header().Number.Uint64(); got != blocknum {
- fmt.Printf("Err, got %d exp %d\n", got, blocknum)
- panic("sd")
- }
- return n.receipts[index]
-}
-
-func (n *network) forget(blocknum uint64) {
- index := blocknum - uint64(n.offset)
- n.chain = n.chain[index:]
- n.receipts = n.receipts[index:]
- n.offset = int(blocknum)
-}
-func (n *network) progress(numBlocks int) {
- n.lock.Lock()
- defer n.lock.Unlock()
- //fmt.Printf("progressing...\n")
- newBlocks, newR := makeChain(numBlocks, 0, n.chain[len(n.chain)-1], false)
- n.chain = append(n.chain, newBlocks...)
- n.receipts = append(n.receipts, newR...)
- n.cond.Broadcast()
-}
-
-func (n *network) headers(from int) []*types.Header {
- numHeaders := 128
- var hdrs []*types.Header
- index := from - n.offset
-
- for index >= len(n.chain) {
- // wait for progress
- n.cond.L.Lock()
- //fmt.Printf("header going into wait\n")
- n.cond.Wait()
- index = from - n.offset
- n.cond.L.Unlock()
- }
- n.lock.RLock()
- defer n.lock.RUnlock()
- for i, b := range n.chain[index:] {
- hdrs = append(hdrs, b.Header())
- if i >= numHeaders {
- break
- }
- }
- return hdrs
-}
diff --git a/eth/downloader/resultstore.go b/eth/downloader/resultstore.go
deleted file mode 100644
index e4323c04eb..0000000000
--- a/eth/downloader/resultstore.go
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright 2020 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 downloader
-
-import (
- "fmt"
- "sync"
- "sync/atomic"
-
- "github.com/ethereum/go-ethereum/core/types"
-)
-
-// resultStore implements a structure for maintaining fetchResults, tracking their
-// download-progress and delivering (finished) results.
-type resultStore struct {
- items []*fetchResult // Downloaded but not yet delivered fetch results
- resultOffset uint64 // Offset of the first cached fetch result in the block chain
-
- // Internal index of first non-completed entry, updated atomically when needed.
- // If all items are complete, this will equal length(items), so
- // *important* : is not safe to use for indexing without checking against length
- indexIncomplete atomic.Int32
-
- // throttleThreshold is the limit up to which we _want_ to fill the
- // results. If blocks are large, we want to limit the results to less
- // than the number of available slots, and maybe only fill 1024 out of
- // 8192 possible places. The queue will, at certain times, recalibrate
- // this index.
- throttleThreshold uint64
-
- lock sync.RWMutex
-}
-
-func newResultStore(size int) *resultStore {
- return &resultStore{
- resultOffset: 0,
- items: make([]*fetchResult, size),
- throttleThreshold: uint64(size),
- }
-}
-
-// SetThrottleThreshold updates the throttling threshold based on the requested
-// limit and the total queue capacity. It returns the (possibly capped) threshold
-func (r *resultStore) SetThrottleThreshold(threshold uint64) uint64 {
- r.lock.Lock()
- defer r.lock.Unlock()
-
- limit := uint64(len(r.items))
- if threshold >= limit {
- threshold = limit
- }
- r.throttleThreshold = threshold
- return r.throttleThreshold
-}
-
-// AddFetch adds a header for body/receipt fetching. This is used when the queue
-// wants to reserve headers for fetching.
-//
-// It returns the following:
-//
-// stale - if true, this item is already passed, and should not be requested again
-// throttled - if true, the store is at capacity, this particular header is not prio now
-// item - the result to store data into
-// err - any error that occurred
-func (r *resultStore) AddFetch(header *types.Header, fastSync bool) (stale, throttled bool, item *fetchResult, err error) {
- r.lock.Lock()
- defer r.lock.Unlock()
-
- var index int
- item, index, stale, throttled, err = r.getFetchResult(header.Number.Uint64())
- if err != nil || stale || throttled {
- return stale, throttled, item, err
- }
- if item == nil {
- item = newFetchResult(header, fastSync)
- r.items[index] = item
- }
- return stale, throttled, item, err
-}
-
-// GetDeliverySlot returns the fetchResult for the given header. If the 'stale' flag
-// is true, that means the header has already been delivered 'upstream'. This method
-// does not bubble up the 'throttle' flag, since it's moot at the point in time when
-// the item is downloaded and ready for delivery
-func (r *resultStore) GetDeliverySlot(headerNumber uint64) (*fetchResult, bool, error) {
- r.lock.RLock()
- defer r.lock.RUnlock()
-
- res, _, stale, _, err := r.getFetchResult(headerNumber)
- return res, stale, err
-}
-
-// getFetchResult returns the fetchResult corresponding to the given item, and
-// the index where the result is stored.
-func (r *resultStore) getFetchResult(headerNumber uint64) (item *fetchResult, index int, stale, throttle bool, err error) {
- index = int(int64(headerNumber) - int64(r.resultOffset))
- throttle = index >= int(r.throttleThreshold)
- stale = index < 0
-
- if index >= len(r.items) {
- err = fmt.Errorf("%w: index allocation went beyond available resultStore space "+
- "(index [%d] = header [%d] - resultOffset [%d], len(resultStore) = %d", errInvalidChain,
- index, headerNumber, r.resultOffset, len(r.items))
- return nil, index, stale, throttle, err
- }
- if stale {
- return nil, index, stale, throttle, nil
- }
- item = r.items[index]
- return item, index, stale, throttle, nil
-}
-
-// HasCompletedItems returns true if there are processable items available
-// this method is cheaper than countCompleted
-func (r *resultStore) HasCompletedItems() bool {
- r.lock.RLock()
- defer r.lock.RUnlock()
-
- if len(r.items) == 0 {
- return false
- }
- if item := r.items[0]; item != nil && item.AllDone() {
- return true
- }
- return false
-}
-
-// countCompleted returns the number of items ready for delivery, stopping at
-// the first non-complete item.
-//
-// The method assumes (at least) rlock is held.
-func (r *resultStore) countCompleted() int {
- // We iterate from the already known complete point, and see
- // if any more has completed since last count
- index := r.indexIncomplete.Load()
- for ; ; index++ {
- if index >= int32(len(r.items)) {
- break
- }
- result := r.items[index]
- if result == nil || !result.AllDone() {
- break
- }
- }
- r.indexIncomplete.Store(index)
- return int(index)
-}
-
-// GetCompleted returns the next batch of completed fetchResults
-func (r *resultStore) GetCompleted(limit int) []*fetchResult {
- r.lock.Lock()
- defer r.lock.Unlock()
-
- completed := r.countCompleted()
- if limit > completed {
- limit = completed
- }
- results := make([]*fetchResult, limit)
- copy(results, r.items[:limit])
-
- // Delete the results from the cache and clear the tail.
- copy(r.items, r.items[limit:])
- for i := len(r.items) - limit; i < len(r.items); i++ {
- r.items[i] = nil
- }
- // Advance the expected block number of the first cache entry
- r.resultOffset += uint64(limit)
- r.indexIncomplete.Add(int32(-limit))
-
- return results
-}
-
-// Prepare initialises the offset with the given block number
-func (r *resultStore) Prepare(offset uint64) {
- r.lock.Lock()
- defer r.lock.Unlock()
-
- if r.resultOffset < offset {
- r.resultOffset = offset
- }
-}
diff --git a/eth/downloader/skeleton.go b/eth/downloader/skeleton.go
deleted file mode 100644
index f40ca24d99..0000000000
--- a/eth/downloader/skeleton.go
+++ /dev/null
@@ -1,1232 +0,0 @@
-// 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 downloader
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "math/rand"
- "sort"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// scratchHeaders is the number of headers to store in a scratch space to allow
-// concurrent downloads. A header is about 0.5KB in size, so there is no worry
-// about using too much memory. The only catch is that we can only validate gaps
-// after they're linked to the head, so the bigger the scratch space, the larger
-// potential for invalid headers.
-//
-// The current scratch space of 131072 headers is expected to use 64MB RAM.
-const scratchHeaders = 131072
-
-// requestHeaders is the number of header to request from a remote peer in a single
-// network packet. Although the skeleton downloader takes into consideration peer
-// capacities when picking idlers, the packet size was decided to remain constant
-// since headers are relatively small and it's easier to work with fixed batches
-// vs. dynamic interval fillings.
-const requestHeaders = 512
-
-// errSyncLinked is an internal helper error to signal that the current sync
-// cycle linked up to the genesis block, this the skeleton syncer should ping
-// the backfiller to resume. Since we already have that logic on sync start,
-// piggy-back on that instead of 2 entrypoints.
-var errSyncLinked = errors.New("sync linked")
-
-// errSyncMerged is an internal helper error to signal that the current sync
-// cycle merged with a previously aborted subchain, thus the skeleton syncer
-// should abort and restart with the new state.
-var errSyncMerged = errors.New("sync merged")
-
-// errSyncReorged is an internal helper error to signal that the head chain of
-// the current sync cycle was (partially) reorged, thus the skeleton syncer
-// should abort and restart with the new state.
-var errSyncReorged = errors.New("sync reorged")
-
-// errTerminated is returned if the sync mechanism was terminated for this run of
-// the process. This is usually the case when Geth is shutting down and some events
-// might still be propagating.
-var errTerminated = errors.New("terminated")
-
-// errChainReorged is an internal helper error to signal that the header chain
-// of the current sync cycle was (partially) reorged.
-var errChainReorged = errors.New("chain reorged")
-
-// errChainGapped is an internal helper error to signal that the header chain
-// of the current sync cycle is gaped with the one advertised by consensus client.
-var errChainGapped = errors.New("chain gapped")
-
-// errChainForked is an internal helper error to signal that the header chain
-// of the current sync cycle is forked with the one advertised by consensus client.
-var errChainForked = errors.New("chain forked")
-
-func init() {
- // Tuning parameters is nice, but the scratch space must be assignable in
- // full to peers. It's a useless cornercase to support a dangling half-group.
- if scratchHeaders%requestHeaders != 0 {
- panic("Please make scratchHeaders divisible by requestHeaders")
- }
-}
-
-// subchain is a contiguous header chain segment that is backed by the database,
-// but may not be linked to the live chain. The skeleton downloader may produce
-// a new one of these every time it is restarted until the subchain grows large
-// enough to connect with a previous subchain.
-//
-// The subchains use the exact same database namespace and are not disjoint from
-// each other. As such, extending one to overlap the other entails reducing the
-// second one first. This combined buffer model is used to avoid having to move
-// data on disk when two subchains are joined together.
-type subchain struct {
- Head uint64 // Block number of the newest header in the subchain
- Tail uint64 // Block number of the oldest header in the subchain
- Next common.Hash // Block hash of the next oldest header in the subchain
-}
-
-// skeletonProgress is a database entry to allow suspending and resuming a chain
-// sync. As the skeleton header chain is downloaded backwards, restarts can and
-// will produce temporarily disjoint subchains. There is no way to restart a
-// suspended skeleton sync without prior knowledge of all prior suspension points.
-type skeletonProgress struct {
- Subchains []*subchain // Disjoint subchains downloaded until now
- Finalized *uint64 // Last known finalized block number
-}
-
-// headUpdate is a notification that the beacon sync should switch to a new target.
-// The update might request whether to forcefully change the target, or only try to
-// extend it and fail if it's not possible.
-type headUpdate struct {
- header *types.Header // Header to update the sync target to
- final *types.Header // Finalized header to use as thresholds
- force bool // Whether to force the update or only extend if possible
- errc chan error // Channel to signal acceptance of the new head
-}
-
-// headerRequest tracks a pending header request to ensure responses are to
-// actual requests and to validate any security constraints.
-//
-// Concurrency note: header requests and responses are handled concurrently from
-// the main runloop to allow Keccak256 hash verifications on the peer's thread and
-// to drop on invalid response. The request struct must contain all the data to
-// construct the response without accessing runloop internals (i.e. subchains).
-// That is only included to allow the runloop to match a response to the task being
-// synced without having yet another set of maps.
-type headerRequest struct {
- peer string // Peer to which this request is assigned
- id uint64 // Request ID of this request
-
- deliver chan *headerResponse // Channel to deliver successful response on
- revert chan *headerRequest // Channel to deliver request failure on
- cancel chan struct{} // Channel to track sync cancellation
- stale chan struct{} // Channel to signal the request was dropped
-
- head uint64 // Head number of the requested batch of headers
-}
-
-// headerResponse is an already verified remote response to a header request.
-type headerResponse struct {
- peer *peerConnection // Peer from which this response originates
- reqid uint64 // Request ID that this response fulfils
- headers []*types.Header // Chain of headers
-}
-
-// backfiller is a callback interface through which the skeleton sync can tell
-// the downloader that it should suspend or resume backfilling on specific head
-// events (e.g. suspend on forks or gaps, resume on successful linkups).
-type backfiller interface {
- // suspend requests the backfiller to abort any running full or snap sync
- // based on the skeleton chain as it might be invalid. The backfiller should
- // gracefully handle multiple consecutive suspends without a resume, even
- // on initial startup.
- //
- // The method should return the last block header that has been successfully
- // backfilled, or nil if the backfiller was not resumed.
- suspend() *types.Header
-
- // resume requests the backfiller to start running fill or snap sync based on
- // the skeleton chain as it has successfully been linked. Appending new heads
- // to the end of the chain will not result in suspend/resume cycles.
- // leaking too much sync logic out to the filler.
- resume()
-}
-
-// skeleton represents a header chain synchronized after the merge where blocks
-// aren't validated any more via PoW in a forward fashion, rather are dictated
-// and extended at the head via the beacon chain and backfilled on the original
-// Ethereum block sync protocol.
-//
-// Since the skeleton is grown backwards from head to genesis, it is handled as
-// a separate entity, not mixed in with the logical sequential transition of the
-// blocks. Once the skeleton is connected to an existing, validated chain, the
-// headers will be moved into the main downloader for filling and execution.
-//
-// Opposed to the original Ethereum block synchronization which is trustless (and
-// uses a master peer to minimize the attack surface), post-merge block sync starts
-// from a trusted head. As such, there is no need for a master peer any more and
-// headers can be requested fully concurrently (though some batches might be
-// discarded if they don't link up correctly).
-//
-// Although a skeleton is part of a sync cycle, it is not recreated, rather stays
-// alive throughout the lifetime of the downloader. This allows it to be extended
-// concurrently with the sync cycle, since extensions arrive from an API surface,
-// not from within (vs. legacy Ethereum sync).
-//
-// Since the skeleton tracks the entire header chain until it is consumed by the
-// forward block filling, it needs 0.5KB/block storage. At current mainnet sizes
-// this is only possible with a disk backend. Since the skeleton is separate from
-// the node's header chain, storing the headers ephemerally until sync finishes
-// is wasted disk IO, but it's a price we're going to pay to keep things simple
-// for now.
-type skeleton struct {
- db ethdb.Database // Database backing the skeleton
- filler backfiller // Chain syncer suspended/resumed by head events
-
- peers *peerSet // Set of peers we can sync from
- idles map[string]*peerConnection // Set of idle peers in the current sync cycle
- drop peerDropFn // Drops a peer for misbehaving
-
- progress *skeletonProgress // Sync progress tracker for resumption and metrics
- started time.Time // Timestamp when the skeleton syncer was created
- logged time.Time // Timestamp when progress was last logged to the user
- pulled uint64 // Number of headers downloaded in this run
-
- scratchSpace []*types.Header // Scratch space to accumulate headers in (first = recent)
- scratchOwners []string // Peer IDs owning chunks of the scratch space (pend or delivered)
- scratchHead uint64 // Block number of the first item in the scratch space
-
- requests map[uint64]*headerRequest // Header requests currently running
-
- headEvents chan *headUpdate // Notification channel for new heads
- terminate chan chan error // Termination channel to abort sync
- terminated chan struct{} // Channel to signal that the syncer is dead
-
- // Callback hooks used during testing
- syncStarting func() // callback triggered after a sync cycle is inited but before started
-}
-
-// newSkeleton creates a new sync skeleton that tracks a potentially dangling
-// header chain until it's linked into an existing set of blocks.
-func newSkeleton(db ethdb.Database, peers *peerSet, drop peerDropFn, filler backfiller) *skeleton {
- sk := &skeleton{
- db: db,
- filler: filler,
- peers: peers,
- drop: drop,
- requests: make(map[uint64]*headerRequest),
- headEvents: make(chan *headUpdate),
- terminate: make(chan chan error),
- terminated: make(chan struct{}),
- }
- go sk.startup()
- return sk
-}
-
-// startup is an initial background loop which waits for an event to start or
-// tear the syncer down. This is required to make the skeleton sync loop once
-// per process but at the same time not start before the beacon chain announces
-// a new (existing) head.
-func (s *skeleton) startup() {
- // Close a notification channel so anyone sending us events will know if the
- // sync loop was torn down for good.
- defer close(s.terminated)
-
- // Wait for startup or teardown. This wait might loop a few times if a beacon
- // client requests sync head extensions, but not forced reorgs (i.e. they are
- // giving us new payloads without setting a starting head initially).
- for {
- select {
- case errc := <-s.terminate:
- // No head was announced but Geth is shutting down
- errc <- nil
- return
-
- case event := <-s.headEvents:
- // New head announced, start syncing to it, looping every time a current
- // cycle is terminated due to a chain event (head reorg, old chain merge).
- if !event.force {
- event.errc <- errors.New("forced head needed for startup")
- continue
- }
- event.errc <- nil // forced head accepted for startup
- head := event.header
- s.started = time.Now()
-
- for {
- // If the sync cycle terminated or was terminated, propagate up when
- // higher layers request termination. There's no fancy explicit error
- // signalling as the sync loop should never terminate (TM).
- newhead, err := s.sync(head)
- switch {
- case err == errSyncLinked:
- // Sync cycle linked up to the genesis block, or the existent chain
- // segment. Tear down the loop and restart it so, it can properly
- // notify the backfiller. Don't account a new head.
- head = nil
-
- case err == errSyncMerged:
- // Subchains were merged, we just need to reinit the internal
- // start to continue on the tail of the merged chain. Don't
- // announce a new head,
- head = nil
-
- case err == errSyncReorged:
- // The subchain being synced got modified at the head in a
- // way that requires resyncing it. Restart sync with the new
- // head to force a cleanup.
- head = newhead
-
- case err == errTerminated:
- // Sync was requested to be terminated from within, stop and
- // return (no need to pass a message, was already done internally)
- return
-
- default:
- // Sync either successfully terminated or failed with an unhandled
- // error. Abort and wait until Geth requests a termination.
- errc := <-s.terminate
- errc <- err
- return
- }
- }
- }
- }
-}
-
-// Terminate tears down the syncer indefinitely.
-func (s *skeleton) Terminate() error {
- // Request termination and fetch any errors
- errc := make(chan error)
- s.terminate <- errc
- err := <-errc
-
- // Wait for full shutdown (not necessary, but cleaner)
- <-s.terminated
- return err
-}
-
-// Sync starts or resumes a previous sync cycle to download and maintain a reverse
-// header chain starting at the head and leading towards genesis to an available
-// ancestor.
-//
-// This method does not block, rather it just waits until the syncer receives the
-// fed header. What the syncer does with it is the syncer's problem.
-func (s *skeleton) Sync(head *types.Header, final *types.Header, force bool) error {
- log.Trace("New skeleton head announced", "number", head.Number, "hash", head.Hash(), "force", force)
- errc := make(chan error)
-
- select {
- case s.headEvents <- &headUpdate{header: head, final: final, force: force, errc: errc}:
- return <-errc
- case <-s.terminated:
- return errTerminated
- }
-}
-
-// sync is the internal version of Sync that executes a single sync cycle, either
-// until some termination condition is reached, or until the current cycle merges
-// with a previously aborted run.
-func (s *skeleton) sync(head *types.Header) (*types.Header, error) {
- // If we're continuing a previous merge interrupt, just access the existing
- // old state without initing from disk.
- if head == nil {
- head = rawdb.ReadSkeletonHeader(s.db, s.progress.Subchains[0].Head)
- } else {
- // Otherwise, initialize the sync, trimming and previous leftovers until
- // we're consistent with the newly requested chain head
- s.initSync(head)
- }
- // Create the scratch space to fill with concurrently downloaded headers
- s.scratchSpace = make([]*types.Header, scratchHeaders)
- defer func() { s.scratchSpace = nil }() // don't hold on to references after sync
-
- s.scratchOwners = make([]string, scratchHeaders/requestHeaders)
- defer func() { s.scratchOwners = nil }() // don't hold on to references after sync
-
- s.scratchHead = s.progress.Subchains[0].Tail - 1 // tail must not be 0!
-
- // If the sync is already done, resume the backfiller. When the loop stops,
- // terminate the backfiller too.
- linked := len(s.progress.Subchains) == 1 &&
- rawdb.HasHeader(s.db, s.progress.Subchains[0].Next, s.scratchHead) &&
- rawdb.HasBody(s.db, s.progress.Subchains[0].Next, s.scratchHead) &&
- rawdb.HasReceipts(s.db, s.progress.Subchains[0].Next, s.scratchHead)
- if linked {
- s.filler.resume()
- }
- defer func() {
- // The filler needs to be suspended, but since it can block for a while
- // when there are many blocks queued up for full-sync importing, run it
- // on a separate goroutine and consume head messages that need instant
- // replies.
- done := make(chan struct{})
- go func() {
- defer close(done)
- if filled := s.filler.suspend(); filled != nil {
- // If something was filled, try to delete stale sync helpers. If
- // unsuccessful, warn the user, but not much else we can do (it's
- // a programming error, just let users report an issue and don't
- // choke in the meantime).
- if err := s.cleanStales(filled); err != nil {
- log.Error("Failed to clean stale beacon headers", "err", err)
- }
- }
- }()
- // Wait for the suspend to finish, consuming head events in the meantime
- // and dropping them on the floor.
- for {
- select {
- case <-done:
- return
- case event := <-s.headEvents:
- event.errc <- errors.New("beacon syncer reorging")
- }
- }
- }()
- // Create a set of unique channels for this sync cycle. We need these to be
- // ephemeral so a data race doesn't accidentally deliver something stale on
- // a persistent channel across syncs (yup, this happened)
- var (
- requestFails = make(chan *headerRequest)
- responses = make(chan *headerResponse)
- )
- cancel := make(chan struct{})
- defer close(cancel)
-
- log.Debug("Starting reverse header sync cycle", "head", head.Number, "hash", head.Hash(), "cont", s.scratchHead)
-
- // Whether sync completed or not, disregard any future packets
- defer func() {
- log.Debug("Terminating reverse header sync cycle", "head", head.Number, "hash", head.Hash(), "cont", s.scratchHead)
- s.requests = make(map[uint64]*headerRequest)
- }()
-
- // Start tracking idle peers for task assignments
- peering := make(chan *peeringEvent, 64) // arbitrary buffer, just some burst protection
-
- peeringSub := s.peers.SubscribeEvents(peering)
- defer peeringSub.Unsubscribe()
-
- s.idles = make(map[string]*peerConnection)
- for _, peer := range s.peers.AllPeers() {
- s.idles[peer.id] = peer
- }
- // Notify any tester listening for startup events
- if s.syncStarting != nil {
- s.syncStarting()
- }
- for {
- // Something happened, try to assign new tasks to any idle peers
- if !linked {
- s.assignTasks(responses, requestFails, cancel)
- }
- // Wait for something to happen
- select {
- case event := <-peering:
- // A peer joined or left, the tasks queue and allocations need to be
- // checked for potential assignment or reassignment
- peerid := event.peer.id
- if event.join {
- log.Debug("Joining skeleton peer", "id", peerid)
- s.idles[peerid] = event.peer
- } else {
- log.Debug("Leaving skeleton peer", "id", peerid)
- s.revertRequests(peerid)
- delete(s.idles, peerid)
- }
-
- case errc := <-s.terminate:
- errc <- nil
- return nil, errTerminated
-
- case event := <-s.headEvents:
- // New head was announced, try to integrate it. If successful, nothing
- // needs to be done as the head simply extended the last range. For now
- // we don't seamlessly integrate reorgs to keep things simple. If the
- // network starts doing many mini reorgs, it might be worthwhile handling
- // a limited depth without an error.
- if err := s.processNewHead(event.header, event.final); err != nil {
- // If a reorg is needed, and we're forcing the new head, signal
- // the syncer to tear down and start over. Otherwise, drop the
- // non-force reorg.
- if event.force {
- event.errc <- nil // forced head reorg accepted
- log.Info("Restarting sync cycle", "reason", err)
- return event.header, errSyncReorged
- }
- event.errc <- err
- continue
- }
- event.errc <- nil // head extension accepted
-
- // New head was integrated into the skeleton chain. If the backfiller
- // is still running, it will pick it up. If it already terminated,
- // a new cycle needs to be spun up.
- if linked {
- s.filler.resume()
- }
-
- case req := <-requestFails:
- s.revertRequest(req)
-
- case res := <-responses:
- // Process the batch of headers. If though processing we managed to
- // link the current subchain to a previously downloaded one, abort the
- // sync and restart with the merged subchains.
- //
- // If we managed to link to the existing local chain or genesis block,
- // abort sync altogether.
- linked, merged := s.processResponse(res)
- if linked {
- log.Debug("Beacon sync linked to local chain")
- return nil, errSyncLinked
- }
- if merged {
- log.Debug("Beacon sync merged subchains")
- return nil, errSyncMerged
- }
- // We still have work to do, loop and repeat
- }
- }
-}
-
-// initSync attempts to get the skeleton sync into a consistent state wrt any
-// past state on disk and the newly requested head to sync to. If the new head
-// is nil, the method will return and continue from the previous head.
-func (s *skeleton) initSync(head *types.Header) {
- // Extract the head number, we'll need it all over
- number := head.Number.Uint64()
-
- // Retrieve the previously saved sync progress
- if status := rawdb.ReadSkeletonSyncStatus(s.db); len(status) > 0 {
- s.progress = new(skeletonProgress)
- if err := json.Unmarshal(status, s.progress); err != nil {
- log.Error("Failed to decode skeleton sync status", "err", err)
- } else {
- // Previous sync was available, print some continuation logs
- for _, subchain := range s.progress.Subchains {
- log.Debug("Restarting skeleton subchain", "head", subchain.Head, "tail", subchain.Tail)
- }
- // Create a new subchain for the head (unless the last can be extended),
- // trimming anything it would overwrite
- headchain := &subchain{
- Head: number,
- Tail: number,
- Next: head.ParentHash,
- }
- for len(s.progress.Subchains) > 0 {
- // If the last chain is above the new head, delete altogether
- lastchain := s.progress.Subchains[0]
- if lastchain.Tail >= headchain.Tail {
- log.Debug("Dropping skeleton subchain", "head", lastchain.Head, "tail", lastchain.Tail)
- s.progress.Subchains = s.progress.Subchains[1:]
- continue
- }
- // Otherwise truncate the last chain if needed and abort trimming
- if lastchain.Head >= headchain.Tail {
- log.Debug("Trimming skeleton subchain", "oldhead", lastchain.Head, "newhead", headchain.Tail-1, "tail", lastchain.Tail)
- lastchain.Head = headchain.Tail - 1
- }
- break
- }
- // If the last subchain can be extended, we're lucky. Otherwise, create
- // a new subchain sync task.
- var extended bool
- if n := len(s.progress.Subchains); n > 0 {
- lastchain := s.progress.Subchains[0]
- if lastchain.Head == headchain.Tail-1 {
- lasthead := rawdb.ReadSkeletonHeader(s.db, lastchain.Head)
- if lasthead.Hash() == head.ParentHash {
- log.Debug("Extended skeleton subchain with new head", "head", headchain.Tail, "tail", lastchain.Tail)
- lastchain.Head = headchain.Tail
- extended = true
- }
- }
- }
- if !extended {
- log.Debug("Created new skeleton subchain", "head", number, "tail", number)
- s.progress.Subchains = append([]*subchain{headchain}, s.progress.Subchains...)
- }
- // Update the database with the new sync stats and insert the new
- // head header. We won't delete any trimmed skeleton headers since
- // those will be outside the index space of the many subchains and
- // the database space will be reclaimed eventually when processing
- // blocks above the current head (TODO(karalabe): don't forget).
- batch := s.db.NewBatch()
-
- rawdb.WriteSkeletonHeader(batch, head)
- s.saveSyncStatus(batch)
-
- if err := batch.Write(); err != nil {
- log.Crit("Failed to write skeleton sync status", "err", err)
- }
- return
- }
- }
- // Either we've failed to decode the previous state, or there was none. Start
- // a fresh sync with a single subchain represented by the currently sent
- // chain head.
- s.progress = &skeletonProgress{
- Subchains: []*subchain{
- {
- Head: number,
- Tail: number,
- Next: head.ParentHash,
- },
- },
- }
- batch := s.db.NewBatch()
-
- rawdb.WriteSkeletonHeader(batch, head)
- s.saveSyncStatus(batch)
-
- if err := batch.Write(); err != nil {
- log.Crit("Failed to write initial skeleton sync status", "err", err)
- }
- log.Debug("Created initial skeleton subchain", "head", number, "tail", number)
-}
-
-// saveSyncStatus marshals the remaining sync tasks into leveldb.
-func (s *skeleton) saveSyncStatus(db ethdb.KeyValueWriter) {
- status, err := json.Marshal(s.progress)
- if err != nil {
- panic(err) // This can only fail during implementation
- }
- rawdb.WriteSkeletonSyncStatus(db, status)
-}
-
-// processNewHead does the internal shuffling for a new head marker and either
-// accepts and integrates it into the skeleton or requests a reorg. Upon reorg,
-// the syncer will tear itself down and restart with a fresh head. It is simpler
-// to reconstruct the sync state than to mutate it and hope for the best.
-func (s *skeleton) processNewHead(head *types.Header, final *types.Header) error {
- // If a new finalized block was announced, update the sync process independent
- // of what happens with the sync head below
- if final != nil {
- if number := final.Number.Uint64(); s.progress.Finalized == nil || *s.progress.Finalized != number {
- s.progress.Finalized = new(uint64)
- *s.progress.Finalized = final.Number.Uint64()
-
- s.saveSyncStatus(s.db)
- }
- }
- // If the header cannot be inserted without interruption, return an error for
- // the outer loop to tear down the skeleton sync and restart it
- number := head.Number.Uint64()
-
- lastchain := s.progress.Subchains[0]
- if lastchain.Tail >= number {
- // If the chain is down to a single beacon header, and it is re-announced
- // once more, ignore it instead of tearing down sync for a noop.
- if lastchain.Head == lastchain.Tail {
- if current := rawdb.ReadSkeletonHeader(s.db, number); current.Hash() == head.Hash() {
- return nil
- }
- }
- // Not a noop / double head announce, abort with a reorg
- return fmt.Errorf("%w, tail: %d, head: %d, newHead: %d", errChainReorged, lastchain.Tail, lastchain.Head, number)
- }
- if lastchain.Head+1 < number {
- return fmt.Errorf("%w, head: %d, newHead: %d", errChainGapped, lastchain.Head, number)
- }
- if parent := rawdb.ReadSkeletonHeader(s.db, number-1); parent.Hash() != head.ParentHash {
- return fmt.Errorf("%w, ancestor: %d, hash: %s, want: %s", errChainForked, number-1, parent.Hash(), head.ParentHash)
- }
- // New header seems to be in the last subchain range. Unwind any extra headers
- // from the chain tip and insert the new head. We won't delete any trimmed
- // skeleton headers since those will be outside the index space of the many
- // subchains and the database space will be reclaimed eventually when processing
- // blocks above the current head (TODO(karalabe): don't forget).
- batch := s.db.NewBatch()
-
- rawdb.WriteSkeletonHeader(batch, head)
- lastchain.Head = number
- s.saveSyncStatus(batch)
-
- if err := batch.Write(); err != nil {
- log.Crit("Failed to write skeleton sync status", "err", err)
- }
- return nil
-}
-
-// assignTasks attempts to match idle peers to pending header retrievals.
-func (s *skeleton) assignTasks(success chan *headerResponse, fail chan *headerRequest, cancel chan struct{}) {
- // Sort the peers by download capacity to use faster ones if many available
- idlers := &peerCapacitySort{
- peers: make([]*peerConnection, 0, len(s.idles)),
- caps: make([]int, 0, len(s.idles)),
- }
- targetTTL := s.peers.rates.TargetTimeout()
- for _, peer := range s.idles {
- idlers.peers = append(idlers.peers, peer)
- idlers.caps = append(idlers.caps, s.peers.rates.Capacity(peer.id, eth.BlockHeadersMsg, targetTTL))
- }
- if len(idlers.peers) == 0 {
- return
- }
- sort.Sort(idlers)
-
- // Find header regions not yet downloading and fill them
- for task, owner := range s.scratchOwners {
- // If we're out of idle peers, stop assigning tasks
- if len(idlers.peers) == 0 {
- return
- }
- // Skip any tasks already filling
- if owner != "" {
- continue
- }
- // If we've reached the genesis, stop assigning tasks
- if uint64(task*requestHeaders) >= s.scratchHead {
- return
- }
- // Found a task and have peers available, assign it
- idle := idlers.peers[0]
-
- idlers.peers = idlers.peers[1:]
- idlers.caps = idlers.caps[1:]
-
- // Matched a pending task to an idle peer, allocate a unique request id
- var reqid uint64
- for {
- reqid = uint64(rand.Int63())
- if reqid == 0 {
- continue
- }
- if _, ok := s.requests[reqid]; ok {
- continue
- }
- break
- }
- // Generate the network query and send it to the peer
- req := &headerRequest{
- peer: idle.id,
- id: reqid,
- deliver: success,
- revert: fail,
- cancel: cancel,
- stale: make(chan struct{}),
- head: s.scratchHead - uint64(task*requestHeaders),
- }
- s.requests[reqid] = req
- delete(s.idles, idle.id)
-
- // Generate the network query and send it to the peer
- go s.executeTask(idle, req)
-
- // Inject the request into the task to block further assignments
- s.scratchOwners[task] = idle.id
- }
-}
-
-// executeTask executes a single fetch request, blocking until either a result
-// arrives or a timeouts / cancellation is triggered. The method should be run
-// on its own goroutine and will deliver on the requested channels.
-func (s *skeleton) executeTask(peer *peerConnection, req *headerRequest) {
- start := time.Now()
- resCh := make(chan *eth.Response)
-
- // Figure out how many headers to fetch. Usually this will be a full batch,
- // but for the very tail of the chain, trim the request to the number left.
- // Since nodes may or may not return the genesis header for a batch request,
- // don't even request it. The parent hash of block #1 is enough to link.
- requestCount := requestHeaders
- if req.head < requestHeaders {
- requestCount = int(req.head)
- }
- peer.log.Trace("Fetching skeleton headers", "from", req.head, "count", requestCount)
- netreq, err := peer.peer.RequestHeadersByNumber(req.head, requestCount, 0, true, resCh)
- if err != nil {
- peer.log.Trace("Failed to request headers", "err", err)
- s.scheduleRevertRequest(req)
- return
- }
- defer netreq.Close()
-
- // Wait until the response arrives, the request is cancelled or times out
- ttl := s.peers.rates.TargetTimeout()
-
- timeoutTimer := time.NewTimer(ttl)
- defer timeoutTimer.Stop()
-
- select {
- case <-req.cancel:
- peer.log.Debug("Header request cancelled")
- s.scheduleRevertRequest(req)
-
- case <-timeoutTimer.C:
- // Header retrieval timed out, update the metrics
- peer.log.Warn("Header request timed out, dropping peer", "elapsed", ttl)
- headerTimeoutMeter.Mark(1)
- s.peers.rates.Update(peer.id, eth.BlockHeadersMsg, 0, 0)
- s.scheduleRevertRequest(req)
-
- // At this point we either need to drop the offending peer, or we need a
- // mechanism to allow waiting for the response and not cancel it. For now
- // lets go with dropping since the header sizes are deterministic and the
- // beacon sync runs exclusive (downloader is idle) so there should be no
- // other load to make timeouts probable. If we notice that timeouts happen
- // more often than we'd like, we can introduce a tracker for the requests
- // gone stale and monitor them. However, in that case too, we need a way
- // to protect against malicious peers never responding, so it would need
- // a second, hard-timeout mechanism.
- s.drop(peer.id)
-
- case res := <-resCh:
- // Headers successfully retrieved, update the metrics
- headers := *res.Res.(*eth.BlockHeadersRequest)
-
- headerReqTimer.Update(time.Since(start))
- s.peers.rates.Update(peer.id, eth.BlockHeadersMsg, res.Time, len(headers))
-
- // Cross validate the headers with the requests
- switch {
- case len(headers) == 0:
- // No headers were delivered, reject the response and reschedule
- peer.log.Debug("No headers delivered")
- res.Done <- errors.New("no headers delivered")
- s.scheduleRevertRequest(req)
-
- case headers[0].Number.Uint64() != req.head:
- // Header batch anchored at non-requested number
- peer.log.Debug("Invalid header response head", "have", headers[0].Number, "want", req.head)
- res.Done <- errors.New("invalid header batch anchor")
- s.scheduleRevertRequest(req)
-
- case req.head >= requestHeaders && len(headers) != requestHeaders:
- // Invalid number of non-genesis headers delivered, reject the response and reschedule
- peer.log.Debug("Invalid non-genesis header count", "have", len(headers), "want", requestHeaders)
- res.Done <- errors.New("not enough non-genesis headers delivered")
- s.scheduleRevertRequest(req)
-
- case req.head < requestHeaders && uint64(len(headers)) != req.head:
- // Invalid number of genesis headers delivered, reject the response and reschedule
- peer.log.Debug("Invalid genesis header count", "have", len(headers), "want", headers[0].Number.Uint64())
- res.Done <- errors.New("not enough genesis headers delivered")
- s.scheduleRevertRequest(req)
-
- default:
- // Packet seems structurally valid, check hash progression and if it
- // is correct too, deliver for storage
- for i := 0; i < len(headers)-1; i++ {
- if headers[i].ParentHash != headers[i+1].Hash() {
- peer.log.Debug("Invalid hash progression", "index", i, "wantparenthash", headers[i].ParentHash, "haveparenthash", headers[i+1].Hash())
- res.Done <- errors.New("invalid hash progression")
- s.scheduleRevertRequest(req)
- return
- }
- }
- // Hash chain is valid. The delivery might still be junk as we're
- // downloading batches concurrently (so no way to link the headers
- // until gaps are filled); in that case, we'll nuke the peer when
- // we detect the fault.
- res.Done <- nil
-
- select {
- case req.deliver <- &headerResponse{
- peer: peer,
- reqid: req.id,
- headers: headers,
- }:
- case <-req.cancel:
- }
- }
- }
-}
-
-// revertRequests locates all the currently pending requests from a particular
-// peer and reverts them, rescheduling for others to fulfill.
-func (s *skeleton) revertRequests(peer string) {
- // Gather the requests first, revertals need the lock too
- var requests []*headerRequest
- for _, req := range s.requests {
- if req.peer == peer {
- requests = append(requests, req)
- }
- }
- // Revert all the requests matching the peer
- for _, req := range requests {
- s.revertRequest(req)
- }
-}
-
-// scheduleRevertRequest asks the event loop to clean up a request and return
-// all failed retrieval tasks to the scheduler for reassignment.
-func (s *skeleton) scheduleRevertRequest(req *headerRequest) {
- select {
- case req.revert <- req:
- // Sync event loop notified
- case <-req.cancel:
- // Sync cycle got cancelled
- case <-req.stale:
- // Request already reverted
- }
-}
-
-// revertRequest cleans up a request and returns all failed retrieval tasks to
-// the scheduler for reassignment.
-//
-// Note, this needs to run on the event runloop thread to reschedule to idle peers.
-// On peer threads, use scheduleRevertRequest.
-func (s *skeleton) revertRequest(req *headerRequest) {
- log.Trace("Reverting header request", "peer", req.peer, "reqid", req.id)
- select {
- case <-req.stale:
- log.Trace("Header request already reverted", "peer", req.peer, "reqid", req.id)
- return
- default:
- }
- close(req.stale)
-
- // Remove the request from the tracked set
- delete(s.requests, req.id)
-
- // Remove the request from the tracked set and mark the task as not-pending,
- // ready for rescheduling
- s.scratchOwners[(s.scratchHead-req.head)/requestHeaders] = ""
-}
-
-func (s *skeleton) processResponse(res *headerResponse) (linked bool, merged bool) {
- res.peer.log.Trace("Processing header response", "head", res.headers[0].Number, "hash", res.headers[0].Hash(), "count", len(res.headers))
-
- // Whether the response is valid, we can mark the peer as idle and notify
- // the scheduler to assign a new task. If the response is invalid, we'll
- // drop the peer in a bit.
- s.idles[res.peer.id] = res.peer
-
- // Ensure the response is for a valid request
- if _, ok := s.requests[res.reqid]; !ok {
- // Some internal accounting is broken. A request either times out or it
- // gets fulfilled successfully. It should not be possible to deliver a
- // response to a non-existing request.
- res.peer.log.Error("Unexpected header packet")
- return false, false
- }
- delete(s.requests, res.reqid)
-
- // Insert the delivered headers into the scratch space independent of the
- // content or continuation; those will be validated in a moment
- head := res.headers[0].Number.Uint64()
- copy(s.scratchSpace[s.scratchHead-head:], res.headers)
-
- // If there's still a gap in the head of the scratch space, abort
- if s.scratchSpace[0] == nil {
- return false, false
- }
- // Try to consume any head headers, validating the boundary conditions
- batch := s.db.NewBatch()
- for s.scratchSpace[0] != nil {
- // Next batch of headers available, cross-reference with the subchain
- // we are extending and either accept or discard
- if s.progress.Subchains[0].Next != s.scratchSpace[0].Hash() {
- // Print a log messages to track what's going on
- tail := s.progress.Subchains[0].Tail
- want := s.progress.Subchains[0].Next
- have := s.scratchSpace[0].Hash()
-
- log.Warn("Invalid skeleton headers", "peer", s.scratchOwners[0], "number", tail-1, "want", want, "have", have)
-
- // The peer delivered junk, or at least not the subchain we are
- // syncing to. Free up the scratch space and assignment, reassign
- // and drop the original peer.
- for i := 0; i < requestHeaders; i++ {
- s.scratchSpace[i] = nil
- }
- s.drop(s.scratchOwners[0])
- s.scratchOwners[0] = ""
- break
- }
- // Scratch delivery matches required subchain, deliver the batch of
- // headers and push the subchain forward
- var consumed int
- for _, header := range s.scratchSpace[:requestHeaders] {
- if header != nil { // nil when the genesis is reached
- consumed++
-
- rawdb.WriteSkeletonHeader(batch, header)
- s.pulled++
-
- s.progress.Subchains[0].Tail--
- s.progress.Subchains[0].Next = header.ParentHash
-
- // If we've reached an existing block in the chain, stop retrieving
- // headers. Note, if we want to support light clients with the same
- // code we'd need to switch here based on the downloader mode. That
- // said, there's no such functionality for now, so don't complicate.
- //
- // In the case of full sync it would be enough to check for the body,
- // but even a full syncing node will generate a receipt once block
- // processing is done, so it's just one more "needless" check.
- //
- // The weird cascading checks are done to minimize the database reads.
- linked = rawdb.HasHeader(s.db, header.ParentHash, header.Number.Uint64()-1) &&
- rawdb.HasBody(s.db, header.ParentHash, header.Number.Uint64()-1) &&
- rawdb.HasReceipts(s.db, header.ParentHash, header.Number.Uint64()-1)
- if linked {
- break
- }
- }
- }
- head := s.progress.Subchains[0].Head
- tail := s.progress.Subchains[0].Tail
- next := s.progress.Subchains[0].Next
-
- log.Trace("Primary subchain extended", "head", head, "tail", tail, "next", next)
-
- // If the beacon chain was linked to the local chain, completely swap out
- // all internal progress and abort header synchronization.
- if linked {
- // Linking into the local chain should also mean that there are no
- // leftover subchains, but in the case of importing the blocks via
- // the engine API, we will not push the subchains forward. This will
- // lead to a gap between an old sync cycle and a future one.
- if subchains := len(s.progress.Subchains); subchains > 1 {
- switch {
- // If there are only 2 subchains - the current one and an older
- // one - and the old one consists of a single block, then it's
- // the expected new sync cycle after some propagated blocks. Log
- // it for debugging purposes, explicitly clean and don't escalate.
- case subchains == 2 && s.progress.Subchains[1].Head == s.progress.Subchains[1].Tail:
- // Remove the leftover skeleton header associated with old
- // skeleton chain only if it's not covered by the current
- // skeleton range.
- if s.progress.Subchains[1].Head < s.progress.Subchains[0].Tail {
- log.Debug("Cleaning previous beacon sync state", "head", s.progress.Subchains[1].Head)
- rawdb.DeleteSkeletonHeader(batch, s.progress.Subchains[1].Head)
- }
- // Drop the leftover skeleton chain since it's stale.
- s.progress.Subchains = s.progress.Subchains[:1]
-
- // If we have more than one header or more than one leftover chain,
- // the syncer's internal state is corrupted. Do try to fix it, but
- // be very vocal about the fault.
- default:
- var context []interface{}
-
- for i := range s.progress.Subchains[1:] {
- context = append(context, fmt.Sprintf("stale_head_%d", i+1))
- context = append(context, s.progress.Subchains[i+1].Head)
- context = append(context, fmt.Sprintf("stale_tail_%d", i+1))
- context = append(context, s.progress.Subchains[i+1].Tail)
- context = append(context, fmt.Sprintf("stale_next_%d", i+1))
- context = append(context, s.progress.Subchains[i+1].Next)
- }
- log.Error("Cleaning spurious beacon sync leftovers", context...)
- s.progress.Subchains = s.progress.Subchains[:1]
-
- // Note, here we didn't actually delete the headers at all,
- // just the metadata. We could implement a cleanup mechanism,
- // but further modifying corrupted state is kind of asking
- // for it. Unless there's a good enough reason to risk it,
- // better to live with the small database junk.
- }
- }
- break
- }
- // Batch of headers consumed, shift the download window forward
- copy(s.scratchSpace, s.scratchSpace[requestHeaders:])
- for i := 0; i < requestHeaders; i++ {
- s.scratchSpace[scratchHeaders-i-1] = nil
- }
- copy(s.scratchOwners, s.scratchOwners[1:])
- s.scratchOwners[scratchHeaders/requestHeaders-1] = ""
-
- s.scratchHead -= uint64(consumed)
-
- // If the subchain extended into the next subchain, we need to handle
- // the overlap. Since there could be many overlaps (come on), do this
- // in a loop.
- for len(s.progress.Subchains) > 1 && s.progress.Subchains[1].Head >= s.progress.Subchains[0].Tail {
- // Extract some stats from the second subchain
- head := s.progress.Subchains[1].Head
- tail := s.progress.Subchains[1].Tail
- next := s.progress.Subchains[1].Next
-
- // Since we just overwrote part of the next subchain, we need to trim
- // its head independent of matching or mismatching content
- if s.progress.Subchains[1].Tail >= s.progress.Subchains[0].Tail {
- // Fully overwritten, get rid of the subchain as a whole
- log.Debug("Previous subchain fully overwritten", "head", head, "tail", tail, "next", next)
- s.progress.Subchains = append(s.progress.Subchains[:1], s.progress.Subchains[2:]...)
- continue
- } else {
- // Partially overwritten, trim the head to the overwritten size
- log.Debug("Previous subchain partially overwritten", "head", head, "tail", tail, "next", next)
- s.progress.Subchains[1].Head = s.progress.Subchains[0].Tail - 1
- }
- // If the old subchain is an extension of the new one, merge the two
- // and let the skeleton syncer restart (to clean internal state)
- if rawdb.ReadSkeletonHeader(s.db, s.progress.Subchains[1].Head).Hash() == s.progress.Subchains[0].Next {
- log.Debug("Previous subchain merged", "head", head, "tail", tail, "next", next)
- s.progress.Subchains[0].Tail = s.progress.Subchains[1].Tail
- s.progress.Subchains[0].Next = s.progress.Subchains[1].Next
-
- s.progress.Subchains = append(s.progress.Subchains[:1], s.progress.Subchains[2:]...)
- merged = true
- }
- }
- // If subchains were merged, all further available headers in the scratch
- // space are invalid since we skipped ahead. Stop processing the scratch
- // space to avoid dropping peers thinking they delivered invalid data.
- if merged {
- break
- }
- }
- s.saveSyncStatus(batch)
- if err := batch.Write(); err != nil {
- log.Crit("Failed to write skeleton headers and progress", "err", err)
- }
- // Print a progress report making the UX a bit nicer
- left := s.progress.Subchains[0].Tail - 1
- if linked {
- left = 0
- }
- if time.Since(s.logged) > 8*time.Second || left == 0 {
- s.logged = time.Now()
-
- if s.pulled == 0 {
- log.Info("Beacon sync starting", "left", left)
- } else {
- eta := float64(time.Since(s.started)) / float64(s.pulled) * float64(left)
- log.Info("Syncing beacon headers", "downloaded", s.pulled, "left", left, "eta", common.PrettyDuration(eta))
- }
- }
- return linked, merged
-}
-
-// cleanStales removes previously synced beacon headers that have become stale
-// due to the downloader backfilling past the tracked tail.
-func (s *skeleton) cleanStales(filled *types.Header) error {
- number := filled.Number.Uint64()
- log.Trace("Cleaning stale beacon headers", "filled", number, "hash", filled.Hash())
-
- // If the filled header is below the linked subchain, something's
- // corrupted internally. Report and error and refuse to do anything.
- if number < s.progress.Subchains[0].Tail {
- return fmt.Errorf("filled header below beacon header tail: %d < %d", number, s.progress.Subchains[0].Tail)
- }
- // Subchain seems trimmable, push the tail forward up to the last
- // filled header and delete everything before it - if available. In
- // case we filled past the head, recreate the subchain with a new
- // head to keep it consistent with the data on disk.
- var (
- start = s.progress.Subchains[0].Tail // start deleting from the first known header
- end = number // delete until the requested threshold
- batch = s.db.NewBatch()
- )
- s.progress.Subchains[0].Tail = number
- s.progress.Subchains[0].Next = filled.ParentHash
-
- if s.progress.Subchains[0].Head < number {
- // If more headers were filled than available, push the entire
- // subchain forward to keep tracking the node's block imports
- end = s.progress.Subchains[0].Head + 1 // delete the entire original range, including the head
- s.progress.Subchains[0].Head = number // assign a new head (tail is already assigned to this)
-
- // The entire original skeleton chain was deleted and a new one
- // defined. Make sure the new single-header chain gets pushed to
- // disk to keep internal state consistent.
- rawdb.WriteSkeletonHeader(batch, filled)
- }
- // Execute the trimming and the potential rewiring of the progress
- s.saveSyncStatus(batch)
- for n := start; n < end; n++ {
- // If the batch grew too big, flush it and continue with a new batch.
- // The catch is that the sync metadata needs to reflect the actually
- // flushed state, so temporarily change the subchain progress and
- // revert after the flush.
- if batch.ValueSize() >= ethdb.IdealBatchSize {
- tmpTail := s.progress.Subchains[0].Tail
- tmpNext := s.progress.Subchains[0].Next
-
- s.progress.Subchains[0].Tail = n
- s.progress.Subchains[0].Next = rawdb.ReadSkeletonHeader(s.db, n).ParentHash
- s.saveSyncStatus(batch)
-
- if err := batch.Write(); err != nil {
- log.Crit("Failed to write beacon trim data", "err", err)
- }
- batch.Reset()
-
- s.progress.Subchains[0].Tail = tmpTail
- s.progress.Subchains[0].Next = tmpNext
- s.saveSyncStatus(batch)
- }
- rawdb.DeleteSkeletonHeader(batch, n)
- }
- if err := batch.Write(); err != nil {
- log.Crit("Failed to write beacon trim data", "err", err)
- }
- return nil
-}
-
-// Bounds retrieves the current head and tail tracked by the skeleton syncer
-// and optionally the last known finalized header if any was announced and if
-// it is still in the sync range. This method is used by the backfiller, whose
-// life cycle is controlled by the skeleton syncer.
-//
-// Note, the method will not use the internal state of the skeleton, but will
-// rather blindly pull stuff from the database. This is fine, because the back-
-// filler will only run when the skeleton chain is fully downloaded and stable.
-// There might be new heads appended, but those are atomic from the perspective
-// of this method. Any head reorg will first tear down the backfiller and only
-// then make the modification.
-func (s *skeleton) Bounds() (head *types.Header, tail *types.Header, final *types.Header, err error) {
- // Read the current sync progress from disk and figure out the current head.
- // Although there's a lot of error handling here, these are mostly as sanity
- // checks to avoid crashing if a programming error happens. These should not
- // happen in live code.
- status := rawdb.ReadSkeletonSyncStatus(s.db)
- if len(status) == 0 {
- return nil, nil, nil, errors.New("beacon sync not yet started")
- }
- progress := new(skeletonProgress)
- if err := json.Unmarshal(status, progress); err != nil {
- return nil, nil, nil, err
- }
- head = rawdb.ReadSkeletonHeader(s.db, progress.Subchains[0].Head)
- if head == nil {
- return nil, nil, nil, fmt.Errorf("head skeleton header %d is missing", progress.Subchains[0].Head)
- }
- tail = rawdb.ReadSkeletonHeader(s.db, progress.Subchains[0].Tail)
- if tail == nil {
- return nil, nil, nil, fmt.Errorf("tail skeleton header %d is missing", progress.Subchains[0].Tail)
- }
- if progress.Finalized != nil && tail.Number.Uint64() <= *progress.Finalized && *progress.Finalized <= head.Number.Uint64() {
- final = rawdb.ReadSkeletonHeader(s.db, *progress.Finalized)
- if final == nil {
- return nil, nil, nil, fmt.Errorf("finalized skeleton header %d is missing", *progress.Finalized)
- }
- }
- return head, tail, final, nil
-}
-
-// Header retrieves a specific header tracked by the skeleton syncer. This method
-// is meant to be used by the backfiller, whose life cycle is controlled by the
-// skeleton syncer.
-//
-// Note, outside the permitted runtimes, this method might return nil results and
-// subsequent calls might return headers from different chains.
-func (s *skeleton) Header(number uint64) *types.Header {
- return rawdb.ReadSkeletonHeader(s.db, number)
-}
diff --git a/eth/downloader/skeleton_test.go b/eth/downloader/skeleton_test.go
deleted file mode 100644
index aceadd00d3..0000000000
--- a/eth/downloader/skeleton_test.go
+++ /dev/null
@@ -1,975 +0,0 @@
-// 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 downloader
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
- "sync/atomic"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// hookedBackfiller is a tester backfiller with all interface methods mocked and
-// hooked so tests can implement only the things they need.
-type hookedBackfiller struct {
- // suspendHook is an optional hook to be called when the filler is requested
- // to be suspended.
- suspendHook func() *types.Header
-
- // resumeHook is an optional hook to be called when the filler is requested
- // to be resumed.
- resumeHook func()
-}
-
-// newHookedBackfiller creates a hooked backfiller with all callbacks disabled,
-// essentially acting as a noop.
-func newHookedBackfiller() backfiller {
- return new(hookedBackfiller)
-}
-
-// suspend requests the backfiller to abort any running full or snap sync
-// based on the skeleton chain as it might be invalid. The backfiller should
-// gracefully handle multiple consecutive suspends without a resume, even
-// on initial startup.
-func (hf *hookedBackfiller) suspend() *types.Header {
- if hf.suspendHook != nil {
- return hf.suspendHook()
- }
- return nil // we don't really care about header cleanups for now
-}
-
-// resume requests the backfiller to start running fill or snap sync based on
-// the skeleton chain as it has successfully been linked. Appending new heads
-// to the end of the chain will not result in suspend/resume cycles.
-func (hf *hookedBackfiller) resume() {
- if hf.resumeHook != nil {
- hf.resumeHook()
- }
-}
-
-// skeletonTestPeer is a mock peer that can only serve header requests from a
-// pre-perated header chain (which may be arbitrarily wrong for testing).
-//
-// Requesting anything else from these peers will hard panic. Note, do *not*
-// implement any other methods. We actually want to make sure that the skeleton
-// syncer only depends on - and will only ever do so - on header requests.
-type skeletonTestPeer struct {
- id string // Unique identifier of the mock peer
- headers []*types.Header // Headers to serve when requested
-
- serve func(origin uint64) []*types.Header // Hook to allow custom responses
-
- served atomic.Uint64 // Number of headers served by this peer
- dropped atomic.Uint64 // Flag whether the peer was dropped (stop responding)
-}
-
-// newSkeletonTestPeer creates a new mock peer to test the skeleton sync with.
-func newSkeletonTestPeer(id string, headers []*types.Header) *skeletonTestPeer {
- return &skeletonTestPeer{
- id: id,
- headers: headers,
- }
-}
-
-// newSkeletonTestPeer creates a new mock peer to test the skeleton sync with,
-// and sets an optional serve hook that can return headers for delivery instead
-// of the predefined chain. Useful for emulating malicious behavior that would
-// otherwise require dedicated peer types.
-func newSkeletonTestPeerWithHook(id string, headers []*types.Header, serve func(origin uint64) []*types.Header) *skeletonTestPeer {
- return &skeletonTestPeer{
- id: id,
- headers: headers,
- serve: serve,
- }
-}
-
-// RequestHeadersByNumber constructs a GetBlockHeaders function based on a numbered
-// origin; associated with a particular peer in the download tester. The returned
-// function can be used to retrieve batches of headers from the particular peer.
-func (p *skeletonTestPeer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool, sink chan *eth.Response) (*eth.Request, error) {
- // Since skeleton test peer are in-memory mocks, dropping the does not make
- // them inaccessible. As such, check a local `dropped` field to see if the
- // peer has been dropped and should not respond any more.
- if p.dropped.Load() != 0 {
- return nil, errors.New("peer already dropped")
- }
- // Skeleton sync retrieves batches of headers going backward without gaps.
- // This ensures we can follow a clean parent progression without any reorg
- // hiccups. There is no need for any other type of header retrieval, so do
- // panic if there's such a request.
- if !reverse || skip != 0 {
- // Note, if other clients want to do these kinds of requests, it's their
- // problem, it will still work. We just don't want *us* making complicated
- // requests without a very strong reason to.
- panic(fmt.Sprintf("invalid header retrieval: reverse %v, want true; skip %d, want 0", reverse, skip))
- }
- // If the skeleton syncer requests the genesis block, panic. Whilst it could
- // be considered a valid request, our code specifically should not request it
- // ever since we want to link up headers to an existing local chain, which at
- // worse will be the genesis.
- if int64(origin)-int64(amount) < 0 {
- panic(fmt.Sprintf("headers requested before (or at) genesis: origin %d, amount %d", origin, amount))
- }
- // To make concurrency easier, the skeleton syncer always requests fixed size
- // batches of headers. Panic if the peer is requested an amount other than the
- // configured batch size (apart from the request leading to the genesis).
- if amount > requestHeaders || (amount < requestHeaders && origin > uint64(amount)) {
- panic(fmt.Sprintf("non-chunk size header batch requested: requested %d, want %d, origin %d", amount, requestHeaders, origin))
- }
- // Simple reverse header retrieval. Fill from the peer's chain and return.
- // If the tester has a serve hook set, try to use that before falling back
- // to the default behavior.
- var headers []*types.Header
- if p.serve != nil {
- headers = p.serve(origin)
- }
- if headers == nil {
- headers = make([]*types.Header, 0, amount)
- if len(p.headers) > int(origin) { // Don't serve headers if we're missing the origin
- for i := 0; i < amount; i++ {
- // Consider nil headers as a form of attack and withhold them. Nil
- // cannot be decoded from RLP, so it's not possible to produce an
- // attack by sending/receiving those over eth.
- header := p.headers[int(origin)-i]
- if header == nil {
- continue
- }
- headers = append(headers, header)
- }
- }
- }
- p.served.Add(uint64(len(headers)))
-
- hashes := make([]common.Hash, len(headers))
- for i, header := range headers {
- hashes[i] = header.Hash()
- }
- // Deliver the headers to the downloader
- req := ð.Request{
- Peer: p.id,
- }
- res := ð.Response{
- Req: req,
- Res: (*eth.BlockHeadersRequest)(&headers),
- Meta: hashes,
- Time: 1,
- Done: make(chan error),
- }
- go func() {
- sink <- res
- if err := <-res.Done; err != nil {
- log.Warn("Skeleton test peer response rejected", "err", err)
- p.dropped.Add(1)
- }
- }()
- return req, nil
-}
-
-func (p *skeletonTestPeer) Head() (common.Hash, *big.Int) {
- panic("skeleton sync must not request the remote head")
-}
-
-func (p *skeletonTestPeer) RequestHeadersByHash(common.Hash, int, int, bool, chan *eth.Response) (*eth.Request, error) {
- panic("skeleton sync must not request headers by hash")
-}
-
-func (p *skeletonTestPeer) RequestBodies([]common.Hash, chan *eth.Response) (*eth.Request, error) {
- panic("skeleton sync must not request block bodies")
-}
-
-func (p *skeletonTestPeer) RequestReceipts([]common.Hash, chan *eth.Response) (*eth.Request, error) {
- panic("skeleton sync must not request receipts")
-}
-
-// Tests various sync initializations based on previous leftovers in the database
-// and announced heads.
-func TestSkeletonSyncInit(t *testing.T) {
- // Create a few key headers
- var (
- genesis = &types.Header{Number: big.NewInt(0)}
- block49 = &types.Header{Number: big.NewInt(49)}
- block49B = &types.Header{Number: big.NewInt(49), Extra: []byte("B")}
- block50 = &types.Header{Number: big.NewInt(50), ParentHash: block49.Hash()}
- )
- tests := []struct {
- headers []*types.Header // Database content (beside the genesis)
- oldstate []*subchain // Old sync state with various interrupted subchains
- head *types.Header // New head header to announce to reorg to
- newstate []*subchain // Expected sync state after the reorg
- }{
- // Completely empty database with only the genesis set. The sync is expected
- // to create a single subchain with the requested head.
- {
- head: block50,
- newstate: []*subchain{{Head: 50, Tail: 50}},
- },
- // Empty database with only the genesis set with a leftover empty sync
- // progress. This is a synthetic case, just for the sake of covering things.
- {
- oldstate: []*subchain{},
- head: block50,
- newstate: []*subchain{{Head: 50, Tail: 50}},
- },
- // A single leftover subchain is present, older than the new head. The
- // old subchain should be left as is and a new one appended to the sync
- // status.
- {
- oldstate: []*subchain{{Head: 10, Tail: 5}},
- head: block50,
- newstate: []*subchain{
- {Head: 50, Tail: 50},
- {Head: 10, Tail: 5},
- },
- },
- // Multiple leftover subchains are present, older than the new head. The
- // old subchains should be left as is and a new one appended to the sync
- // status.
- {
- oldstate: []*subchain{
- {Head: 20, Tail: 15},
- {Head: 10, Tail: 5},
- },
- head: block50,
- newstate: []*subchain{
- {Head: 50, Tail: 50},
- {Head: 20, Tail: 15},
- {Head: 10, Tail: 5},
- },
- },
- // A single leftover subchain is present, newer than the new head. The
- // newer subchain should be deleted and a fresh one created for the head.
- {
- oldstate: []*subchain{{Head: 65, Tail: 60}},
- head: block50,
- newstate: []*subchain{{Head: 50, Tail: 50}},
- },
- // Multiple leftover subchain is present, newer than the new head. The
- // newer subchains should be deleted and a fresh one created for the head.
- {
- oldstate: []*subchain{
- {Head: 75, Tail: 70},
- {Head: 65, Tail: 60},
- },
- head: block50,
- newstate: []*subchain{{Head: 50, Tail: 50}},
- },
-
- // Two leftover subchains are present, one fully older and one fully
- // newer than the announced head. The head should delete the newer one,
- // keeping the older one.
- {
- oldstate: []*subchain{
- {Head: 65, Tail: 60},
- {Head: 10, Tail: 5},
- },
- head: block50,
- newstate: []*subchain{
- {Head: 50, Tail: 50},
- {Head: 10, Tail: 5},
- },
- },
- // Multiple leftover subchains are present, some fully older and some
- // fully newer than the announced head. The head should delete the newer
- // ones, keeping the older ones.
- {
- oldstate: []*subchain{
- {Head: 75, Tail: 70},
- {Head: 65, Tail: 60},
- {Head: 20, Tail: 15},
- {Head: 10, Tail: 5},
- },
- head: block50,
- newstate: []*subchain{
- {Head: 50, Tail: 50},
- {Head: 20, Tail: 15},
- {Head: 10, Tail: 5},
- },
- },
- // A single leftover subchain is present and the new head is extending
- // it with one more header. We expect the subchain head to be pushed
- // forward.
- {
- headers: []*types.Header{block49},
- oldstate: []*subchain{{Head: 49, Tail: 5}},
- head: block50,
- newstate: []*subchain{{Head: 50, Tail: 5}},
- },
- // A single leftover subchain is present and although the new head does
- // extend it number wise, the hash chain does not link up. We expect a
- // new subchain to be created for the dangling head.
- {
- headers: []*types.Header{block49B},
- oldstate: []*subchain{{Head: 49, Tail: 5}},
- head: block50,
- newstate: []*subchain{
- {Head: 50, Tail: 50},
- {Head: 49, Tail: 5},
- },
- },
- // A single leftover subchain is present. A new head is announced that
- // links into the middle of it, correctly anchoring into an existing
- // header. We expect the old subchain to be truncated and extended with
- // the new head.
- {
- headers: []*types.Header{block49},
- oldstate: []*subchain{{Head: 100, Tail: 5}},
- head: block50,
- newstate: []*subchain{{Head: 50, Tail: 5}},
- },
- // A single leftover subchain is present. A new head is announced that
- // links into the middle of it, but does not anchor into an existing
- // header. We expect the old subchain to be truncated and a new chain
- // be created for the dangling head.
- {
- headers: []*types.Header{block49B},
- oldstate: []*subchain{{Head: 100, Tail: 5}},
- head: block50,
- newstate: []*subchain{
- {Head: 50, Tail: 50},
- {Head: 49, Tail: 5},
- },
- },
- }
- for i, tt := range tests {
- // Create a fresh database and initialize it with the starting state
- db := rawdb.NewMemoryDatabase()
-
- rawdb.WriteHeader(db, genesis)
- for _, header := range tt.headers {
- rawdb.WriteSkeletonHeader(db, header)
- }
- if tt.oldstate != nil {
- blob, _ := json.Marshal(&skeletonProgress{Subchains: tt.oldstate})
- rawdb.WriteSkeletonSyncStatus(db, blob)
- }
- // Create a skeleton sync and run a cycle
- wait := make(chan struct{})
-
- skeleton := newSkeleton(db, newPeerSet(), nil, newHookedBackfiller())
- skeleton.syncStarting = func() { close(wait) }
- skeleton.Sync(tt.head, nil, true)
-
- <-wait
- skeleton.Terminate()
-
- // Ensure the correct resulting sync status
- var progress skeletonProgress
- json.Unmarshal(rawdb.ReadSkeletonSyncStatus(db), &progress)
-
- if len(progress.Subchains) != len(tt.newstate) {
- t.Errorf("test %d: subchain count mismatch: have %d, want %d", i, len(progress.Subchains), len(tt.newstate))
- continue
- }
- for j := 0; j < len(progress.Subchains); j++ {
- if progress.Subchains[j].Head != tt.newstate[j].Head {
- t.Errorf("test %d: subchain %d head mismatch: have %d, want %d", i, j, progress.Subchains[j].Head, tt.newstate[j].Head)
- }
- if progress.Subchains[j].Tail != tt.newstate[j].Tail {
- t.Errorf("test %d: subchain %d tail mismatch: have %d, want %d", i, j, progress.Subchains[j].Tail, tt.newstate[j].Tail)
- }
- }
- }
-}
-
-// Tests that a running skeleton sync can be extended with properly linked up
-// headers but not with side chains.
-func TestSkeletonSyncExtend(t *testing.T) {
- // Create a few key headers
- var (
- genesis = &types.Header{Number: big.NewInt(0)}
- block49 = &types.Header{Number: big.NewInt(49)}
- block49B = &types.Header{Number: big.NewInt(49), Extra: []byte("B")}
- block50 = &types.Header{Number: big.NewInt(50), ParentHash: block49.Hash()}
- block51 = &types.Header{Number: big.NewInt(51), ParentHash: block50.Hash()}
- )
- tests := []struct {
- head *types.Header // New head header to announce to reorg to
- extend *types.Header // New head header to announce to extend with
- newstate []*subchain // Expected sync state after the reorg
- err error // Whether extension succeeds or not
- }{
- // Initialize a sync and try to extend it with a subsequent block.
- {
- head: block49,
- extend: block50,
- newstate: []*subchain{
- {Head: 50, Tail: 49},
- },
- },
- // Initialize a sync and try to extend it with the existing head block.
- {
- head: block49,
- extend: block49,
- newstate: []*subchain{
- {Head: 49, Tail: 49},
- },
- },
- // Initialize a sync and try to extend it with a sibling block.
- {
- head: block49,
- extend: block49B,
- newstate: []*subchain{
- {Head: 49, Tail: 49},
- },
- err: errChainReorged,
- },
- // Initialize a sync and try to extend it with a number-wise sequential
- // header, but a hash wise non-linking one.
- {
- head: block49B,
- extend: block50,
- newstate: []*subchain{
- {Head: 49, Tail: 49},
- },
- err: errChainForked,
- },
- // Initialize a sync and try to extend it with a non-linking future block.
- {
- head: block49,
- extend: block51,
- newstate: []*subchain{
- {Head: 49, Tail: 49},
- },
- err: errChainGapped,
- },
- // Initialize a sync and try to extend it with a past canonical block.
- {
- head: block50,
- extend: block49,
- newstate: []*subchain{
- {Head: 50, Tail: 50},
- },
- err: errChainReorged,
- },
- // Initialize a sync and try to extend it with a past sidechain block.
- {
- head: block50,
- extend: block49B,
- newstate: []*subchain{
- {Head: 50, Tail: 50},
- },
- err: errChainReorged,
- },
- }
- for i, tt := range tests {
- // Create a fresh database and initialize it with the starting state
- db := rawdb.NewMemoryDatabase()
- rawdb.WriteHeader(db, genesis)
-
- // Create a skeleton sync and run a cycle
- wait := make(chan struct{})
-
- skeleton := newSkeleton(db, newPeerSet(), nil, newHookedBackfiller())
- skeleton.syncStarting = func() { close(wait) }
- skeleton.Sync(tt.head, nil, true)
-
- <-wait
- if err := skeleton.Sync(tt.extend, nil, false); !errors.Is(err, tt.err) {
- t.Errorf("test %d: extension failure mismatch: have %v, want %v", i, err, tt.err)
- }
- skeleton.Terminate()
-
- // Ensure the correct resulting sync status
- var progress skeletonProgress
- json.Unmarshal(rawdb.ReadSkeletonSyncStatus(db), &progress)
-
- if len(progress.Subchains) != len(tt.newstate) {
- t.Errorf("test %d: subchain count mismatch: have %d, want %d", i, len(progress.Subchains), len(tt.newstate))
- continue
- }
- for j := 0; j < len(progress.Subchains); j++ {
- if progress.Subchains[j].Head != tt.newstate[j].Head {
- t.Errorf("test %d: subchain %d head mismatch: have %d, want %d", i, j, progress.Subchains[j].Head, tt.newstate[j].Head)
- }
- if progress.Subchains[j].Tail != tt.newstate[j].Tail {
- t.Errorf("test %d: subchain %d tail mismatch: have %d, want %d", i, j, progress.Subchains[j].Tail, tt.newstate[j].Tail)
- }
- }
- }
-}
-
-// Tests that the skeleton sync correctly retrieves headers from one or more
-// peers without duplicates or other strange side effects.
-func TestSkeletonSyncRetrievals(t *testing.T) {
- //log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
-
- // Since skeleton headers don't need to be meaningful, beyond a parent hash
- // progression, create a long fake chain to test with.
- chain := []*types.Header{{Number: big.NewInt(0)}}
- for i := 1; i < 10000; i++ {
- chain = append(chain, &types.Header{
- ParentHash: chain[i-1].Hash(),
- Number: big.NewInt(int64(i)),
- })
- }
- // Some tests require a forking side chain to trigger cornercases.
- var sidechain []*types.Header
- for i := 0; i < len(chain)/2; i++ { // Fork at block #5000
- sidechain = append(sidechain, chain[i])
- }
- for i := len(chain) / 2; i < len(chain); i++ {
- sidechain = append(sidechain, &types.Header{
- ParentHash: sidechain[i-1].Hash(),
- Number: big.NewInt(int64(i)),
- Extra: []byte("B"), // force a different hash
- })
- }
- tests := []struct {
- fill bool // Whether to run a real backfiller in this test case
- unpredictable bool // Whether to ignore drops/serves due to uncertain packet assignments
-
- head *types.Header // New head header to announce to reorg to
- peers []*skeletonTestPeer // Initial peer set to start the sync with
- midstate []*subchain // Expected sync state after initial cycle
- midserve uint64 // Expected number of header retrievals after initial cycle
- middrop uint64 // Expected number of peers dropped after initial cycle
-
- newHead *types.Header // New header to anoint on top of the old one
- newPeer *skeletonTestPeer // New peer to join the skeleton syncer
- endstate []*subchain // Expected sync state after the post-init event
- endserve uint64 // Expected number of header retrievals after the post-init event
- enddrop uint64 // Expected number of peers dropped after the post-init event
- }{
- // Completely empty database with only the genesis set. The sync is expected
- // to create a single subchain with the requested head. No peers however, so
- // the sync should be stuck without any progression.
- //
- // When a new peer is added, it should detect the join and fill the headers
- // to the genesis block.
- {
- head: chain[len(chain)-1],
- midstate: []*subchain{{Head: uint64(len(chain) - 1), Tail: uint64(len(chain) - 1)}},
-
- newPeer: newSkeletonTestPeer("test-peer", chain),
- endstate: []*subchain{{Head: uint64(len(chain) - 1), Tail: 1}},
- endserve: uint64(len(chain) - 2), // len - head - genesis
- },
- // Completely empty database with only the genesis set. The sync is expected
- // to create a single subchain with the requested head. With one valid peer,
- // the sync is expected to complete already in the initial round.
- //
- // Adding a second peer should not have any effect.
- {
- head: chain[len(chain)-1],
- peers: []*skeletonTestPeer{newSkeletonTestPeer("test-peer-1", chain)},
- midstate: []*subchain{{Head: uint64(len(chain) - 1), Tail: 1}},
- midserve: uint64(len(chain) - 2), // len - head - genesis
-
- newPeer: newSkeletonTestPeer("test-peer-2", chain),
- endstate: []*subchain{{Head: uint64(len(chain) - 1), Tail: 1}},
- endserve: uint64(len(chain) - 2), // len - head - genesis
- },
- // Completely empty database with only the genesis set. The sync is expected
- // to create a single subchain with the requested head. With many valid peers,
- // the sync is expected to complete already in the initial round.
- //
- // Adding a new peer should not have any effect.
- {
- head: chain[len(chain)-1],
- peers: []*skeletonTestPeer{
- newSkeletonTestPeer("test-peer-1", chain),
- newSkeletonTestPeer("test-peer-2", chain),
- newSkeletonTestPeer("test-peer-3", chain),
- },
- midstate: []*subchain{{Head: uint64(len(chain) - 1), Tail: 1}},
- midserve: uint64(len(chain) - 2), // len - head - genesis
-
- newPeer: newSkeletonTestPeer("test-peer-4", chain),
- endstate: []*subchain{{Head: uint64(len(chain) - 1), Tail: 1}},
- endserve: uint64(len(chain) - 2), // len - head - genesis
- },
- // This test checks if a peer tries to withhold a header - *on* the sync
- // boundary - instead of sending the requested amount. The malicious short
- // package should not be accepted.
- //
- // Joining with a new peer should however unblock the sync.
- {
- head: chain[requestHeaders+100],
- peers: []*skeletonTestPeer{
- newSkeletonTestPeer("header-skipper", append(append(append([]*types.Header{}, chain[:99]...), nil), chain[100:]...)),
- },
- midstate: []*subchain{{Head: requestHeaders + 100, Tail: 100}},
- midserve: requestHeaders + 101 - 3, // len - head - genesis - missing
- middrop: 1, // penalize shortened header deliveries
-
- newPeer: newSkeletonTestPeer("good-peer", chain),
- endstate: []*subchain{{Head: requestHeaders + 100, Tail: 1}},
- endserve: (requestHeaders + 101 - 3) + (100 - 1), // midserve + lenrest - genesis
- enddrop: 1, // no new drops
- },
- // This test checks if a peer tries to withhold a header - *off* the sync
- // boundary - instead of sending the requested amount. The malicious short
- // package should not be accepted.
- //
- // Joining with a new peer should however unblock the sync.
- {
- head: chain[requestHeaders+100],
- peers: []*skeletonTestPeer{
- newSkeletonTestPeer("header-skipper", append(append(append([]*types.Header{}, chain[:50]...), nil), chain[51:]...)),
- },
- midstate: []*subchain{{Head: requestHeaders + 100, Tail: 100}},
- midserve: requestHeaders + 101 - 3, // len - head - genesis - missing
- middrop: 1, // penalize shortened header deliveries
-
- newPeer: newSkeletonTestPeer("good-peer", chain),
- endstate: []*subchain{{Head: requestHeaders + 100, Tail: 1}},
- endserve: (requestHeaders + 101 - 3) + (100 - 1), // midserve + lenrest - genesis
- enddrop: 1, // no new drops
- },
- // This test checks if a peer tries to duplicate a header - *on* the sync
- // boundary - instead of sending the correct sequence. The malicious duped
- // package should not be accepted.
- //
- // Joining with a new peer should however unblock the sync.
- {
- head: chain[requestHeaders+100], // We want to force the 100th header to be a request boundary
- peers: []*skeletonTestPeer{
- newSkeletonTestPeer("header-duper", append(append(append([]*types.Header{}, chain[:99]...), chain[98]), chain[100:]...)),
- },
- midstate: []*subchain{{Head: requestHeaders + 100, Tail: 100}},
- midserve: requestHeaders + 101 - 2, // len - head - genesis
- middrop: 1, // penalize invalid header sequences
-
- newPeer: newSkeletonTestPeer("good-peer", chain),
- endstate: []*subchain{{Head: requestHeaders + 100, Tail: 1}},
- endserve: (requestHeaders + 101 - 2) + (100 - 1), // midserve + lenrest - genesis
- enddrop: 1, // no new drops
- },
- // This test checks if a peer tries to duplicate a header - *off* the sync
- // boundary - instead of sending the correct sequence. The malicious duped
- // package should not be accepted.
- //
- // Joining with a new peer should however unblock the sync.
- {
- head: chain[requestHeaders+100], // We want to force the 100th header to be a request boundary
- peers: []*skeletonTestPeer{
- newSkeletonTestPeer("header-duper", append(append(append([]*types.Header{}, chain[:50]...), chain[49]), chain[51:]...)),
- },
- midstate: []*subchain{{Head: requestHeaders + 100, Tail: 100}},
- midserve: requestHeaders + 101 - 2, // len - head - genesis
- middrop: 1, // penalize invalid header sequences
-
- newPeer: newSkeletonTestPeer("good-peer", chain),
- endstate: []*subchain{{Head: requestHeaders + 100, Tail: 1}},
- endserve: (requestHeaders + 101 - 2) + (100 - 1), // midserve + lenrest - genesis
- enddrop: 1, // no new drops
- },
- // This test checks if a peer tries to inject a different header - *on*
- // the sync boundary - instead of sending the correct sequence. The bad
- // package should not be accepted.
- //
- // Joining with a new peer should however unblock the sync.
- {
- head: chain[requestHeaders+100], // We want to force the 100th header to be a request boundary
- peers: []*skeletonTestPeer{
- newSkeletonTestPeer("header-changer",
- append(
- append(
- append([]*types.Header{}, chain[:99]...),
- &types.Header{
- ParentHash: chain[98].Hash(),
- Number: big.NewInt(int64(99)),
- GasLimit: 1,
- },
- ), chain[100:]...,
- ),
- ),
- },
- midstate: []*subchain{{Head: requestHeaders + 100, Tail: 100}},
- midserve: requestHeaders + 101 - 2, // len - head - genesis
- middrop: 1, // different set of headers, drop // TODO(karalabe): maybe just diff sync?
-
- newPeer: newSkeletonTestPeer("good-peer", chain),
- endstate: []*subchain{{Head: requestHeaders + 100, Tail: 1}},
- endserve: (requestHeaders + 101 - 2) + (100 - 1), // midserve + lenrest - genesis
- enddrop: 1, // no new drops
- },
- // This test checks if a peer tries to inject a different header - *off*
- // the sync boundary - instead of sending the correct sequence. The bad
- // package should not be accepted.
- //
- // Joining with a new peer should however unblock the sync.
- {
- head: chain[requestHeaders+100], // We want to force the 100th header to be a request boundary
- peers: []*skeletonTestPeer{
- newSkeletonTestPeer("header-changer",
- append(
- append(
- append([]*types.Header{}, chain[:50]...),
- &types.Header{
- ParentHash: chain[49].Hash(),
- Number: big.NewInt(int64(50)),
- GasLimit: 1,
- },
- ), chain[51:]...,
- ),
- ),
- },
- midstate: []*subchain{{Head: requestHeaders + 100, Tail: 100}},
- midserve: requestHeaders + 101 - 2, // len - head - genesis
- middrop: 1, // different set of headers, drop
-
- newPeer: newSkeletonTestPeer("good-peer", chain),
- endstate: []*subchain{{Head: requestHeaders + 100, Tail: 1}},
- endserve: (requestHeaders + 101 - 2) + (100 - 1), // midserve + lenrest - genesis
- enddrop: 1, // no new drops
- },
- // This test reproduces a bug caught during review (kudos to @holiman)
- // where a subchain is merged with a previously interrupted one, causing
- // pending data in the scratch space to become "invalid" (since we jump
- // ahead during subchain merge). In that case it is expected to ignore
- // the queued up data instead of trying to process on top of a shifted
- // task set.
- //
- // The test is a bit convoluted since it needs to trigger a concurrency
- // issue. First we sync up an initial chain of 2x512 items. Then announce
- // 2x512+2 as head and delay delivering the head batch to fill the scratch
- // space first. The delivery head should merge with the previous download
- // and the scratch space must not be consumed further.
- {
- head: chain[2*requestHeaders],
- peers: []*skeletonTestPeer{
- newSkeletonTestPeerWithHook("peer-1", chain, func(origin uint64) []*types.Header {
- if origin == chain[2*requestHeaders+1].Number.Uint64() {
- time.Sleep(100 * time.Millisecond)
- }
- return nil // Fallback to default behavior, just delayed
- }),
- newSkeletonTestPeerWithHook("peer-2", chain, func(origin uint64) []*types.Header {
- if origin == chain[2*requestHeaders+1].Number.Uint64() {
- time.Sleep(100 * time.Millisecond)
- }
- return nil // Fallback to default behavior, just delayed
- }),
- },
- midstate: []*subchain{{Head: 2 * requestHeaders, Tail: 1}},
- midserve: 2*requestHeaders - 1, // len - head - genesis
-
- newHead: chain[2*requestHeaders+2],
- endstate: []*subchain{{Head: 2*requestHeaders + 2, Tail: 1}},
- endserve: 4 * requestHeaders,
- },
- // This test reproduces a bug caught by (@rjl493456442) where a skeleton
- // header goes missing, causing the sync to get stuck and/or panic.
- //
- // The setup requires a previously successfully synced chain up to a block
- // height N. That results is a single skeleton header (block N) and a single
- // subchain (head N, Tail N) being stored on disk.
- //
- // The following step requires a new sync cycle to a new side chain of a
- // height higher than N, and an ancestor lower than N (e.g. N-2, N+2).
- // In this scenario, when processing a batch of headers, a link point of
- // N-2 will be found, meaning that N-1 and N have been overwritten.
- //
- // The link event triggers an early exit, noticing that the previous sub-
- // chain is a leftover and deletes it (with it's skeleton header N). But
- // since skeleton header N has been overwritten to the new side chain, we
- // end up losing it and creating a gap.
- {
- fill: true,
- unpredictable: true, // We have good and bad peer too, bad may be dropped, test too short for certainty
-
- head: chain[len(chain)/2+1], // Sync up until the sidechain common ancestor + 2
- peers: []*skeletonTestPeer{newSkeletonTestPeer("test-peer-oldchain", chain)},
- midstate: []*subchain{{Head: uint64(len(chain)/2 + 1), Tail: 1}},
-
- newHead: sidechain[len(sidechain)/2+3], // Sync up until the sidechain common ancestor + 4
- newPeer: newSkeletonTestPeer("test-peer-newchain", sidechain),
- endstate: []*subchain{{Head: uint64(len(sidechain)/2 + 3), Tail: uint64(len(chain) / 2)}},
- },
- }
- for i, tt := range tests {
- // Create a fresh database and initialize it with the starting state
- db := rawdb.NewMemoryDatabase()
-
- rawdb.WriteBlock(db, types.NewBlockWithHeader(chain[0]))
- rawdb.WriteReceipts(db, chain[0].Hash(), chain[0].Number.Uint64(), types.Receipts{})
-
- // Create a peer set to feed headers through
- peerset := newPeerSet()
- for _, peer := range tt.peers {
- peerset.Register(newPeerConnection(peer.id, eth.ETH67, peer, log.New("id", peer.id)))
- }
- // Create a peer dropper to track malicious peers
- dropped := make(map[string]int)
- drop := func(peer string) {
- if p := peerset.Peer(peer); p != nil {
- p.peer.(*skeletonTestPeer).dropped.Add(1)
- }
- peerset.Unregister(peer)
- dropped[peer]++
- }
- // Create a backfiller if we need to run more advanced tests
- filler := newHookedBackfiller()
- if tt.fill {
- var filled *types.Header
-
- filler = &hookedBackfiller{
- resumeHook: func() {
- var progress skeletonProgress
- json.Unmarshal(rawdb.ReadSkeletonSyncStatus(db), &progress)
-
- for progress.Subchains[0].Tail < progress.Subchains[0].Head {
- header := rawdb.ReadSkeletonHeader(db, progress.Subchains[0].Tail)
-
- rawdb.WriteBlock(db, types.NewBlockWithHeader(header))
- rawdb.WriteReceipts(db, header.Hash(), header.Number.Uint64(), types.Receipts{})
-
- rawdb.DeleteSkeletonHeader(db, header.Number.Uint64())
-
- progress.Subchains[0].Tail++
- progress.Subchains[0].Next = header.Hash()
- }
- filled = rawdb.ReadSkeletonHeader(db, progress.Subchains[0].Tail)
-
- rawdb.WriteBlock(db, types.NewBlockWithHeader(filled))
- rawdb.WriteReceipts(db, filled.Hash(), filled.Number.Uint64(), types.Receipts{})
- },
-
- suspendHook: func() *types.Header {
- prev := filled
- filled = nil
-
- return prev
- },
- }
- }
- // Create a skeleton sync and run a cycle
- skeleton := newSkeleton(db, peerset, drop, filler)
- skeleton.Sync(tt.head, nil, true)
-
- var progress skeletonProgress
- // Wait a bit (bleah) for the initial sync loop to go to idle. This might
- // be either a finish or a never-start hence why there's no event to hook.
- check := func() error {
- if len(progress.Subchains) != len(tt.midstate) {
- return fmt.Errorf("test %d, mid state: subchain count mismatch: have %d, want %d", i, len(progress.Subchains), len(tt.midstate))
- }
- for j := 0; j < len(progress.Subchains); j++ {
- if progress.Subchains[j].Head != tt.midstate[j].Head {
- return fmt.Errorf("test %d, mid state: subchain %d head mismatch: have %d, want %d", i, j, progress.Subchains[j].Head, tt.midstate[j].Head)
- }
- if progress.Subchains[j].Tail != tt.midstate[j].Tail {
- return fmt.Errorf("test %d, mid state: subchain %d tail mismatch: have %d, want %d", i, j, progress.Subchains[j].Tail, tt.midstate[j].Tail)
- }
- }
- return nil
- }
-
- waitStart := time.Now()
- for waitTime := 20 * time.Millisecond; time.Since(waitStart) < 2*time.Second; waitTime = waitTime * 2 {
- time.Sleep(waitTime)
- // Check the post-init end state if it matches the required results
- json.Unmarshal(rawdb.ReadSkeletonSyncStatus(db), &progress)
- if err := check(); err == nil {
- break
- }
- }
- if err := check(); err != nil {
- t.Error(err)
- continue
- }
- if !tt.unpredictable {
- var served uint64
- for _, peer := range tt.peers {
- served += peer.served.Load()
- }
- if served != tt.midserve {
- t.Errorf("test %d, mid state: served headers mismatch: have %d, want %d", i, served, tt.midserve)
- }
- var drops uint64
- for _, peer := range tt.peers {
- drops += peer.dropped.Load()
- }
- if drops != tt.middrop {
- t.Errorf("test %d, mid state: dropped peers mismatch: have %d, want %d", i, drops, tt.middrop)
- }
- }
- // Apply the post-init events if there's any
- if tt.newHead != nil {
- skeleton.Sync(tt.newHead, nil, true)
- }
- if tt.newPeer != nil {
- if err := peerset.Register(newPeerConnection(tt.newPeer.id, eth.ETH67, tt.newPeer, log.New("id", tt.newPeer.id))); err != nil {
- t.Errorf("test %d: failed to register new peer: %v", i, err)
- }
- }
- // Wait a bit (bleah) for the second sync loop to go to idle. This might
- // be either a finish or a never-start hence why there's no event to hook.
- check = func() error {
- if len(progress.Subchains) != len(tt.endstate) {
- return fmt.Errorf("test %d, end state: subchain count mismatch: have %d, want %d", i, len(progress.Subchains), len(tt.endstate))
- }
- for j := 0; j < len(progress.Subchains); j++ {
- if progress.Subchains[j].Head != tt.endstate[j].Head {
- return fmt.Errorf("test %d, end state: subchain %d head mismatch: have %d, want %d", i, j, progress.Subchains[j].Head, tt.endstate[j].Head)
- }
- if progress.Subchains[j].Tail != tt.endstate[j].Tail {
- return fmt.Errorf("test %d, end state: subchain %d tail mismatch: have %d, want %d", i, j, progress.Subchains[j].Tail, tt.endstate[j].Tail)
- }
- }
- return nil
- }
- waitStart = time.Now()
- for waitTime := 20 * time.Millisecond; time.Since(waitStart) < 2*time.Second; waitTime = waitTime * 2 {
- time.Sleep(waitTime)
- // Check the post-init end state if it matches the required results
- json.Unmarshal(rawdb.ReadSkeletonSyncStatus(db), &progress)
- if err := check(); err == nil {
- break
- }
- }
- if err := check(); err != nil {
- t.Error(err)
- continue
- }
- // Check that the peers served no more headers than we actually needed
- if !tt.unpredictable {
- served := uint64(0)
- for _, peer := range tt.peers {
- served += peer.served.Load()
- }
- if tt.newPeer != nil {
- served += tt.newPeer.served.Load()
- }
- if served != tt.endserve {
- t.Errorf("test %d, end state: served headers mismatch: have %d, want %d", i, served, tt.endserve)
- }
- drops := uint64(0)
- for _, peer := range tt.peers {
- drops += peer.dropped.Load()
- }
- if tt.newPeer != nil {
- drops += tt.newPeer.dropped.Load()
- }
- if drops != tt.enddrop {
- t.Errorf("test %d, end state: dropped peers mismatch: have %d, want %d", i, drops, tt.middrop)
- }
- }
- // Clean up any leftover skeleton sync resources
- skeleton.Terminate()
- }
-}
diff --git a/eth/downloader/statesync.go b/eth/downloader/statesync.go
deleted file mode 100644
index 501af63ed5..0000000000
--- a/eth/downloader/statesync.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 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 downloader
-
-import (
- "sync"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// syncState starts downloading state with the given root hash.
-func (d *Downloader) syncState(root common.Hash) *stateSync {
- // Create the state sync
- s := newStateSync(d, root)
- select {
- case d.stateSyncStart <- s:
- // If we tell the statesync to restart with a new root, we also need
- // to wait for it to actually also start -- when old requests have timed
- // out or been delivered
- <-s.started
- case <-d.quitCh:
- s.err = errCancelStateFetch
- close(s.done)
- }
- return s
-}
-
-// stateFetcher manages the active state sync and accepts requests
-// on its behalf.
-func (d *Downloader) stateFetcher() {
- for {
- select {
- case s := <-d.stateSyncStart:
- for next := s; next != nil; {
- next = d.runStateSync(next)
- }
- case <-d.quitCh:
- return
- }
- }
-}
-
-// runStateSync runs a state synchronisation until it completes or another root
-// hash is requested to be switched over to.
-func (d *Downloader) runStateSync(s *stateSync) *stateSync {
- log.Trace("State sync starting", "root", s.root)
-
- go s.run()
- defer s.Cancel()
-
- for {
- select {
- case next := <-d.stateSyncStart:
- return next
-
- case <-s.done:
- return nil
- }
- }
-}
-
-// stateSync schedules requests for downloading a particular state trie defined
-// by a given state root.
-type stateSync struct {
- d *Downloader // Downloader instance to access and manage current peerset
- root common.Hash // State root currently being synced
-
- started chan struct{} // Started is signalled once the sync loop starts
- cancel chan struct{} // Channel to signal a termination request
- cancelOnce sync.Once // Ensures cancel only ever gets called once
- done chan struct{} // Channel to signal termination completion
- err error // Any error hit during sync (set before completion)
-}
-
-// newStateSync creates a new state trie download scheduler. This method does not
-// yet start the sync. The user needs to call run to initiate.
-func newStateSync(d *Downloader, root common.Hash) *stateSync {
- return &stateSync{
- d: d,
- root: root,
- cancel: make(chan struct{}),
- done: make(chan struct{}),
- started: make(chan struct{}),
- }
-}
-
-// run starts the task assignment and response processing loop, blocking until
-// it finishes, and finally notifying any goroutines waiting for the loop to
-// finish.
-func (s *stateSync) run() {
- close(s.started)
- s.err = s.d.SnapSyncer.Sync(s.root, s.cancel)
- close(s.done)
-}
-
-// Wait blocks until the sync is done or canceled.
-func (s *stateSync) Wait() error {
- <-s.done
- return s.err
-}
-
-// Cancel cancels the sync and waits until it has shut down.
-func (s *stateSync) Cancel() error {
- s.cancelOnce.Do(func() {
- close(s.cancel)
- })
- return s.Wait()
-}
diff --git a/eth/downloader/testchain_test.go b/eth/downloader/testchain_test.go
deleted file mode 100644
index 1bf03411d1..0000000000
--- a/eth/downloader/testchain_test.go
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2018 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 downloader
-
-import (
- "fmt"
- "math/big"
- "sync"
- "time"
-
- "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/params"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-// Test chain parameters.
-var (
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
- testDB = rawdb.NewMemoryDatabase()
-
- testGspec = &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{testAddress: {Balance: big.NewInt(1000000000000000)}},
- BaseFee: big.NewInt(params.InitialBaseFee),
- }
- testGenesis = testGspec.MustCommit(testDB, trie.NewDatabase(testDB, trie.HashDefaults))
-)
-
-// The common prefix of all test chains:
-var testChainBase *testChain
-
-// Different forks on top of the base chain:
-var testChainForkLightA, testChainForkLightB, testChainForkHeavy *testChain
-
-var pregenerated bool
-
-func init() {
- // Reduce some of the parameters to make the tester faster
- fullMaxForkAncestry = 10000
- lightMaxForkAncestry = 10000
- blockCacheMaxItems = 1024
- fsHeaderSafetyNet = 256
- fsHeaderContCheck = 500 * time.Millisecond
-
- testChainBase = newTestChain(blockCacheMaxItems+200, testGenesis)
-
- var forkLen = int(fullMaxForkAncestry + 50)
- var wg sync.WaitGroup
-
- // Generate the test chains to seed the peers with
- wg.Add(3)
- go func() { testChainForkLightA = testChainBase.makeFork(forkLen, false, 1); wg.Done() }()
- go func() { testChainForkLightB = testChainBase.makeFork(forkLen, false, 2); wg.Done() }()
- go func() { testChainForkHeavy = testChainBase.makeFork(forkLen, true, 3); wg.Done() }()
- wg.Wait()
-
- // Generate the test peers used by the tests to avoid overloading during testing.
- // These seemingly random chains are used in various downloader tests. We're just
- // pre-generating them here.
- chains := []*testChain{
- testChainBase,
- testChainForkLightA,
- testChainForkLightB,
- testChainForkHeavy,
- testChainBase.shorten(1),
- testChainBase.shorten(blockCacheMaxItems - 15),
- testChainBase.shorten((blockCacheMaxItems - 15) / 2),
- testChainBase.shorten(blockCacheMaxItems - 15 - 5),
- testChainBase.shorten(MaxHeaderFetch),
- testChainBase.shorten(800),
- testChainBase.shorten(800 / 2),
- testChainBase.shorten(800 / 3),
- testChainBase.shorten(800 / 4),
- testChainBase.shorten(800 / 5),
- testChainBase.shorten(800 / 6),
- testChainBase.shorten(800 / 7),
- testChainBase.shorten(800 / 8),
- testChainBase.shorten(3*fsHeaderSafetyNet + 256 + fsMinFullBlocks),
- testChainBase.shorten(fsMinFullBlocks + 256 - 1),
- testChainForkLightA.shorten(len(testChainBase.blocks) + 80),
- testChainForkLightB.shorten(len(testChainBase.blocks) + 81),
- testChainForkLightA.shorten(len(testChainBase.blocks) + MaxHeaderFetch),
- testChainForkLightB.shorten(len(testChainBase.blocks) + MaxHeaderFetch),
- testChainForkHeavy.shorten(len(testChainBase.blocks) + 79),
- }
- wg.Add(len(chains))
- for _, chain := range chains {
- go func(blocks []*types.Block) {
- newTestBlockchain(blocks)
- wg.Done()
- }(chain.blocks[1:])
- }
- wg.Wait()
-
- // Mark the chains pregenerated. Generating a new one will lead to a panic.
- pregenerated = true
-}
-
-type testChain struct {
- blocks []*types.Block
-}
-
-// newTestChain creates a blockchain of the given length.
-func newTestChain(length int, genesis *types.Block) *testChain {
- tc := &testChain{
- blocks: []*types.Block{genesis},
- }
- tc.generate(length-1, 0, genesis, false)
- return tc
-}
-
-// makeFork creates a fork on top of the test chain.
-func (tc *testChain) makeFork(length int, heavy bool, seed byte) *testChain {
- fork := tc.copy(len(tc.blocks) + length)
- fork.generate(length, seed, tc.blocks[len(tc.blocks)-1], heavy)
- return fork
-}
-
-// shorten creates a copy of the chain with the given length. It panics if the
-// length is longer than the number of available blocks.
-func (tc *testChain) shorten(length int) *testChain {
- if length > len(tc.blocks) {
- panic(fmt.Errorf("can't shorten test chain to %d blocks, it's only %d blocks long", length, len(tc.blocks)))
- }
- return tc.copy(length)
-}
-
-func (tc *testChain) copy(newlen int) *testChain {
- if newlen > len(tc.blocks) {
- newlen = len(tc.blocks)
- }
- cpy := &testChain{
- blocks: append([]*types.Block{}, tc.blocks[:newlen]...),
- }
- return cpy
-}
-
-// generate creates a chain of n blocks starting at and including parent.
-// the returned hash chain is ordered head->parent. In addition, every 22th block
-// contains a transaction and every 5th an uncle to allow testing correct block
-// reassembly.
-func (tc *testChain) generate(n int, seed byte, parent *types.Block, heavy bool) {
- blocks, _ := core.GenerateChain(testGspec.Config, parent, ethash.NewFaker(), testDB, n, func(i int, block *core.BlockGen) {
- block.SetCoinbase(common.Address{seed})
- // If a heavy chain is requested, delay blocks to raise difficulty
- if heavy {
- block.OffsetTime(-9)
- }
- // Include transactions to the miner to make blocks more interesting.
- if parent == tc.blocks[0] && i%22 == 0 {
- signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
- tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
- if err != nil {
- panic(err)
- }
- block.AddTx(tx)
- }
- // if the block number is a multiple of 5, add a bonus uncle to the block
- if i > 0 && i%5 == 0 {
- block.AddUncle(&types.Header{
- ParentHash: block.PrevBlock(i - 2).Hash(),
- Number: big.NewInt(block.Number().Int64() - 1),
- })
- }
- })
- tc.blocks = append(tc.blocks, blocks...)
-}
-
-var (
- testBlockchains = make(map[common.Hash]*testBlockchain)
- testBlockchainsLock sync.Mutex
-)
-
-type testBlockchain struct {
- chain *core.BlockChain
- gen sync.Once
-}
-
-// newTestBlockchain creates a blockchain database built by running the given blocks,
-// either actually running them, or reusing a previously created one. The returned
-// chains are *shared*, so *do not* mutate them.
-func newTestBlockchain(blocks []*types.Block) *core.BlockChain {
- // Retrieve an existing database, or create a new one
- head := testGenesis.Hash()
- if len(blocks) > 0 {
- head = blocks[len(blocks)-1].Hash()
- }
- testBlockchainsLock.Lock()
- if _, ok := testBlockchains[head]; !ok {
- testBlockchains[head] = new(testBlockchain)
- }
- tbc := testBlockchains[head]
- testBlockchainsLock.Unlock()
-
- // Ensure that the database is generated
- tbc.gen.Do(func() {
- if pregenerated {
- panic("Requested chain generation outside of init")
- }
- chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), nil, testGspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
- if err != nil {
- panic(err)
- }
- if n, err := chain.InsertChain(blocks); err != nil {
- panic(fmt.Sprintf("block %d: %v", n, err))
- }
- tbc.chain = chain
- })
- return tbc.chain
-}
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
deleted file mode 100644
index ad664afb5b..0000000000
--- a/eth/ethconfig/config.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2021 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 ethconfig contains the configuration of the ETH and LES protocols.
-package ethconfig
-
-import (
- "errors"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/beacon"
- "github.com/ethereum/go-ethereum/consensus/clique"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/txpool/blobpool"
- "github.com/ethereum/go-ethereum/core/txpool/legacypool"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/params"
-)
-
-// FullNodeGPO contains default gasprice oracle settings for full node.
-var FullNodeGPO = gasprice.Config{
- Blocks: 20,
- Percentile: 60,
- MaxHeaderHistory: 1024,
- MaxBlockHistory: 1024,
- MaxPrice: gasprice.DefaultMaxPrice,
- IgnorePrice: gasprice.DefaultIgnorePrice,
-}
-
-// Defaults contains default settings for use on the Ethereum main net.
-var Defaults = Config{
- SyncMode: downloader.SnapSync,
- NetworkId: 0, // enable auto configuration of networkID == chainID
- TxLookupLimit: 2350000,
- TransactionHistory: 2350000,
- StateHistory: params.FullImmutabilityThreshold,
- LightPeers: 100,
- DatabaseCache: 512,
- TrieCleanCache: 154,
- TrieDirtyCache: 256,
- TrieTimeout: 60 * time.Minute,
- SnapshotCache: 102,
- FilterLogCacheSize: 32,
- Miner: miner.DefaultConfig,
- TxPool: legacypool.DefaultConfig,
- BlobPool: blobpool.DefaultConfig,
- RPCGasCap: 50000000,
- RPCEVMTimeout: 5 * time.Second,
- GPO: FullNodeGPO,
- RPCTxFeeCap: 1, // 1 ether
-}
-
-//go:generate go run github.com/fjl/gencodec -type Config -formats toml -out gen_config.go
-
-// Config contains configuration options for ETH and LES protocols.
-type Config struct {
- // The genesis block, which is inserted if the database is empty.
- // If nil, the Ethereum main net block is used.
- Genesis *core.Genesis `toml:",omitempty"`
-
- // Network ID separates blockchains on the peer-to-peer networking level. When left
- // zero, the chain ID is used as network ID.
- NetworkId uint64
- SyncMode downloader.SyncMode
-
- // This can be set to list of enrtree:// URLs which will be queried for
- // for nodes to connect to.
- EthDiscoveryURLs []string
- SnapDiscoveryURLs []string
-
- NoPruning bool // Whether to disable pruning and flush everything to disk
- NoPrefetch bool // Whether to disable prefetching and only load state on demand
-
- // Deprecated, use 'TransactionHistory' instead.
- TxLookupLimit uint64 `toml:",omitempty"` // The maximum number of blocks from head whose tx indices are reserved.
- TransactionHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head whose tx indices are reserved.
- StateHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head whose state histories are reserved.
-
- // State scheme represents the scheme used to store ethereum states and trie
- // nodes on top. It can be 'hash', 'path', or none which means use the scheme
- // consistent with persistent state.
- StateScheme string `toml:",omitempty"`
-
- // RequiredBlocks is a set of block number -> hash mappings which must be in the
- // canonical chain of all remote peers. Setting the option makes geth verify the
- // presence of these blocks for every new peer connection.
- RequiredBlocks map[uint64]common.Hash `toml:"-"`
-
- // Light client options
- LightServ int `toml:",omitempty"` // Maximum percentage of time allowed for serving LES requests
- LightIngress int `toml:",omitempty"` // Incoming bandwidth limit for light servers
- LightEgress int `toml:",omitempty"` // Outgoing bandwidth limit for light servers
- LightPeers int `toml:",omitempty"` // Maximum number of LES client peers
- LightNoPrune bool `toml:",omitempty"` // Whether to disable light chain pruning
- LightNoSyncServe bool `toml:",omitempty"` // Whether to serve light clients before syncing
-
- // Database options
- SkipBcVersionCheck bool `toml:"-"`
- DatabaseHandles int `toml:"-"`
- DatabaseCache int
- DatabaseFreezer string
-
- TrieCleanCache int
- TrieDirtyCache int
- TrieTimeout time.Duration
- SnapshotCache int
- Preimages bool
-
- // This is the number of blocks for which logs will be cached in the filter system.
- FilterLogCacheSize int
-
- // Mining options
- Miner miner.Config
-
- // Transaction pool options
- TxPool legacypool.Config
- BlobPool blobpool.Config
-
- // Gas Price Oracle options
- GPO gasprice.Config
-
- // Enables tracking of SHA3 preimages in the VM
- EnablePreimageRecording bool
-
- // Miscellaneous options
- DocRoot string `toml:"-"`
-
- // RPCGasCap is the global gas cap for eth-call variants.
- RPCGasCap uint64
-
- // RPCEVMTimeout is the global timeout for eth-call.
- RPCEVMTimeout time.Duration
-
- // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for
- // send-transaction variants. The unit is ether.
- RPCTxFeeCap float64
-
- // OverrideCancun (TODO: remove after the fork)
- OverrideCancun *uint64 `toml:",omitempty"`
-
- // OverrideVerkle (TODO: remove after the fork)
- OverrideVerkle *uint64 `toml:",omitempty"`
-}
-
-// CreateConsensusEngine creates a consensus engine for the given chain config.
-// Clique is allowed for now to live standalone, but ethash is forbidden and can
-// only exist on already merged networks.
-func CreateConsensusEngine(config *params.ChainConfig, db ethdb.Database) (consensus.Engine, error) {
- // If proof-of-authority is requested, set it up
- if config.Clique != nil {
- return beacon.New(clique.New(config.Clique, db)), nil
- }
- // If defaulting to proof-of-work, enforce an already merged network since
- // we cannot run PoW algorithms anymore, so we cannot even follow a chain
- // not coordinated by a beacon node.
- if !config.TerminalTotalDifficultyPassed {
- return nil, errors.New("ethash is only supported as a historical component of already merged networks")
- }
- return beacon.New(ethash.NewFaker()), nil
-}
diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go
deleted file mode 100644
index 2abddc9e0d..0000000000
--- a/eth/ethconfig/gen_config.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package ethconfig
-
-import (
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/txpool/blobpool"
- "github.com/ethereum/go-ethereum/core/txpool/legacypool"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/miner"
-)
-
-// MarshalTOML marshals as TOML.
-func (c Config) MarshalTOML() (interface{}, error) {
- type Config struct {
- Genesis *core.Genesis `toml:",omitempty"`
- NetworkId uint64
- SyncMode downloader.SyncMode
- EthDiscoveryURLs []string
- SnapDiscoveryURLs []string
- NoPruning bool
- NoPrefetch bool
- TxLookupLimit uint64 `toml:",omitempty"`
- TransactionHistory uint64 `toml:",omitempty"`
- StateHistory uint64 `toml:",omitempty"`
- StateScheme string `toml:",omitempty"`
- RequiredBlocks map[uint64]common.Hash `toml:"-"`
- LightServ int `toml:",omitempty"`
- LightIngress int `toml:",omitempty"`
- LightEgress int `toml:",omitempty"`
- LightPeers int `toml:",omitempty"`
- LightNoPrune bool `toml:",omitempty"`
- LightNoSyncServe bool `toml:",omitempty"`
- SkipBcVersionCheck bool `toml:"-"`
- DatabaseHandles int `toml:"-"`
- DatabaseCache int
- DatabaseFreezer string
- TrieCleanCache int
- TrieDirtyCache int
- TrieTimeout time.Duration
- SnapshotCache int
- Preimages bool
- FilterLogCacheSize int
- Miner miner.Config
- TxPool legacypool.Config
- BlobPool blobpool.Config
- GPO gasprice.Config
- EnablePreimageRecording bool
- DocRoot string `toml:"-"`
- RPCGasCap uint64
- RPCEVMTimeout time.Duration
- RPCTxFeeCap float64
- OverrideCancun *uint64 `toml:",omitempty"`
- OverrideVerkle *uint64 `toml:",omitempty"`
- }
- var enc Config
- enc.Genesis = c.Genesis
- enc.NetworkId = c.NetworkId
- enc.SyncMode = c.SyncMode
- enc.EthDiscoveryURLs = c.EthDiscoveryURLs
- enc.SnapDiscoveryURLs = c.SnapDiscoveryURLs
- enc.NoPruning = c.NoPruning
- enc.NoPrefetch = c.NoPrefetch
- enc.TxLookupLimit = c.TxLookupLimit
- enc.TransactionHistory = c.TransactionHistory
- enc.StateHistory = c.StateHistory
- enc.StateScheme = c.StateScheme
- enc.RequiredBlocks = c.RequiredBlocks
- enc.LightServ = c.LightServ
- enc.LightIngress = c.LightIngress
- enc.LightEgress = c.LightEgress
- enc.LightPeers = c.LightPeers
- enc.LightNoPrune = c.LightNoPrune
- enc.LightNoSyncServe = c.LightNoSyncServe
- enc.SkipBcVersionCheck = c.SkipBcVersionCheck
- enc.DatabaseHandles = c.DatabaseHandles
- enc.DatabaseCache = c.DatabaseCache
- enc.DatabaseFreezer = c.DatabaseFreezer
- enc.TrieCleanCache = c.TrieCleanCache
- enc.TrieDirtyCache = c.TrieDirtyCache
- enc.TrieTimeout = c.TrieTimeout
- enc.SnapshotCache = c.SnapshotCache
- enc.Preimages = c.Preimages
- enc.FilterLogCacheSize = c.FilterLogCacheSize
- enc.Miner = c.Miner
- enc.TxPool = c.TxPool
- enc.BlobPool = c.BlobPool
- enc.GPO = c.GPO
- enc.EnablePreimageRecording = c.EnablePreimageRecording
- enc.DocRoot = c.DocRoot
- enc.RPCGasCap = c.RPCGasCap
- enc.RPCEVMTimeout = c.RPCEVMTimeout
- enc.RPCTxFeeCap = c.RPCTxFeeCap
- enc.OverrideCancun = c.OverrideCancun
- enc.OverrideVerkle = c.OverrideVerkle
- return &enc, nil
-}
-
-// UnmarshalTOML unmarshals from TOML.
-func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
- type Config struct {
- Genesis *core.Genesis `toml:",omitempty"`
- NetworkId *uint64
- SyncMode *downloader.SyncMode
- EthDiscoveryURLs []string
- SnapDiscoveryURLs []string
- NoPruning *bool
- NoPrefetch *bool
- TxLookupLimit *uint64 `toml:",omitempty"`
- TransactionHistory *uint64 `toml:",omitempty"`
- StateHistory *uint64 `toml:",omitempty"`
- StateScheme *string `toml:",omitempty"`
- RequiredBlocks map[uint64]common.Hash `toml:"-"`
- LightServ *int `toml:",omitempty"`
- LightIngress *int `toml:",omitempty"`
- LightEgress *int `toml:",omitempty"`
- LightPeers *int `toml:",omitempty"`
- LightNoPrune *bool `toml:",omitempty"`
- LightNoSyncServe *bool `toml:",omitempty"`
- SkipBcVersionCheck *bool `toml:"-"`
- DatabaseHandles *int `toml:"-"`
- DatabaseCache *int
- DatabaseFreezer *string
- TrieCleanCache *int
- TrieDirtyCache *int
- TrieTimeout *time.Duration
- SnapshotCache *int
- Preimages *bool
- FilterLogCacheSize *int
- Miner *miner.Config
- TxPool *legacypool.Config
- BlobPool *blobpool.Config
- GPO *gasprice.Config
- EnablePreimageRecording *bool
- DocRoot *string `toml:"-"`
- RPCGasCap *uint64
- RPCEVMTimeout *time.Duration
- RPCTxFeeCap *float64
- OverrideCancun *uint64 `toml:",omitempty"`
- OverrideVerkle *uint64 `toml:",omitempty"`
- }
- var dec Config
- if err := unmarshal(&dec); err != nil {
- return err
- }
- if dec.Genesis != nil {
- c.Genesis = dec.Genesis
- }
- if dec.NetworkId != nil {
- c.NetworkId = *dec.NetworkId
- }
- if dec.SyncMode != nil {
- c.SyncMode = *dec.SyncMode
- }
- if dec.EthDiscoveryURLs != nil {
- c.EthDiscoveryURLs = dec.EthDiscoveryURLs
- }
- if dec.SnapDiscoveryURLs != nil {
- c.SnapDiscoveryURLs = dec.SnapDiscoveryURLs
- }
- if dec.NoPruning != nil {
- c.NoPruning = *dec.NoPruning
- }
- if dec.NoPrefetch != nil {
- c.NoPrefetch = *dec.NoPrefetch
- }
- if dec.TxLookupLimit != nil {
- c.TxLookupLimit = *dec.TxLookupLimit
- }
- if dec.TransactionHistory != nil {
- c.TransactionHistory = *dec.TransactionHistory
- }
- if dec.StateHistory != nil {
- c.StateHistory = *dec.StateHistory
- }
- if dec.StateScheme != nil {
- c.StateScheme = *dec.StateScheme
- }
- if dec.RequiredBlocks != nil {
- c.RequiredBlocks = dec.RequiredBlocks
- }
- if dec.LightServ != nil {
- c.LightServ = *dec.LightServ
- }
- if dec.LightIngress != nil {
- c.LightIngress = *dec.LightIngress
- }
- if dec.LightEgress != nil {
- c.LightEgress = *dec.LightEgress
- }
- if dec.LightPeers != nil {
- c.LightPeers = *dec.LightPeers
- }
- if dec.LightNoPrune != nil {
- c.LightNoPrune = *dec.LightNoPrune
- }
- if dec.LightNoSyncServe != nil {
- c.LightNoSyncServe = *dec.LightNoSyncServe
- }
- if dec.SkipBcVersionCheck != nil {
- c.SkipBcVersionCheck = *dec.SkipBcVersionCheck
- }
- if dec.DatabaseHandles != nil {
- c.DatabaseHandles = *dec.DatabaseHandles
- }
- if dec.DatabaseCache != nil {
- c.DatabaseCache = *dec.DatabaseCache
- }
- if dec.DatabaseFreezer != nil {
- c.DatabaseFreezer = *dec.DatabaseFreezer
- }
- if dec.TrieCleanCache != nil {
- c.TrieCleanCache = *dec.TrieCleanCache
- }
- if dec.TrieDirtyCache != nil {
- c.TrieDirtyCache = *dec.TrieDirtyCache
- }
- if dec.TrieTimeout != nil {
- c.TrieTimeout = *dec.TrieTimeout
- }
- if dec.SnapshotCache != nil {
- c.SnapshotCache = *dec.SnapshotCache
- }
- if dec.Preimages != nil {
- c.Preimages = *dec.Preimages
- }
- if dec.FilterLogCacheSize != nil {
- c.FilterLogCacheSize = *dec.FilterLogCacheSize
- }
- if dec.Miner != nil {
- c.Miner = *dec.Miner
- }
- if dec.TxPool != nil {
- c.TxPool = *dec.TxPool
- }
- if dec.BlobPool != nil {
- c.BlobPool = *dec.BlobPool
- }
- if dec.GPO != nil {
- c.GPO = *dec.GPO
- }
- if dec.EnablePreimageRecording != nil {
- c.EnablePreimageRecording = *dec.EnablePreimageRecording
- }
- if dec.DocRoot != nil {
- c.DocRoot = *dec.DocRoot
- }
- if dec.RPCGasCap != nil {
- c.RPCGasCap = *dec.RPCGasCap
- }
- if dec.RPCEVMTimeout != nil {
- c.RPCEVMTimeout = *dec.RPCEVMTimeout
- }
- if dec.RPCTxFeeCap != nil {
- c.RPCTxFeeCap = *dec.RPCTxFeeCap
- }
- if dec.OverrideCancun != nil {
- c.OverrideCancun = dec.OverrideCancun
- }
- if dec.OverrideVerkle != nil {
- c.OverrideVerkle = dec.OverrideVerkle
- }
- return nil
-}
diff --git a/eth/fetcher/block_fetcher.go b/eth/fetcher/block_fetcher.go
deleted file mode 100644
index 126eaaea7f..0000000000
--- a/eth/fetcher/block_fetcher.go
+++ /dev/null
@@ -1,939 +0,0 @@
-// Copyright 2015 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 fetcher contains the announcement based header, blocks or transaction synchronisation.
-package fetcher
-
-import (
- "errors"
- "math/rand"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/prque"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-const (
- lightTimeout = time.Millisecond // Time allowance before an announced header is explicitly requested
- arriveTimeout = 500 * time.Millisecond // Time allowance before an announced block/transaction is explicitly requested
- gatherSlack = 100 * time.Millisecond // Interval used to collate almost-expired announces with fetches
- fetchTimeout = 5 * time.Second // Maximum allotted time to return an explicitly requested block/transaction
-)
-
-const (
- maxUncleDist = 7 // Maximum allowed backward distance from the chain head
- maxQueueDist = 32 // Maximum allowed distance from the chain head to queue
- hashLimit = 256 // Maximum number of unique blocks or headers a peer may have announced
- blockLimit = 64 // Maximum number of unique blocks a peer may have delivered
-)
-
-var (
- blockAnnounceInMeter = metrics.NewRegisteredMeter("eth/fetcher/block/announces/in", nil)
- blockAnnounceOutTimer = metrics.NewRegisteredTimer("eth/fetcher/block/announces/out", nil)
- blockAnnounceDropMeter = metrics.NewRegisteredMeter("eth/fetcher/block/announces/drop", nil)
- blockAnnounceDOSMeter = metrics.NewRegisteredMeter("eth/fetcher/block/announces/dos", nil)
-
- blockBroadcastInMeter = metrics.NewRegisteredMeter("eth/fetcher/block/broadcasts/in", nil)
- blockBroadcastOutTimer = metrics.NewRegisteredTimer("eth/fetcher/block/broadcasts/out", nil)
- blockBroadcastDropMeter = metrics.NewRegisteredMeter("eth/fetcher/block/broadcasts/drop", nil)
- blockBroadcastDOSMeter = metrics.NewRegisteredMeter("eth/fetcher/block/broadcasts/dos", nil)
-
- headerFetchMeter = metrics.NewRegisteredMeter("eth/fetcher/block/headers", nil)
- bodyFetchMeter = metrics.NewRegisteredMeter("eth/fetcher/block/bodies", nil)
-
- headerFilterInMeter = metrics.NewRegisteredMeter("eth/fetcher/block/filter/headers/in", nil)
- headerFilterOutMeter = metrics.NewRegisteredMeter("eth/fetcher/block/filter/headers/out", nil)
- bodyFilterInMeter = metrics.NewRegisteredMeter("eth/fetcher/block/filter/bodies/in", nil)
- bodyFilterOutMeter = metrics.NewRegisteredMeter("eth/fetcher/block/filter/bodies/out", nil)
-)
-
-var errTerminated = errors.New("terminated")
-
-// HeaderRetrievalFn is a callback type for retrieving a header from the local chain.
-type HeaderRetrievalFn func(common.Hash) *types.Header
-
-// blockRetrievalFn is a callback type for retrieving a block from the local chain.
-type blockRetrievalFn func(common.Hash) *types.Block
-
-// headerRequesterFn is a callback type for sending a header retrieval request.
-type headerRequesterFn func(common.Hash, chan *eth.Response) (*eth.Request, error)
-
-// bodyRequesterFn is a callback type for sending a body retrieval request.
-type bodyRequesterFn func([]common.Hash, chan *eth.Response) (*eth.Request, error)
-
-// headerVerifierFn is a callback type to verify a block's header for fast propagation.
-type headerVerifierFn func(header *types.Header) error
-
-// blockBroadcasterFn is a callback type for broadcasting a block to connected peers.
-type blockBroadcasterFn func(block *types.Block, propagate bool)
-
-// chainHeightFn is a callback type to retrieve the current chain height.
-type chainHeightFn func() uint64
-
-// headersInsertFn is a callback type to insert a batch of headers into the local chain.
-type headersInsertFn func(headers []*types.Header) (int, error)
-
-// chainInsertFn is a callback type to insert a batch of blocks into the local chain.
-type chainInsertFn func(types.Blocks) (int, error)
-
-// peerDropFn is a callback type for dropping a peer detected as malicious.
-type peerDropFn func(id string)
-
-// blockAnnounce is the hash notification of the availability of a new block in the
-// network.
-type blockAnnounce struct {
- hash common.Hash // Hash of the block being announced
- number uint64 // Number of the block being announced (0 = unknown | old protocol)
- header *types.Header // Header of the block partially reassembled (new protocol)
- time time.Time // Timestamp of the announcement
-
- origin string // Identifier of the peer originating the notification
-
- fetchHeader headerRequesterFn // Fetcher function to retrieve the header of an announced block
- fetchBodies bodyRequesterFn // Fetcher function to retrieve the body of an announced block
-}
-
-// headerFilterTask represents a batch of headers needing fetcher filtering.
-type headerFilterTask struct {
- peer string // The source peer of block headers
- headers []*types.Header // Collection of headers to filter
- time time.Time // Arrival time of the headers
-}
-
-// bodyFilterTask represents a batch of block bodies (transactions and uncles)
-// needing fetcher filtering.
-type bodyFilterTask struct {
- peer string // The source peer of block bodies
- transactions [][]*types.Transaction // Collection of transactions per block bodies
- uncles [][]*types.Header // Collection of uncles per block bodies
- time time.Time // Arrival time of the blocks' contents
-}
-
-// blockOrHeaderInject represents a schedules import operation.
-type blockOrHeaderInject struct {
- origin string
-
- header *types.Header // Used for light mode fetcher which only cares about header.
- block *types.Block // Used for normal mode fetcher which imports full block.
-}
-
-// number returns the block number of the injected object.
-func (inject *blockOrHeaderInject) number() uint64 {
- if inject.header != nil {
- return inject.header.Number.Uint64()
- }
- return inject.block.NumberU64()
-}
-
-// number returns the block hash of the injected object.
-func (inject *blockOrHeaderInject) hash() common.Hash {
- if inject.header != nil {
- return inject.header.Hash()
- }
- return inject.block.Hash()
-}
-
-// BlockFetcher is responsible for accumulating block announcements from various peers
-// and scheduling them for retrieval.
-type BlockFetcher struct {
- light bool // The indicator whether it's a light fetcher or normal one.
-
- // Various event channels
- notify chan *blockAnnounce
- inject chan *blockOrHeaderInject
-
- headerFilter chan chan *headerFilterTask
- bodyFilter chan chan *bodyFilterTask
-
- done chan common.Hash
- quit chan struct{}
-
- // Announce states
- announces map[string]int // Per peer blockAnnounce counts to prevent memory exhaustion
- announced map[common.Hash][]*blockAnnounce // Announced blocks, scheduled for fetching
- fetching map[common.Hash]*blockAnnounce // Announced blocks, currently fetching
- fetched map[common.Hash][]*blockAnnounce // Blocks with headers fetched, scheduled for body retrieval
- completing map[common.Hash]*blockAnnounce // Blocks with headers, currently body-completing
-
- // Block cache
- queue *prque.Prque[int64, *blockOrHeaderInject] // Queue containing the import operations (block number sorted)
- queues map[string]int // Per peer block counts to prevent memory exhaustion
- queued map[common.Hash]*blockOrHeaderInject // Set of already queued blocks (to dedup imports)
-
- // Callbacks
- getHeader HeaderRetrievalFn // Retrieves a header from the local chain
- getBlock blockRetrievalFn // Retrieves a block from the local chain
- verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work
- broadcastBlock blockBroadcasterFn // Broadcasts a block to connected peers
- chainHeight chainHeightFn // Retrieves the current chain's height
- insertHeaders headersInsertFn // Injects a batch of headers into the chain
- insertChain chainInsertFn // Injects a batch of blocks into the chain
- dropPeer peerDropFn // Drops a peer for misbehaving
-
- // Testing hooks
- announceChangeHook func(common.Hash, bool) // Method to call upon adding or deleting a hash from the blockAnnounce list
- queueChangeHook func(common.Hash, bool) // Method to call upon adding or deleting a block from the import queue
- fetchingHook func([]common.Hash) // Method to call upon starting a block (eth/61) or header (eth/62) fetch
- completingHook func([]common.Hash) // Method to call upon starting a block body fetch (eth/62)
- importedHook func(*types.Header, *types.Block) // Method to call upon successful header or block import (both eth/61 and eth/62)
-}
-
-// NewBlockFetcher creates a block fetcher to retrieve blocks based on hash announcements.
-func NewBlockFetcher(light bool, getHeader HeaderRetrievalFn, getBlock blockRetrievalFn, verifyHeader headerVerifierFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertHeaders headersInsertFn, insertChain chainInsertFn, dropPeer peerDropFn) *BlockFetcher {
- return &BlockFetcher{
- light: light,
- notify: make(chan *blockAnnounce),
- inject: make(chan *blockOrHeaderInject),
- headerFilter: make(chan chan *headerFilterTask),
- bodyFilter: make(chan chan *bodyFilterTask),
- done: make(chan common.Hash),
- quit: make(chan struct{}),
- announces: make(map[string]int),
- announced: make(map[common.Hash][]*blockAnnounce),
- fetching: make(map[common.Hash]*blockAnnounce),
- fetched: make(map[common.Hash][]*blockAnnounce),
- completing: make(map[common.Hash]*blockAnnounce),
- queue: prque.New[int64, *blockOrHeaderInject](nil),
- queues: make(map[string]int),
- queued: make(map[common.Hash]*blockOrHeaderInject),
- getHeader: getHeader,
- getBlock: getBlock,
- verifyHeader: verifyHeader,
- broadcastBlock: broadcastBlock,
- chainHeight: chainHeight,
- insertHeaders: insertHeaders,
- insertChain: insertChain,
- dropPeer: dropPeer,
- }
-}
-
-// Start boots up the announcement based synchroniser, accepting and processing
-// hash notifications and block fetches until termination requested.
-func (f *BlockFetcher) Start() {
- go f.loop()
-}
-
-// Stop terminates the announcement based synchroniser, canceling all pending
-// operations.
-func (f *BlockFetcher) Stop() {
- close(f.quit)
-}
-
-// Notify announces the fetcher of the potential availability of a new block in
-// the network.
-func (f *BlockFetcher) Notify(peer string, hash common.Hash, number uint64, time time.Time,
- headerFetcher headerRequesterFn, bodyFetcher bodyRequesterFn) error {
- block := &blockAnnounce{
- hash: hash,
- number: number,
- time: time,
- origin: peer,
- fetchHeader: headerFetcher,
- fetchBodies: bodyFetcher,
- }
- select {
- case f.notify <- block:
- return nil
- case <-f.quit:
- return errTerminated
- }
-}
-
-// Enqueue tries to fill gaps the fetcher's future import queue.
-func (f *BlockFetcher) Enqueue(peer string, block *types.Block) error {
- op := &blockOrHeaderInject{
- origin: peer,
- block: block,
- }
- select {
- case f.inject <- op:
- return nil
- case <-f.quit:
- return errTerminated
- }
-}
-
-// FilterHeaders extracts all the headers that were explicitly requested by the fetcher,
-// returning those that should be handled differently.
-func (f *BlockFetcher) FilterHeaders(peer string, headers []*types.Header, time time.Time) []*types.Header {
- log.Trace("Filtering headers", "peer", peer, "headers", len(headers))
-
- // Send the filter channel to the fetcher
- filter := make(chan *headerFilterTask)
-
- select {
- case f.headerFilter <- filter:
- case <-f.quit:
- return nil
- }
- // Request the filtering of the header list
- select {
- case filter <- &headerFilterTask{peer: peer, headers: headers, time: time}:
- case <-f.quit:
- return nil
- }
- // Retrieve the headers remaining after filtering
- select {
- case task := <-filter:
- return task.headers
- case <-f.quit:
- return nil
- }
-}
-
-// FilterBodies extracts all the block bodies that were explicitly requested by
-// the fetcher, returning those that should be handled differently.
-func (f *BlockFetcher) FilterBodies(peer string, transactions [][]*types.Transaction, uncles [][]*types.Header, time time.Time) ([][]*types.Transaction, [][]*types.Header) {
- log.Trace("Filtering bodies", "peer", peer, "txs", len(transactions), "uncles", len(uncles))
-
- // Send the filter channel to the fetcher
- filter := make(chan *bodyFilterTask)
-
- select {
- case f.bodyFilter <- filter:
- case <-f.quit:
- return nil, nil
- }
- // Request the filtering of the body list
- select {
- case filter <- &bodyFilterTask{peer: peer, transactions: transactions, uncles: uncles, time: time}:
- case <-f.quit:
- return nil, nil
- }
- // Retrieve the bodies remaining after filtering
- select {
- case task := <-filter:
- return task.transactions, task.uncles
- case <-f.quit:
- return nil, nil
- }
-}
-
-// Loop is the main fetcher loop, checking and processing various notification
-// events.
-func (f *BlockFetcher) loop() {
- // Iterate the block fetching until a quit is requested
- var (
- fetchTimer = time.NewTimer(0)
- completeTimer = time.NewTimer(0)
- )
- <-fetchTimer.C // clear out the channel
- <-completeTimer.C
- defer fetchTimer.Stop()
- defer completeTimer.Stop()
-
- for {
- // Clean up any expired block fetches
- for hash, announce := range f.fetching {
- if time.Since(announce.time) > fetchTimeout {
- f.forgetHash(hash)
- }
- }
- // Import any queued blocks that could potentially fit
- height := f.chainHeight()
- for !f.queue.Empty() {
- op := f.queue.PopItem()
- hash := op.hash()
- if f.queueChangeHook != nil {
- f.queueChangeHook(hash, false)
- }
- // If too high up the chain or phase, continue later
- number := op.number()
- if number > height+1 {
- f.queue.Push(op, -int64(number))
- if f.queueChangeHook != nil {
- f.queueChangeHook(hash, true)
- }
- break
- }
- // Otherwise if fresh and still unknown, try and import
- if (number+maxUncleDist < height) || (f.light && f.getHeader(hash) != nil) || (!f.light && f.getBlock(hash) != nil) {
- f.forgetBlock(hash)
- continue
- }
- if f.light {
- f.importHeaders(op.origin, op.header)
- } else {
- f.importBlocks(op.origin, op.block)
- }
- }
- // Wait for an outside event to occur
- select {
- case <-f.quit:
- // BlockFetcher terminating, abort all operations
- return
-
- case notification := <-f.notify:
- // A block was announced, make sure the peer isn't DOSing us
- blockAnnounceInMeter.Mark(1)
-
- count := f.announces[notification.origin] + 1
- if count > hashLimit {
- log.Debug("Peer exceeded outstanding announces", "peer", notification.origin, "limit", hashLimit)
- blockAnnounceDOSMeter.Mark(1)
- break
- }
- if notification.number == 0 {
- break
- }
- // If we have a valid block number, check that it's potentially useful
- if dist := int64(notification.number) - int64(f.chainHeight()); dist < -maxUncleDist || dist > maxQueueDist {
- log.Debug("Peer discarded announcement", "peer", notification.origin, "number", notification.number, "hash", notification.hash, "distance", dist)
- blockAnnounceDropMeter.Mark(1)
- break
- }
- // All is well, schedule the announce if block's not yet downloading
- if _, ok := f.fetching[notification.hash]; ok {
- break
- }
- if _, ok := f.completing[notification.hash]; ok {
- break
- }
- f.announces[notification.origin] = count
- f.announced[notification.hash] = append(f.announced[notification.hash], notification)
- if f.announceChangeHook != nil && len(f.announced[notification.hash]) == 1 {
- f.announceChangeHook(notification.hash, true)
- }
- if len(f.announced) == 1 {
- f.rescheduleFetch(fetchTimer)
- }
-
- case op := <-f.inject:
- // A direct block insertion was requested, try and fill any pending gaps
- blockBroadcastInMeter.Mark(1)
-
- // Now only direct block injection is allowed, drop the header injection
- // here silently if we receive.
- if f.light {
- continue
- }
- f.enqueue(op.origin, nil, op.block)
-
- case hash := <-f.done:
- // A pending import finished, remove all traces of the notification
- f.forgetHash(hash)
- f.forgetBlock(hash)
-
- case <-fetchTimer.C:
- // At least one block's timer ran out, check for needing retrieval
- request := make(map[string][]common.Hash)
-
- for hash, announces := range f.announced {
- // In current LES protocol(les2/les3), only header announce is
- // available, no need to wait too much time for header broadcast.
- timeout := arriveTimeout - gatherSlack
- if f.light {
- timeout = 0
- }
- if time.Since(announces[0].time) > timeout {
- // Pick a random peer to retrieve from, reset all others
- announce := announces[rand.Intn(len(announces))]
- f.forgetHash(hash)
-
- // If the block still didn't arrive, queue for fetching
- if (f.light && f.getHeader(hash) == nil) || (!f.light && f.getBlock(hash) == nil) {
- request[announce.origin] = append(request[announce.origin], hash)
- f.fetching[hash] = announce
- }
- }
- }
- // Send out all block header requests
- for peer, hashes := range request {
- log.Trace("Fetching scheduled headers", "peer", peer, "list", hashes)
-
- // Create a closure of the fetch and schedule in on a new thread
- fetchHeader, hashes := f.fetching[hashes[0]].fetchHeader, hashes
- go func(peer string) {
- if f.fetchingHook != nil {
- f.fetchingHook(hashes)
- }
- for _, hash := range hashes {
- headerFetchMeter.Mark(1)
- go func(hash common.Hash) {
- resCh := make(chan *eth.Response)
-
- req, err := fetchHeader(hash, resCh)
- if err != nil {
- return // Legacy code, yolo
- }
- defer req.Close()
-
- timeout := time.NewTimer(2 * fetchTimeout) // 2x leeway before dropping the peer
- defer timeout.Stop()
-
- select {
- case res := <-resCh:
- res.Done <- nil
- f.FilterHeaders(peer, *res.Res.(*eth.BlockHeadersRequest), time.Now())
-
- case <-timeout.C:
- // The peer didn't respond in time. The request
- // was already rescheduled at this point, we were
- // waiting for a catchup. With an unresponsive
- // peer however, it's a protocol violation.
- f.dropPeer(peer)
- }
- }(hash)
- }
- }(peer)
- }
- // Schedule the next fetch if blocks are still pending
- f.rescheduleFetch(fetchTimer)
-
- case <-completeTimer.C:
- // At least one header's timer ran out, retrieve everything
- request := make(map[string][]common.Hash)
-
- for hash, announces := range f.fetched {
- // Pick a random peer to retrieve from, reset all others
- announce := announces[rand.Intn(len(announces))]
- f.forgetHash(hash)
-
- // If the block still didn't arrive, queue for completion
- if f.getBlock(hash) == nil {
- request[announce.origin] = append(request[announce.origin], hash)
- f.completing[hash] = announce
- }
- }
- // Send out all block body requests
- for peer, hashes := range request {
- log.Trace("Fetching scheduled bodies", "peer", peer, "list", hashes)
-
- // Create a closure of the fetch and schedule in on a new thread
- if f.completingHook != nil {
- f.completingHook(hashes)
- }
- fetchBodies := f.completing[hashes[0]].fetchBodies
- bodyFetchMeter.Mark(int64(len(hashes)))
-
- go func(peer string, hashes []common.Hash) {
- resCh := make(chan *eth.Response)
-
- req, err := fetchBodies(hashes, resCh)
- if err != nil {
- return // Legacy code, yolo
- }
- defer req.Close()
-
- timeout := time.NewTimer(2 * fetchTimeout) // 2x leeway before dropping the peer
- defer timeout.Stop()
-
- select {
- case res := <-resCh:
- res.Done <- nil
- // Ignoring withdrawals here, since the block fetcher is not used post-merge.
- txs, uncles, _ := res.Res.(*eth.BlockBodiesResponse).Unpack()
- f.FilterBodies(peer, txs, uncles, time.Now())
-
- case <-timeout.C:
- // The peer didn't respond in time. The request
- // was already rescheduled at this point, we were
- // waiting for a catchup. With an unresponsive
- // peer however, it's a protocol violation.
- f.dropPeer(peer)
- }
- }(peer, hashes)
- }
- // Schedule the next fetch if blocks are still pending
- f.rescheduleComplete(completeTimer)
-
- case filter := <-f.headerFilter:
- // Headers arrived from a remote peer. Extract those that were explicitly
- // requested by the fetcher, and return everything else so it's delivered
- // to other parts of the system.
- var task *headerFilterTask
- select {
- case task = <-filter:
- case <-f.quit:
- return
- }
- headerFilterInMeter.Mark(int64(len(task.headers)))
-
- // Split the batch of headers into unknown ones (to return to the caller),
- // known incomplete ones (requiring body retrievals) and completed blocks.
- unknown, incomplete, complete, lightHeaders := []*types.Header{}, []*blockAnnounce{}, []*types.Block{}, []*blockAnnounce{}
- for _, header := range task.headers {
- hash := header.Hash()
-
- // Filter fetcher-requested headers from other synchronisation algorithms
- if announce := f.fetching[hash]; announce != nil && announce.origin == task.peer && f.fetched[hash] == nil && f.completing[hash] == nil && f.queued[hash] == nil {
- // If the delivered header does not match the promised number, drop the announcer
- if header.Number.Uint64() != announce.number {
- log.Trace("Invalid block number fetched", "peer", announce.origin, "hash", header.Hash(), "announced", announce.number, "provided", header.Number)
- f.dropPeer(announce.origin)
- f.forgetHash(hash)
- continue
- }
- // Collect all headers only if we are running in light
- // mode and the headers are not imported by other means.
- if f.light {
- if f.getHeader(hash) == nil {
- announce.header = header
- lightHeaders = append(lightHeaders, announce)
- }
- f.forgetHash(hash)
- continue
- }
- // Only keep if not imported by other means
- if f.getBlock(hash) == nil {
- announce.header = header
- announce.time = task.time
-
- // If the block is empty (header only), short circuit into the final import queue
- if header.TxHash == types.EmptyTxsHash && header.UncleHash == types.EmptyUncleHash {
- log.Trace("Block empty, skipping body retrieval", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
-
- block := types.NewBlockWithHeader(header)
- block.ReceivedAt = task.time
-
- complete = append(complete, block)
- f.completing[hash] = announce
- continue
- }
- // Otherwise add to the list of blocks needing completion
- incomplete = append(incomplete, announce)
- } else {
- log.Trace("Block already imported, discarding header", "peer", announce.origin, "number", header.Number, "hash", header.Hash())
- f.forgetHash(hash)
- }
- } else {
- // BlockFetcher doesn't know about it, add to the return list
- unknown = append(unknown, header)
- }
- }
- headerFilterOutMeter.Mark(int64(len(unknown)))
- select {
- case filter <- &headerFilterTask{headers: unknown, time: task.time}:
- case <-f.quit:
- return
- }
- // Schedule the retrieved headers for body completion
- for _, announce := range incomplete {
- hash := announce.header.Hash()
- if _, ok := f.completing[hash]; ok {
- continue
- }
- f.fetched[hash] = append(f.fetched[hash], announce)
- if len(f.fetched) == 1 {
- f.rescheduleComplete(completeTimer)
- }
- }
- // Schedule the header for light fetcher import
- for _, announce := range lightHeaders {
- f.enqueue(announce.origin, announce.header, nil)
- }
- // Schedule the header-only blocks for import
- for _, block := range complete {
- if announce := f.completing[block.Hash()]; announce != nil {
- f.enqueue(announce.origin, nil, block)
- }
- }
-
- case filter := <-f.bodyFilter:
- // Block bodies arrived, extract any explicitly requested blocks, return the rest
- var task *bodyFilterTask
- select {
- case task = <-filter:
- case <-f.quit:
- return
- }
- bodyFilterInMeter.Mark(int64(len(task.transactions)))
- blocks := []*types.Block{}
- // abort early if there's nothing explicitly requested
- if len(f.completing) > 0 {
- for i := 0; i < len(task.transactions) && i < len(task.uncles); i++ {
- // Match up a body to any possible completion request
- var (
- matched = false
- uncleHash common.Hash // calculated lazily and reused
- txnHash common.Hash // calculated lazily and reused
- )
- for hash, announce := range f.completing {
- if f.queued[hash] != nil || announce.origin != task.peer {
- continue
- }
- if uncleHash == (common.Hash{}) {
- uncleHash = types.CalcUncleHash(task.uncles[i])
- }
- if uncleHash != announce.header.UncleHash {
- continue
- }
- if txnHash == (common.Hash{}) {
- txnHash = types.DeriveSha(types.Transactions(task.transactions[i]), trie.NewStackTrie(nil))
- }
- if txnHash != announce.header.TxHash {
- continue
- }
- // Mark the body matched, reassemble if still unknown
- matched = true
- if f.getBlock(hash) == nil {
- block := types.NewBlockWithHeader(announce.header).WithBody(task.transactions[i], task.uncles[i])
- block.ReceivedAt = task.time
- blocks = append(blocks, block)
- } else {
- f.forgetHash(hash)
- }
- }
- if matched {
- task.transactions = append(task.transactions[:i], task.transactions[i+1:]...)
- task.uncles = append(task.uncles[:i], task.uncles[i+1:]...)
- i--
- continue
- }
- }
- }
- bodyFilterOutMeter.Mark(int64(len(task.transactions)))
- select {
- case filter <- task:
- case <-f.quit:
- return
- }
- // Schedule the retrieved blocks for ordered import
- for _, block := range blocks {
- if announce := f.completing[block.Hash()]; announce != nil {
- f.enqueue(announce.origin, nil, block)
- }
- }
- }
- }
-}
-
-// rescheduleFetch resets the specified fetch timer to the next blockAnnounce timeout.
-func (f *BlockFetcher) rescheduleFetch(fetch *time.Timer) {
- // Short circuit if no blocks are announced
- if len(f.announced) == 0 {
- return
- }
- // Schedule announcement retrieval quickly for light mode
- // since server won't send any headers to client.
- if f.light {
- fetch.Reset(lightTimeout)
- return
- }
- // Otherwise find the earliest expiring announcement
- earliest := time.Now()
- for _, announces := range f.announced {
- if earliest.After(announces[0].time) {
- earliest = announces[0].time
- }
- }
- fetch.Reset(arriveTimeout - time.Since(earliest))
-}
-
-// rescheduleComplete resets the specified completion timer to the next fetch timeout.
-func (f *BlockFetcher) rescheduleComplete(complete *time.Timer) {
- // Short circuit if no headers are fetched
- if len(f.fetched) == 0 {
- return
- }
- // Otherwise find the earliest expiring announcement
- earliest := time.Now()
- for _, announces := range f.fetched {
- if earliest.After(announces[0].time) {
- earliest = announces[0].time
- }
- }
- complete.Reset(gatherSlack - time.Since(earliest))
-}
-
-// enqueue schedules a new header or block import operation, if the component
-// to be imported has not yet been seen.
-func (f *BlockFetcher) enqueue(peer string, header *types.Header, block *types.Block) {
- var (
- hash common.Hash
- number uint64
- )
- if header != nil {
- hash, number = header.Hash(), header.Number.Uint64()
- } else {
- hash, number = block.Hash(), block.NumberU64()
- }
- // Ensure the peer isn't DOSing us
- count := f.queues[peer] + 1
- if count > blockLimit {
- log.Debug("Discarded delivered header or block, exceeded allowance", "peer", peer, "number", number, "hash", hash, "limit", blockLimit)
- blockBroadcastDOSMeter.Mark(1)
- f.forgetHash(hash)
- return
- }
- // Discard any past or too distant blocks
- if dist := int64(number) - int64(f.chainHeight()); dist < -maxUncleDist || dist > maxQueueDist {
- log.Debug("Discarded delivered header or block, too far away", "peer", peer, "number", number, "hash", hash, "distance", dist)
- blockBroadcastDropMeter.Mark(1)
- f.forgetHash(hash)
- return
- }
- // Schedule the block for future importing
- if _, ok := f.queued[hash]; !ok {
- op := &blockOrHeaderInject{origin: peer}
- if header != nil {
- op.header = header
- } else {
- op.block = block
- }
- f.queues[peer] = count
- f.queued[hash] = op
- f.queue.Push(op, -int64(number))
- if f.queueChangeHook != nil {
- f.queueChangeHook(hash, true)
- }
- log.Debug("Queued delivered header or block", "peer", peer, "number", number, "hash", hash, "queued", f.queue.Size())
- }
-}
-
-// importHeaders spawns a new goroutine to run a header insertion into the chain.
-// If the header's number is at the same height as the current import phase, it
-// updates the phase states accordingly.
-func (f *BlockFetcher) importHeaders(peer string, header *types.Header) {
- hash := header.Hash()
- log.Debug("Importing propagated header", "peer", peer, "number", header.Number, "hash", hash)
-
- go func() {
- defer func() { f.done <- hash }()
- // If the parent's unknown, abort insertion
- parent := f.getHeader(header.ParentHash)
- if parent == nil {
- log.Debug("Unknown parent of propagated header", "peer", peer, "number", header.Number, "hash", hash, "parent", header.ParentHash)
- return
- }
- // Validate the header and if something went wrong, drop the peer
- if err := f.verifyHeader(header); err != nil && err != consensus.ErrFutureBlock {
- log.Debug("Propagated header verification failed", "peer", peer, "number", header.Number, "hash", hash, "err", err)
- f.dropPeer(peer)
- return
- }
- // Run the actual import and log any issues
- if _, err := f.insertHeaders([]*types.Header{header}); err != nil {
- log.Debug("Propagated header import failed", "peer", peer, "number", header.Number, "hash", hash, "err", err)
- return
- }
- // Invoke the testing hook if needed
- if f.importedHook != nil {
- f.importedHook(header, nil)
- }
- }()
-}
-
-// importBlocks spawns a new goroutine to run a block insertion into the chain. If the
-// block's number is at the same height as the current import phase, it updates
-// the phase states accordingly.
-func (f *BlockFetcher) importBlocks(peer string, block *types.Block) {
- hash := block.Hash()
-
- // Run the import on a new thread
- log.Debug("Importing propagated block", "peer", peer, "number", block.Number(), "hash", hash)
- go func() {
- defer func() { f.done <- hash }()
-
- // If the parent's unknown, abort insertion
- parent := f.getBlock(block.ParentHash())
- if parent == nil {
- log.Debug("Unknown parent of propagated block", "peer", peer, "number", block.Number(), "hash", hash, "parent", block.ParentHash())
- return
- }
- // Quickly validate the header and propagate the block if it passes
- switch err := f.verifyHeader(block.Header()); err {
- case nil:
- // All ok, quickly propagate to our peers
- blockBroadcastOutTimer.UpdateSince(block.ReceivedAt)
- go f.broadcastBlock(block, true)
-
- case consensus.ErrFutureBlock:
- // Weird future block, don't fail, but neither propagate
-
- default:
- // Something went very wrong, drop the peer
- log.Debug("Propagated block verification failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
- f.dropPeer(peer)
- return
- }
- // Run the actual import and log any issues
- if _, err := f.insertChain(types.Blocks{block}); err != nil {
- log.Debug("Propagated block import failed", "peer", peer, "number", block.Number(), "hash", hash, "err", err)
- return
- }
- // If import succeeded, broadcast the block
- blockAnnounceOutTimer.UpdateSince(block.ReceivedAt)
- go f.broadcastBlock(block, false)
-
- // Invoke the testing hook if needed
- if f.importedHook != nil {
- f.importedHook(nil, block)
- }
- }()
-}
-
-// forgetHash removes all traces of a block announcement from the fetcher's
-// internal state.
-func (f *BlockFetcher) forgetHash(hash common.Hash) {
- // Remove all pending announces and decrement DOS counters
- if announceMap, ok := f.announced[hash]; ok {
- for _, announce := range announceMap {
- f.announces[announce.origin]--
- if f.announces[announce.origin] <= 0 {
- delete(f.announces, announce.origin)
- }
- }
- delete(f.announced, hash)
- if f.announceChangeHook != nil {
- f.announceChangeHook(hash, false)
- }
- }
- // Remove any pending fetches and decrement the DOS counters
- if announce := f.fetching[hash]; announce != nil {
- f.announces[announce.origin]--
- if f.announces[announce.origin] <= 0 {
- delete(f.announces, announce.origin)
- }
- delete(f.fetching, hash)
- }
-
- // Remove any pending completion requests and decrement the DOS counters
- for _, announce := range f.fetched[hash] {
- f.announces[announce.origin]--
- if f.announces[announce.origin] <= 0 {
- delete(f.announces, announce.origin)
- }
- }
- delete(f.fetched, hash)
-
- // Remove any pending completions and decrement the DOS counters
- if announce := f.completing[hash]; announce != nil {
- f.announces[announce.origin]--
- if f.announces[announce.origin] <= 0 {
- delete(f.announces, announce.origin)
- }
- delete(f.completing, hash)
- }
-}
-
-// forgetBlock removes all traces of a queued block from the fetcher's internal
-// state.
-func (f *BlockFetcher) forgetBlock(hash common.Hash) {
- if insert := f.queued[hash]; insert != nil {
- f.queues[insert.origin]--
- if f.queues[insert.origin] == 0 {
- delete(f.queues, insert.origin)
- }
- delete(f.queued, hash)
- }
-}
diff --git a/eth/fetcher/block_fetcher_test.go b/eth/fetcher/block_fetcher_test.go
deleted file mode 100644
index 6927300b1d..0000000000
--- a/eth/fetcher/block_fetcher_test.go
+++ /dev/null
@@ -1,948 +0,0 @@
-// Copyright 2015 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 fetcher
-
-import (
- "errors"
- "math/big"
- "sync"
- "sync/atomic"
- "testing"
- "time"
-
- "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/crypto"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-var (
- testdb = rawdb.NewMemoryDatabase()
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- testAddress = crypto.PubkeyToAddress(testKey.PublicKey)
- gspec = &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{testAddress: {Balance: big.NewInt(1000000000000000)}},
- BaseFee: big.NewInt(params.InitialBaseFee),
- }
- genesis = gspec.MustCommit(testdb, trie.NewDatabase(testdb, trie.HashDefaults))
- unknownBlock = types.NewBlock(&types.Header{Root: types.EmptyRootHash, GasLimit: params.GenesisGasLimit, BaseFee: big.NewInt(params.InitialBaseFee)}, nil, nil, nil, trie.NewStackTrie(nil))
-)
-
-// makeChain creates a chain of n blocks starting at and including parent.
-// the returned hash chain is ordered head->parent. In addition, every 3rd block
-// contains a transaction and every 5th an uncle to allow testing correct block
-// reassembly.
-func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common.Hash]*types.Block) {
- blocks, _ := core.GenerateChain(gspec.Config, parent, ethash.NewFaker(), testdb, n, func(i int, block *core.BlockGen) {
- block.SetCoinbase(common.Address{seed})
-
- // If the block number is multiple of 3, send a bonus transaction to the miner
- if parent == genesis && i%3 == 0 {
- signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp())
- tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey)
- if err != nil {
- panic(err)
- }
- block.AddTx(tx)
- }
- // If the block number is a multiple of 5, add a bonus uncle to the block
- if i > 0 && i%5 == 0 {
- block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 2).Hash(), Number: big.NewInt(int64(i - 1))})
- }
- })
- hashes := make([]common.Hash, n+1)
- hashes[len(hashes)-1] = parent.Hash()
- blockm := make(map[common.Hash]*types.Block, n+1)
- blockm[parent.Hash()] = parent
- for i, b := range blocks {
- hashes[len(hashes)-i-2] = b.Hash()
- blockm[b.Hash()] = b
- }
- return hashes, blockm
-}
-
-// fetcherTester is a test simulator for mocking out local block chain.
-type fetcherTester struct {
- fetcher *BlockFetcher
-
- hashes []common.Hash // Hash chain belonging to the tester
- headers map[common.Hash]*types.Header // Headers belonging to the tester
- blocks map[common.Hash]*types.Block // Blocks belonging to the tester
- drops map[string]bool // Map of peers dropped by the fetcher
-
- lock sync.RWMutex
-}
-
-// newTester creates a new fetcher test mocker.
-func newTester(light bool) *fetcherTester {
- tester := &fetcherTester{
- hashes: []common.Hash{genesis.Hash()},
- headers: map[common.Hash]*types.Header{genesis.Hash(): genesis.Header()},
- blocks: map[common.Hash]*types.Block{genesis.Hash(): genesis},
- drops: make(map[string]bool),
- }
- tester.fetcher = NewBlockFetcher(light, tester.getHeader, tester.getBlock, tester.verifyHeader, tester.broadcastBlock, tester.chainHeight, tester.insertHeaders, tester.insertChain, tester.dropPeer)
- tester.fetcher.Start()
-
- return tester
-}
-
-// getHeader retrieves a header from the tester's block chain.
-func (f *fetcherTester) getHeader(hash common.Hash) *types.Header {
- f.lock.RLock()
- defer f.lock.RUnlock()
-
- return f.headers[hash]
-}
-
-// getBlock retrieves a block from the tester's block chain.
-func (f *fetcherTester) getBlock(hash common.Hash) *types.Block {
- f.lock.RLock()
- defer f.lock.RUnlock()
-
- return f.blocks[hash]
-}
-
-// verifyHeader is a nop placeholder for the block header verification.
-func (f *fetcherTester) verifyHeader(header *types.Header) error {
- return nil
-}
-
-// broadcastBlock is a nop placeholder for the block broadcasting.
-func (f *fetcherTester) broadcastBlock(block *types.Block, propagate bool) {
-}
-
-// chainHeight retrieves the current height (block number) of the chain.
-func (f *fetcherTester) chainHeight() uint64 {
- f.lock.RLock()
- defer f.lock.RUnlock()
-
- if f.fetcher.light {
- return f.headers[f.hashes[len(f.hashes)-1]].Number.Uint64()
- }
- return f.blocks[f.hashes[len(f.hashes)-1]].NumberU64()
-}
-
-// insertChain injects a new headers into the simulated chain.
-func (f *fetcherTester) insertHeaders(headers []*types.Header) (int, error) {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- for i, header := range headers {
- // Make sure the parent in known
- if _, ok := f.headers[header.ParentHash]; !ok {
- return i, errors.New("unknown parent")
- }
- // Discard any new blocks if the same height already exists
- if header.Number.Uint64() <= f.headers[f.hashes[len(f.hashes)-1]].Number.Uint64() {
- return i, nil
- }
- // Otherwise build our current chain
- f.hashes = append(f.hashes, header.Hash())
- f.headers[header.Hash()] = header
- }
- return 0, nil
-}
-
-// insertChain injects a new blocks into the simulated chain.
-func (f *fetcherTester) insertChain(blocks types.Blocks) (int, error) {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- for i, block := range blocks {
- // Make sure the parent in known
- if _, ok := f.blocks[block.ParentHash()]; !ok {
- return i, errors.New("unknown parent")
- }
- // Discard any new blocks if the same height already exists
- if block.NumberU64() <= f.blocks[f.hashes[len(f.hashes)-1]].NumberU64() {
- return i, nil
- }
- // Otherwise build our current chain
- f.hashes = append(f.hashes, block.Hash())
- f.blocks[block.Hash()] = block
- }
- return 0, nil
-}
-
-// dropPeer is an emulator for the peer removal, simply accumulating the various
-// peers dropped by the fetcher.
-func (f *fetcherTester) dropPeer(peer string) {
- f.lock.Lock()
- defer f.lock.Unlock()
-
- f.drops[peer] = true
-}
-
-// makeHeaderFetcher retrieves a block header fetcher associated with a simulated peer.
-func (f *fetcherTester) makeHeaderFetcher(peer string, blocks map[common.Hash]*types.Block, drift time.Duration) headerRequesterFn {
- closure := make(map[common.Hash]*types.Block)
- for hash, block := range blocks {
- closure[hash] = block
- }
- // Create a function that return a header from the closure
- return func(hash common.Hash, sink chan *eth.Response) (*eth.Request, error) {
- // Gather the blocks to return
- headers := make([]*types.Header, 0, 1)
- if block, ok := closure[hash]; ok {
- headers = append(headers, block.Header())
- }
- // Return on a new thread
- req := ð.Request{
- Peer: peer,
- }
- res := ð.Response{
- Req: req,
- Res: (*eth.BlockHeadersRequest)(&headers),
- Time: drift,
- Done: make(chan error, 1), // Ignore the returned status
- }
- go func() {
- sink <- res
- }()
- return req, nil
- }
-}
-
-// makeBodyFetcher retrieves a block body fetcher associated with a simulated peer.
-func (f *fetcherTester) makeBodyFetcher(peer string, blocks map[common.Hash]*types.Block, drift time.Duration) bodyRequesterFn {
- closure := make(map[common.Hash]*types.Block)
- for hash, block := range blocks {
- closure[hash] = block
- }
- // Create a function that returns blocks from the closure
- return func(hashes []common.Hash, sink chan *eth.Response) (*eth.Request, error) {
- // Gather the block bodies to return
- transactions := make([][]*types.Transaction, 0, len(hashes))
- uncles := make([][]*types.Header, 0, len(hashes))
-
- for _, hash := range hashes {
- if block, ok := closure[hash]; ok {
- transactions = append(transactions, block.Transactions())
- uncles = append(uncles, block.Uncles())
- }
- }
- // Return on a new thread
- bodies := make([]*eth.BlockBody, len(transactions))
- for i, txs := range transactions {
- bodies[i] = ð.BlockBody{
- Transactions: txs,
- Uncles: uncles[i],
- }
- }
- req := ð.Request{
- Peer: peer,
- }
- res := ð.Response{
- Req: req,
- Res: (*eth.BlockBodiesResponse)(&bodies),
- Time: drift,
- Done: make(chan error, 1), // Ignore the returned status
- }
- go func() {
- sink <- res
- }()
- return req, nil
- }
-}
-
-// verifyFetchingEvent verifies that one single event arrive on a fetching channel.
-func verifyFetchingEvent(t *testing.T, fetching chan []common.Hash, arrive bool) {
- t.Helper()
-
- if arrive {
- select {
- case <-fetching:
- case <-time.After(time.Second):
- t.Fatalf("fetching timeout")
- }
- } else {
- select {
- case <-fetching:
- t.Fatalf("fetching invoked")
- case <-time.After(10 * time.Millisecond):
- }
- }
-}
-
-// verifyCompletingEvent verifies that one single event arrive on an completing channel.
-func verifyCompletingEvent(t *testing.T, completing chan []common.Hash, arrive bool) {
- t.Helper()
-
- if arrive {
- select {
- case <-completing:
- case <-time.After(time.Second):
- t.Fatalf("completing timeout")
- }
- } else {
- select {
- case <-completing:
- t.Fatalf("completing invoked")
- case <-time.After(10 * time.Millisecond):
- }
- }
-}
-
-// verifyImportEvent verifies that one single event arrive on an import channel.
-func verifyImportEvent(t *testing.T, imported chan interface{}, arrive bool) {
- t.Helper()
-
- if arrive {
- select {
- case <-imported:
- case <-time.After(time.Second):
- t.Fatalf("import timeout")
- }
- } else {
- select {
- case <-imported:
- t.Fatalf("import invoked")
- case <-time.After(20 * time.Millisecond):
- }
- }
-}
-
-// verifyImportCount verifies that exactly count number of events arrive on an
-// import hook channel.
-func verifyImportCount(t *testing.T, imported chan interface{}, count int) {
- t.Helper()
-
- for i := 0; i < count; i++ {
- select {
- case <-imported:
- case <-time.After(time.Second):
- t.Fatalf("block %d: import timeout", i+1)
- }
- }
- verifyImportDone(t, imported)
-}
-
-// verifyImportDone verifies that no more events are arriving on an import channel.
-func verifyImportDone(t *testing.T, imported chan interface{}) {
- t.Helper()
-
- select {
- case <-imported:
- t.Fatalf("extra block imported")
- case <-time.After(50 * time.Millisecond):
- }
-}
-
-// verifyChainHeight verifies the chain height is as expected.
-func verifyChainHeight(t *testing.T, fetcher *fetcherTester, height uint64) {
- t.Helper()
-
- if fetcher.chainHeight() != height {
- t.Fatalf("chain height mismatch, got %d, want %d", fetcher.chainHeight(), height)
- }
-}
-
-// Tests that a fetcher accepts block/header announcements and initiates retrievals
-// for them, successfully importing into the local chain.
-func TestFullSequentialAnnouncements(t *testing.T) { testSequentialAnnouncements(t, false) }
-func TestLightSequentialAnnouncements(t *testing.T) { testSequentialAnnouncements(t, true) }
-
-func testSequentialAnnouncements(t *testing.T, light bool) {
- // Create a chain of blocks to import
- targetBlocks := 4 * hashLimit
- hashes, blocks := makeChain(targetBlocks, 0, genesis)
-
- tester := newTester(light)
- defer tester.fetcher.Stop()
- headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
- bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
-
- // Iteratively announce blocks until all are imported
- imported := make(chan interface{})
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
- if light {
- if header == nil {
- t.Fatalf("Fetcher try to import empty header")
- }
- imported <- header
- } else {
- if block == nil {
- t.Fatalf("Fetcher try to import empty block")
- }
- imported <- block
- }
- }
- for i := len(hashes) - 2; i >= 0; i-- {
- tester.fetcher.Notify("valid", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
- verifyImportEvent(t, imported, true)
- }
- verifyImportDone(t, imported)
- verifyChainHeight(t, tester, uint64(len(hashes)-1))
-}
-
-// Tests that if blocks are announced by multiple peers (or even the same buggy
-// peer), they will only get downloaded at most once.
-func TestFullConcurrentAnnouncements(t *testing.T) { testConcurrentAnnouncements(t, false) }
-func TestLightConcurrentAnnouncements(t *testing.T) { testConcurrentAnnouncements(t, true) }
-
-func testConcurrentAnnouncements(t *testing.T, light bool) {
- // Create a chain of blocks to import
- targetBlocks := 4 * hashLimit
- hashes, blocks := makeChain(targetBlocks, 0, genesis)
-
- // Assemble a tester with a built in counter for the requests
- tester := newTester(light)
- firstHeaderFetcher := tester.makeHeaderFetcher("first", blocks, -gatherSlack)
- firstBodyFetcher := tester.makeBodyFetcher("first", blocks, 0)
- secondHeaderFetcher := tester.makeHeaderFetcher("second", blocks, -gatherSlack)
- secondBodyFetcher := tester.makeBodyFetcher("second", blocks, 0)
-
- var counter atomic.Uint32
- firstHeaderWrapper := func(hash common.Hash, sink chan *eth.Response) (*eth.Request, error) {
- counter.Add(1)
- return firstHeaderFetcher(hash, sink)
- }
- secondHeaderWrapper := func(hash common.Hash, sink chan *eth.Response) (*eth.Request, error) {
- counter.Add(1)
- return secondHeaderFetcher(hash, sink)
- }
- // Iteratively announce blocks until all are imported
- imported := make(chan interface{})
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
- if light {
- if header == nil {
- t.Fatalf("Fetcher try to import empty header")
- }
- imported <- header
- } else {
- if block == nil {
- t.Fatalf("Fetcher try to import empty block")
- }
- imported <- block
- }
- }
- for i := len(hashes) - 2; i >= 0; i-- {
- tester.fetcher.Notify("first", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout), firstHeaderWrapper, firstBodyFetcher)
- tester.fetcher.Notify("second", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout+time.Millisecond), secondHeaderWrapper, secondBodyFetcher)
- tester.fetcher.Notify("second", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout-time.Millisecond), secondHeaderWrapper, secondBodyFetcher)
- verifyImportEvent(t, imported, true)
- }
- verifyImportDone(t, imported)
-
- // Make sure no blocks were retrieved twice
- if c := int(counter.Load()); c != targetBlocks {
- t.Fatalf("retrieval count mismatch: have %v, want %v", c, targetBlocks)
- }
- verifyChainHeight(t, tester, uint64(len(hashes)-1))
-}
-
-// Tests that announcements arriving while a previous is being fetched still
-// results in a valid import.
-func TestFullOverlappingAnnouncements(t *testing.T) { testOverlappingAnnouncements(t, false) }
-func TestLightOverlappingAnnouncements(t *testing.T) { testOverlappingAnnouncements(t, true) }
-
-func testOverlappingAnnouncements(t *testing.T, light bool) {
- // Create a chain of blocks to import
- targetBlocks := 4 * hashLimit
- hashes, blocks := makeChain(targetBlocks, 0, genesis)
-
- tester := newTester(light)
- headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
- bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
-
- // Iteratively announce blocks, but overlap them continuously
- overlap := 16
- imported := make(chan interface{}, len(hashes)-1)
- for i := 0; i < overlap; i++ {
- imported <- nil
- }
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
- if light {
- if header == nil {
- t.Fatalf("Fetcher try to import empty header")
- }
- imported <- header
- } else {
- if block == nil {
- t.Fatalf("Fetcher try to import empty block")
- }
- imported <- block
- }
- }
-
- for i := len(hashes) - 2; i >= 0; i-- {
- tester.fetcher.Notify("valid", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
- select {
- case <-imported:
- case <-time.After(time.Second):
- t.Fatalf("block %d: import timeout", len(hashes)-i)
- }
- }
- // Wait for all the imports to complete and check count
- verifyImportCount(t, imported, overlap)
- verifyChainHeight(t, tester, uint64(len(hashes)-1))
-}
-
-// Tests that announces already being retrieved will not be duplicated.
-func TestFullPendingDeduplication(t *testing.T) { testPendingDeduplication(t, false) }
-func TestLightPendingDeduplication(t *testing.T) { testPendingDeduplication(t, true) }
-
-func testPendingDeduplication(t *testing.T, light bool) {
- // Create a hash and corresponding block
- hashes, blocks := makeChain(1, 0, genesis)
-
- // Assemble a tester with a built in counter and delayed fetcher
- tester := newTester(light)
- headerFetcher := tester.makeHeaderFetcher("repeater", blocks, -gatherSlack)
- bodyFetcher := tester.makeBodyFetcher("repeater", blocks, 0)
-
- delay := 50 * time.Millisecond
- var counter atomic.Uint32
- headerWrapper := func(hash common.Hash, sink chan *eth.Response) (*eth.Request, error) {
- counter.Add(1)
-
- // Simulate a long running fetch
- resink := make(chan *eth.Response)
- req, err := headerFetcher(hash, resink)
- if err == nil {
- go func() {
- res := <-resink
- time.Sleep(delay)
- sink <- res
- }()
- }
- return req, err
- }
- checkNonExist := func() bool {
- return tester.getBlock(hashes[0]) == nil
- }
- if light {
- checkNonExist = func() bool {
- return tester.getHeader(hashes[0]) == nil
- }
- }
- // Announce the same block many times until it's fetched (wait for any pending ops)
- for checkNonExist() {
- tester.fetcher.Notify("repeater", hashes[0], 1, time.Now().Add(-arriveTimeout), headerWrapper, bodyFetcher)
- time.Sleep(time.Millisecond)
- }
- time.Sleep(delay)
-
- // Check that all blocks were imported and none fetched twice
- if c := counter.Load(); c != 1 {
- t.Fatalf("retrieval count mismatch: have %v, want %v", c, 1)
- }
- verifyChainHeight(t, tester, 1)
-}
-
-// Tests that announcements retrieved in a random order are cached and eventually
-// imported when all the gaps are filled in.
-func TestFullRandomArrivalImport(t *testing.T) { testRandomArrivalImport(t, false) }
-func TestLightRandomArrivalImport(t *testing.T) { testRandomArrivalImport(t, true) }
-
-func testRandomArrivalImport(t *testing.T, light bool) {
- // Create a chain of blocks to import, and choose one to delay
- targetBlocks := maxQueueDist
- hashes, blocks := makeChain(targetBlocks, 0, genesis)
- skip := targetBlocks / 2
-
- tester := newTester(light)
- headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
- bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
-
- // Iteratively announce blocks, skipping one entry
- imported := make(chan interface{}, len(hashes)-1)
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
- if light {
- if header == nil {
- t.Fatalf("Fetcher try to import empty header")
- }
- imported <- header
- } else {
- if block == nil {
- t.Fatalf("Fetcher try to import empty block")
- }
- imported <- block
- }
- }
- for i := len(hashes) - 1; i >= 0; i-- {
- if i != skip {
- tester.fetcher.Notify("valid", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
- time.Sleep(time.Millisecond)
- }
- }
- // Finally announce the skipped entry and check full import
- tester.fetcher.Notify("valid", hashes[skip], uint64(len(hashes)-skip-1), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
- verifyImportCount(t, imported, len(hashes)-1)
- verifyChainHeight(t, tester, uint64(len(hashes)-1))
-}
-
-// Tests that direct block enqueues (due to block propagation vs. hash announce)
-// are correctly schedule, filling and import queue gaps.
-func TestQueueGapFill(t *testing.T) {
- // Create a chain of blocks to import, and choose one to not announce at all
- targetBlocks := maxQueueDist
- hashes, blocks := makeChain(targetBlocks, 0, genesis)
- skip := targetBlocks / 2
-
- tester := newTester(false)
- headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
- bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
-
- // Iteratively announce blocks, skipping one entry
- imported := make(chan interface{}, len(hashes)-1)
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) { imported <- block }
-
- for i := len(hashes) - 1; i >= 0; i-- {
- if i != skip {
- tester.fetcher.Notify("valid", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
- time.Sleep(time.Millisecond)
- }
- }
- // Fill the missing block directly as if propagated
- tester.fetcher.Enqueue("valid", blocks[hashes[skip]])
- verifyImportCount(t, imported, len(hashes)-1)
- verifyChainHeight(t, tester, uint64(len(hashes)-1))
-}
-
-// Tests that blocks arriving from various sources (multiple propagations, hash
-// announces, etc) do not get scheduled for import multiple times.
-func TestImportDeduplication(t *testing.T) {
- // Create two blocks to import (one for duplication, the other for stalling)
- hashes, blocks := makeChain(2, 0, genesis)
-
- // Create the tester and wrap the importer with a counter
- tester := newTester(false)
- headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
- bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
-
- var counter atomic.Uint32
- tester.fetcher.insertChain = func(blocks types.Blocks) (int, error) {
- counter.Add(uint32(len(blocks)))
- return tester.insertChain(blocks)
- }
- // Instrument the fetching and imported events
- fetching := make(chan []common.Hash)
- imported := make(chan interface{}, len(hashes)-1)
- tester.fetcher.fetchingHook = func(hashes []common.Hash) { fetching <- hashes }
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) { imported <- block }
-
- // Announce the duplicating block, wait for retrieval, and also propagate directly
- tester.fetcher.Notify("valid", hashes[0], 1, time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
- <-fetching
-
- tester.fetcher.Enqueue("valid", blocks[hashes[0]])
- tester.fetcher.Enqueue("valid", blocks[hashes[0]])
- tester.fetcher.Enqueue("valid", blocks[hashes[0]])
-
- // Fill the missing block directly as if propagated, and check import uniqueness
- tester.fetcher.Enqueue("valid", blocks[hashes[1]])
- verifyImportCount(t, imported, 2)
-
- if c := counter.Load(); c != 2 {
- t.Fatalf("import invocation count mismatch: have %v, want %v", c, 2)
- }
-}
-
-// Tests that blocks with numbers much lower or higher than out current head get
-// discarded to prevent wasting resources on useless blocks from faulty peers.
-func TestDistantPropagationDiscarding(t *testing.T) {
- // Create a long chain to import and define the discard boundaries
- hashes, blocks := makeChain(3*maxQueueDist, 0, genesis)
- head := hashes[len(hashes)/2]
-
- low, high := len(hashes)/2+maxUncleDist+1, len(hashes)/2-maxQueueDist-1
-
- // Create a tester and simulate a head block being the middle of the above chain
- tester := newTester(false)
-
- tester.lock.Lock()
- tester.hashes = []common.Hash{head}
- tester.blocks = map[common.Hash]*types.Block{head: blocks[head]}
- tester.lock.Unlock()
-
- // Ensure that a block with a lower number than the threshold is discarded
- tester.fetcher.Enqueue("lower", blocks[hashes[low]])
- time.Sleep(10 * time.Millisecond)
- if !tester.fetcher.queue.Empty() {
- t.Fatalf("fetcher queued stale block")
- }
- // Ensure that a block with a higher number than the threshold is discarded
- tester.fetcher.Enqueue("higher", blocks[hashes[high]])
- time.Sleep(10 * time.Millisecond)
- if !tester.fetcher.queue.Empty() {
- t.Fatalf("fetcher queued future block")
- }
-}
-
-// Tests that announcements with numbers much lower or higher than out current
-// head get discarded to prevent wasting resources on useless blocks from faulty
-// peers.
-func TestFullDistantAnnouncementDiscarding(t *testing.T) { testDistantAnnouncementDiscarding(t, false) }
-func TestLightDistantAnnouncementDiscarding(t *testing.T) { testDistantAnnouncementDiscarding(t, true) }
-
-func testDistantAnnouncementDiscarding(t *testing.T, light bool) {
- // Create a long chain to import and define the discard boundaries
- hashes, blocks := makeChain(3*maxQueueDist, 0, genesis)
- head := hashes[len(hashes)/2]
-
- low, high := len(hashes)/2+maxUncleDist+1, len(hashes)/2-maxQueueDist-1
-
- // Create a tester and simulate a head block being the middle of the above chain
- tester := newTester(light)
-
- tester.lock.Lock()
- tester.hashes = []common.Hash{head}
- tester.headers = map[common.Hash]*types.Header{head: blocks[head].Header()}
- tester.blocks = map[common.Hash]*types.Block{head: blocks[head]}
- tester.lock.Unlock()
-
- headerFetcher := tester.makeHeaderFetcher("lower", blocks, -gatherSlack)
- bodyFetcher := tester.makeBodyFetcher("lower", blocks, 0)
-
- fetching := make(chan struct{}, 2)
- tester.fetcher.fetchingHook = func(hashes []common.Hash) { fetching <- struct{}{} }
-
- // Ensure that a block with a lower number than the threshold is discarded
- tester.fetcher.Notify("lower", hashes[low], blocks[hashes[low]].NumberU64(), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
- select {
- case <-time.After(50 * time.Millisecond):
- case <-fetching:
- t.Fatalf("fetcher requested stale header")
- }
- // Ensure that a block with a higher number than the threshold is discarded
- tester.fetcher.Notify("higher", hashes[high], blocks[hashes[high]].NumberU64(), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
- select {
- case <-time.After(50 * time.Millisecond):
- case <-fetching:
- t.Fatalf("fetcher requested future header")
- }
-}
-
-// Tests that peers announcing blocks with invalid numbers (i.e. not matching
-// the headers provided afterwards) get dropped as malicious.
-func TestFullInvalidNumberAnnouncement(t *testing.T) { testInvalidNumberAnnouncement(t, false) }
-func TestLightInvalidNumberAnnouncement(t *testing.T) { testInvalidNumberAnnouncement(t, true) }
-
-func testInvalidNumberAnnouncement(t *testing.T, light bool) {
- // Create a single block to import and check numbers against
- hashes, blocks := makeChain(1, 0, genesis)
-
- tester := newTester(light)
- badHeaderFetcher := tester.makeHeaderFetcher("bad", blocks, -gatherSlack)
- badBodyFetcher := tester.makeBodyFetcher("bad", blocks, 0)
-
- imported := make(chan interface{})
- announced := make(chan interface{}, 2)
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
- if light {
- if header == nil {
- t.Fatalf("Fetcher try to import empty header")
- }
- imported <- header
- } else {
- if block == nil {
- t.Fatalf("Fetcher try to import empty block")
- }
- imported <- block
- }
- }
- // Announce a block with a bad number, check for immediate drop
- tester.fetcher.announceChangeHook = func(hash common.Hash, b bool) {
- announced <- nil
- }
- tester.fetcher.Notify("bad", hashes[0], 2, time.Now().Add(-arriveTimeout), badHeaderFetcher, badBodyFetcher)
- verifyAnnounce := func() {
- for i := 0; i < 2; i++ {
- select {
- case <-announced:
- continue
- case <-time.After(1 * time.Second):
- t.Fatal("announce timeout")
- return
- }
- }
- }
- verifyAnnounce()
- verifyImportEvent(t, imported, false)
- tester.lock.RLock()
- dropped := tester.drops["bad"]
- tester.lock.RUnlock()
-
- if !dropped {
- t.Fatalf("peer with invalid numbered announcement not dropped")
- }
- goodHeaderFetcher := tester.makeHeaderFetcher("good", blocks, -gatherSlack)
- goodBodyFetcher := tester.makeBodyFetcher("good", blocks, 0)
- // Make sure a good announcement passes without a drop
- tester.fetcher.Notify("good", hashes[0], 1, time.Now().Add(-arriveTimeout), goodHeaderFetcher, goodBodyFetcher)
- verifyAnnounce()
- verifyImportEvent(t, imported, true)
-
- tester.lock.RLock()
- dropped = tester.drops["good"]
- tester.lock.RUnlock()
-
- if dropped {
- t.Fatalf("peer with valid numbered announcement dropped")
- }
- verifyImportDone(t, imported)
-}
-
-// Tests that if a block is empty (i.e. header only), no body request should be
-// made, and instead the header should be assembled into a whole block in itself.
-func TestEmptyBlockShortCircuit(t *testing.T) {
- // Create a chain of blocks to import
- hashes, blocks := makeChain(32, 0, genesis)
-
- tester := newTester(false)
- defer tester.fetcher.Stop()
- headerFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
- bodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
-
- // Add a monitoring hook for all internal events
- fetching := make(chan []common.Hash)
- tester.fetcher.fetchingHook = func(hashes []common.Hash) { fetching <- hashes }
-
- completing := make(chan []common.Hash)
- tester.fetcher.completingHook = func(hashes []common.Hash) { completing <- hashes }
-
- imported := make(chan interface{})
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
- if block == nil {
- t.Fatalf("Fetcher try to import empty block")
- }
- imported <- block
- }
- // Iteratively announce blocks until all are imported
- for i := len(hashes) - 2; i >= 0; i-- {
- tester.fetcher.Notify("valid", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher)
-
- // All announces should fetch the header
- verifyFetchingEvent(t, fetching, true)
-
- // Only blocks with data contents should request bodies
- verifyCompletingEvent(t, completing, len(blocks[hashes[i]].Transactions()) > 0 || len(blocks[hashes[i]].Uncles()) > 0)
-
- // Irrelevant of the construct, import should succeed
- verifyImportEvent(t, imported, true)
- }
- verifyImportDone(t, imported)
-}
-
-// Tests that a peer is unable to use unbounded memory with sending infinite
-// block announcements to a node, but that even in the face of such an attack,
-// the fetcher remains operational.
-func TestHashMemoryExhaustionAttack(t *testing.T) {
- // Create a tester with instrumented import hooks
- tester := newTester(false)
-
- imported, announces := make(chan interface{}), atomic.Int32{}
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) { imported <- block }
- tester.fetcher.announceChangeHook = func(hash common.Hash, added bool) {
- if added {
- announces.Add(1)
- } else {
- announces.Add(-1)
- }
- }
- // Create a valid chain and an infinite junk chain
- targetBlocks := hashLimit + 2*maxQueueDist
- hashes, blocks := makeChain(targetBlocks, 0, genesis)
- validHeaderFetcher := tester.makeHeaderFetcher("valid", blocks, -gatherSlack)
- validBodyFetcher := tester.makeBodyFetcher("valid", blocks, 0)
-
- attack, _ := makeChain(targetBlocks, 0, unknownBlock)
- attackerHeaderFetcher := tester.makeHeaderFetcher("attacker", nil, -gatherSlack)
- attackerBodyFetcher := tester.makeBodyFetcher("attacker", nil, 0)
-
- // Feed the tester a huge hashset from the attacker, and a limited from the valid peer
- for i := 0; i < len(attack); i++ {
- if i < maxQueueDist {
- tester.fetcher.Notify("valid", hashes[len(hashes)-2-i], uint64(i+1), time.Now(), validHeaderFetcher, validBodyFetcher)
- }
- tester.fetcher.Notify("attacker", attack[i], 1 /* don't distance drop */, time.Now(), attackerHeaderFetcher, attackerBodyFetcher)
- }
- if count := announces.Load(); count != hashLimit+maxQueueDist {
- t.Fatalf("queued announce count mismatch: have %d, want %d", count, hashLimit+maxQueueDist)
- }
- // Wait for fetches to complete
- verifyImportCount(t, imported, maxQueueDist)
-
- // Feed the remaining valid hashes to ensure DOS protection state remains clean
- for i := len(hashes) - maxQueueDist - 2; i >= 0; i-- {
- tester.fetcher.Notify("valid", hashes[i], uint64(len(hashes)-i-1), time.Now().Add(-arriveTimeout), validHeaderFetcher, validBodyFetcher)
- verifyImportEvent(t, imported, true)
- }
- verifyImportDone(t, imported)
-}
-
-// Tests that blocks sent to the fetcher (either through propagation or via hash
-// announces and retrievals) don't pile up indefinitely, exhausting available
-// system memory.
-func TestBlockMemoryExhaustionAttack(t *testing.T) {
- // Create a tester with instrumented import hooks
- tester := newTester(false)
-
- imported, enqueued := make(chan interface{}), atomic.Int32{}
- tester.fetcher.importedHook = func(header *types.Header, block *types.Block) { imported <- block }
- tester.fetcher.queueChangeHook = func(hash common.Hash, added bool) {
- if added {
- enqueued.Add(1)
- } else {
- enqueued.Add(-1)
- }
- }
- // Create a valid chain and a batch of dangling (but in range) blocks
- targetBlocks := hashLimit + 2*maxQueueDist
- hashes, blocks := makeChain(targetBlocks, 0, genesis)
- attack := make(map[common.Hash]*types.Block)
- for i := byte(0); len(attack) < blockLimit+2*maxQueueDist; i++ {
- hashes, blocks := makeChain(maxQueueDist-1, i, unknownBlock)
- for _, hash := range hashes[:maxQueueDist-2] {
- attack[hash] = blocks[hash]
- }
- }
- // Try to feed all the attacker blocks make sure only a limited batch is accepted
- for _, block := range attack {
- tester.fetcher.Enqueue("attacker", block)
- }
- time.Sleep(200 * time.Millisecond)
- if queued := enqueued.Load(); queued != blockLimit {
- t.Fatalf("queued block count mismatch: have %d, want %d", queued, blockLimit)
- }
- // Queue up a batch of valid blocks, and check that a new peer is allowed to do so
- for i := 0; i < maxQueueDist-1; i++ {
- tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-3-i]])
- }
- time.Sleep(100 * time.Millisecond)
- if queued := enqueued.Load(); queued != blockLimit+maxQueueDist-1 {
- t.Fatalf("queued block count mismatch: have %d, want %d", queued, blockLimit+maxQueueDist-1)
- }
- // Insert the missing piece (and sanity check the import)
- tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-2]])
- verifyImportCount(t, imported, maxQueueDist)
-
- // Insert the remaining blocks in chunks to ensure clean DOS protection
- for i := maxQueueDist; i < len(hashes)-1; i++ {
- tester.fetcher.Enqueue("valid", blocks[hashes[len(hashes)-2-i]])
- verifyImportEvent(t, imported, true)
- }
- verifyImportDone(t, imported)
-}
diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go
deleted file mode 100644
index ea7892d8d8..0000000000
--- a/eth/fetcher/tx_fetcher.go
+++ /dev/null
@@ -1,1003 +0,0 @@
-// 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 fetcher
-
-import (
- "bytes"
- "errors"
- "fmt"
- "math"
- mrand "math/rand"
- "sort"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/lru"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/core/txpool"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
-)
-
-const (
- // maxTxAnnounces is the maximum number of unique transaction a peer
- // can announce in a short time.
- maxTxAnnounces = 4096
-
- // maxTxRetrievals is the maximum number of transactions that can be fetched
- // in one request. The rationale for picking 256 is to have a reasonabe lower
- // bound for the transferred data (don't waste RTTs, transfer more meaningful
- // batch sizes), but also have an upper bound on the sequentiality to allow
- // using our entire peerset for deliveries.
- //
- // This number also acts as a failsafe against malicious announces which might
- // cause us to request more data than we'd expect.
- maxTxRetrievals = 256
-
- // maxTxRetrievalSize is the max number of bytes that delivered transactions
- // should weigh according to the announcements. The 128KB was chosen to limit
- // retrieving a maximum of one blob transaction at a time to minimize hogging
- // a connection between two peers.
- maxTxRetrievalSize = 128 * 1024
-
- // maxTxUnderpricedSetSize is the size of the underpriced transaction set that
- // is used to track recent transactions that have been dropped so we don't
- // re-request them.
- maxTxUnderpricedSetSize = 32768
-
- // maxTxUnderpricedTimeout is the max time a transaction should be stuck in the underpriced set.
- maxTxUnderpricedTimeout = 5 * time.Minute
-
- // txArriveTimeout is the time allowance before an announced transaction is
- // explicitly requested.
- txArriveTimeout = 500 * time.Millisecond
-
- // txGatherSlack is the interval used to collate almost-expired announces
- // with network fetches.
- txGatherSlack = 100 * time.Millisecond
-)
-
-var (
- // txFetchTimeout is the maximum allotted time to return an explicitly
- // requested transaction.
- txFetchTimeout = 5 * time.Second
-)
-
-var (
- txAnnounceInMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/announces/in", nil)
- txAnnounceKnownMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/announces/known", nil)
- txAnnounceUnderpricedMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/announces/underpriced", nil)
- txAnnounceDOSMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/announces/dos", nil)
-
- txBroadcastInMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/broadcasts/in", nil)
- txBroadcastKnownMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/broadcasts/known", nil)
- txBroadcastUnderpricedMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/broadcasts/underpriced", nil)
- txBroadcastOtherRejectMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/broadcasts/otherreject", nil)
-
- txRequestOutMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/request/out", nil)
- txRequestFailMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/request/fail", nil)
- txRequestDoneMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/request/done", nil)
- txRequestTimeoutMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/request/timeout", nil)
-
- txReplyInMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/replies/in", nil)
- txReplyKnownMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/replies/known", nil)
- txReplyUnderpricedMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/replies/underpriced", nil)
- txReplyOtherRejectMeter = metrics.NewRegisteredMeter("eth/fetcher/transaction/replies/otherreject", nil)
-
- txFetcherWaitingPeers = metrics.NewRegisteredGauge("eth/fetcher/transaction/waiting/peers", nil)
- txFetcherWaitingHashes = metrics.NewRegisteredGauge("eth/fetcher/transaction/waiting/hashes", nil)
- txFetcherQueueingPeers = metrics.NewRegisteredGauge("eth/fetcher/transaction/queueing/peers", nil)
- txFetcherQueueingHashes = metrics.NewRegisteredGauge("eth/fetcher/transaction/queueing/hashes", nil)
- txFetcherFetchingPeers = metrics.NewRegisteredGauge("eth/fetcher/transaction/fetching/peers", nil)
- txFetcherFetchingHashes = metrics.NewRegisteredGauge("eth/fetcher/transaction/fetching/hashes", nil)
-)
-
-// txAnnounce is the notification of the availability of a batch
-// of new transactions in the network.
-type txAnnounce struct {
- origin string // Identifier of the peer originating the notification
- hashes []common.Hash // Batch of transaction hashes being announced
- metas []*txMetadata // Batch of metadatas associated with the hashes (nil before eth/68)
-}
-
-// txMetadata is a set of extra data transmitted along the announcement for better
-// fetch scheduling.
-type txMetadata struct {
- kind byte // Transaction consensus type
- size uint32 // Transaction size in bytes
-}
-
-// txRequest represents an in-flight transaction retrieval request destined to
-// a specific peers.
-type txRequest struct {
- hashes []common.Hash // Transactions having been requested
- stolen map[common.Hash]struct{} // Deliveries by someone else (don't re-request)
- time mclock.AbsTime // Timestamp of the request
-}
-
-// txDelivery is the notification that a batch of transactions have been added
-// to the pool and should be untracked.
-type txDelivery struct {
- origin string // Identifier of the peer originating the notification
- hashes []common.Hash // Batch of transaction hashes having been delivered
- metas []txMetadata // Batch of metadatas associated with the delivered hashes
- direct bool // Whether this is a direct reply or a broadcast
-}
-
-// txDrop is the notification that a peer has disconnected.
-type txDrop struct {
- peer string
-}
-
-// TxFetcher is responsible for retrieving new transaction based on announcements.
-//
-// The fetcher operates in 3 stages:
-// - Transactions that are newly discovered are moved into a wait list.
-// - After ~500ms passes, transactions from the wait list that have not been
-// broadcast to us in whole are moved into a queueing area.
-// - When a connected peer doesn't have in-flight retrieval requests, any
-// transaction queued up (and announced by the peer) are allocated to the
-// peer and moved into a fetching status until it's fulfilled or fails.
-//
-// The invariants of the fetcher are:
-// - Each tracked transaction (hash) must only be present in one of the
-// three stages. This ensures that the fetcher operates akin to a finite
-// state automata and there's do data leak.
-// - Each peer that announced transactions may be scheduled retrievals, but
-// only ever one concurrently. This ensures we can immediately know what is
-// missing from a reply and reschedule it.
-type TxFetcher struct {
- notify chan *txAnnounce
- cleanup chan *txDelivery
- drop chan *txDrop
- quit chan struct{}
-
- underpriced *lru.Cache[common.Hash, time.Time] // Transactions discarded as too cheap (don't re-fetch)
-
- // Stage 1: Waiting lists for newly discovered transactions that might be
- // broadcast without needing explicit request/reply round trips.
- waitlist map[common.Hash]map[string]struct{} // Transactions waiting for an potential broadcast
- waittime map[common.Hash]mclock.AbsTime // Timestamps when transactions were added to the waitlist
- waitslots map[string]map[common.Hash]*txMetadata // Waiting announcements grouped by peer (DoS protection)
-
- // Stage 2: Queue of transactions that waiting to be allocated to some peer
- // to be retrieved directly.
- announces map[string]map[common.Hash]*txMetadata // Set of announced transactions, grouped by origin peer
- announced map[common.Hash]map[string]struct{} // Set of download locations, grouped by transaction hash
-
- // Stage 3: Set of transactions currently being retrieved, some which may be
- // fulfilled and some rescheduled. Note, this step shares 'announces' from the
- // previous stage to avoid having to duplicate (need it for DoS checks).
- fetching map[common.Hash]string // Transaction set currently being retrieved
- requests map[string]*txRequest // In-flight transaction retrievals
- alternates map[common.Hash]map[string]struct{} // In-flight transaction alternate origins if retrieval fails
-
- // Callbacks
- hasTx func(common.Hash) bool // Retrieves a tx from the local txpool
- addTxs func([]*types.Transaction) []error // Insert a batch of transactions into local txpool
- fetchTxs func(string, []common.Hash) error // Retrieves a set of txs from a remote peer
- dropPeer func(string) // Drops a peer in case of announcement violation
-
- step chan struct{} // Notification channel when the fetcher loop iterates
- clock mclock.Clock // Time wrapper to simulate in tests
- rand *mrand.Rand // Randomizer to use in tests instead of map range loops (soft-random)
-}
-
-// NewTxFetcher creates a transaction fetcher to retrieve transaction
-// based on hash announcements.
-func NewTxFetcher(hasTx func(common.Hash) bool, addTxs func([]*types.Transaction) []error, fetchTxs func(string, []common.Hash) error, dropPeer func(string)) *TxFetcher {
- return NewTxFetcherForTests(hasTx, addTxs, fetchTxs, dropPeer, mclock.System{}, nil)
-}
-
-// NewTxFetcherForTests is a testing method to mock out the realtime clock with
-// a simulated version and the internal randomness with a deterministic one.
-func NewTxFetcherForTests(
- hasTx func(common.Hash) bool, addTxs func([]*types.Transaction) []error, fetchTxs func(string, []common.Hash) error, dropPeer func(string),
- clock mclock.Clock, rand *mrand.Rand) *TxFetcher {
- return &TxFetcher{
- notify: make(chan *txAnnounce),
- cleanup: make(chan *txDelivery),
- drop: make(chan *txDrop),
- quit: make(chan struct{}),
- waitlist: make(map[common.Hash]map[string]struct{}),
- waittime: make(map[common.Hash]mclock.AbsTime),
- waitslots: make(map[string]map[common.Hash]*txMetadata),
- announces: make(map[string]map[common.Hash]*txMetadata),
- announced: make(map[common.Hash]map[string]struct{}),
- fetching: make(map[common.Hash]string),
- requests: make(map[string]*txRequest),
- alternates: make(map[common.Hash]map[string]struct{}),
- underpriced: lru.NewCache[common.Hash, time.Time](maxTxUnderpricedSetSize),
- hasTx: hasTx,
- addTxs: addTxs,
- fetchTxs: fetchTxs,
- dropPeer: dropPeer,
- clock: clock,
- rand: rand,
- }
-}
-
-// Notify announces the fetcher of the potential availability of a new batch of
-// transactions in the network.
-func (f *TxFetcher) Notify(peer string, types []byte, sizes []uint32, hashes []common.Hash) error {
- // Keep track of all the announced transactions
- txAnnounceInMeter.Mark(int64(len(hashes)))
-
- // Skip any transaction announcements that we already know of, or that we've
- // previously marked as cheap and discarded. This check is of course racy,
- // because multiple concurrent notifies will still manage to pass it, but it's
- // still valuable to check here because it runs concurrent to the internal
- // loop, so anything caught here is time saved internally.
- var (
- unknownHashes = make([]common.Hash, 0, len(hashes))
- unknownMetas = make([]*txMetadata, 0, len(hashes))
-
- duplicate int64
- underpriced int64
- )
- for i, hash := range hashes {
- switch {
- case f.hasTx(hash):
- duplicate++
- case f.isKnownUnderpriced(hash):
- underpriced++
- default:
- unknownHashes = append(unknownHashes, hash)
- if types == nil {
- unknownMetas = append(unknownMetas, nil)
- } else {
- unknownMetas = append(unknownMetas, &txMetadata{kind: types[i], size: sizes[i]})
- }
- }
- }
- txAnnounceKnownMeter.Mark(duplicate)
- txAnnounceUnderpricedMeter.Mark(underpriced)
-
- // If anything's left to announce, push it into the internal loop
- if len(unknownHashes) == 0 {
- return nil
- }
- announce := &txAnnounce{origin: peer, hashes: unknownHashes, metas: unknownMetas}
- select {
- case f.notify <- announce:
- return nil
- case <-f.quit:
- return errTerminated
- }
-}
-
-// isKnownUnderpriced reports whether a transaction hash was recently found to be underpriced.
-func (f *TxFetcher) isKnownUnderpriced(hash common.Hash) bool {
- prevTime, ok := f.underpriced.Peek(hash)
- if ok && prevTime.Before(time.Now().Add(-maxTxUnderpricedTimeout)) {
- f.underpriced.Remove(hash)
- return false
- }
- return ok
-}
-
-// Enqueue imports a batch of received transaction into the transaction pool
-// and the fetcher. This method may be called by both transaction broadcasts and
-// direct request replies. The differentiation is important so the fetcher can
-// re-schedule missing transactions as soon as possible.
-func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) error {
- var (
- inMeter = txReplyInMeter
- knownMeter = txReplyKnownMeter
- underpricedMeter = txReplyUnderpricedMeter
- otherRejectMeter = txReplyOtherRejectMeter
- )
- if !direct {
- inMeter = txBroadcastInMeter
- knownMeter = txBroadcastKnownMeter
- underpricedMeter = txBroadcastUnderpricedMeter
- otherRejectMeter = txBroadcastOtherRejectMeter
- }
- // Keep track of all the propagated transactions
- inMeter.Mark(int64(len(txs)))
-
- // Push all the transactions into the pool, tracking underpriced ones to avoid
- // re-requesting them and dropping the peer in case of malicious transfers.
- var (
- added = make([]common.Hash, 0, len(txs))
- metas = make([]txMetadata, 0, len(txs))
- )
- // proceed in batches
- for i := 0; i < len(txs); i += 128 {
- end := i + 128
- if end > len(txs) {
- end = len(txs)
- }
- var (
- duplicate int64
- underpriced int64
- otherreject int64
- )
- batch := txs[i:end]
-
- for j, err := range f.addTxs(batch) {
- // Track the transaction hash if the price is too low for us.
- // Avoid re-request this transaction when we receive another
- // announcement.
- if errors.Is(err, txpool.ErrUnderpriced) || errors.Is(err, txpool.ErrReplaceUnderpriced) {
- f.underpriced.Add(batch[j].Hash(), batch[j].Time())
- }
- // Track a few interesting failure types
- switch {
- case err == nil: // Noop, but need to handle to not count these
-
- case errors.Is(err, txpool.ErrAlreadyKnown):
- duplicate++
-
- case errors.Is(err, txpool.ErrUnderpriced) || errors.Is(err, txpool.ErrReplaceUnderpriced):
- underpriced++
-
- default:
- otherreject++
- }
- added = append(added, batch[j].Hash())
- metas = append(metas, txMetadata{
- kind: batch[j].Type(),
- size: uint32(batch[j].Size()),
- })
- }
- knownMeter.Mark(duplicate)
- underpricedMeter.Mark(underpriced)
- otherRejectMeter.Mark(otherreject)
-
- // If 'other reject' is >25% of the deliveries in any batch, sleep a bit.
- if otherreject > 128/4 {
- time.Sleep(200 * time.Millisecond)
- log.Debug("Peer delivering stale transactions", "peer", peer, "rejected", otherreject)
- }
- }
- select {
- case f.cleanup <- &txDelivery{origin: peer, hashes: added, metas: metas, direct: direct}:
- return nil
- case <-f.quit:
- return errTerminated
- }
-}
-
-// Drop should be called when a peer disconnects. It cleans up all the internal
-// data structures of the given node.
-func (f *TxFetcher) Drop(peer string) error {
- select {
- case f.drop <- &txDrop{peer: peer}:
- return nil
- case <-f.quit:
- return errTerminated
- }
-}
-
-// Start boots up the announcement based synchroniser, accepting and processing
-// hash notifications and block fetches until termination requested.
-func (f *TxFetcher) Start() {
- go f.loop()
-}
-
-// Stop terminates the announcement based synchroniser, canceling all pending
-// operations.
-func (f *TxFetcher) Stop() {
- close(f.quit)
-}
-
-func (f *TxFetcher) loop() {
- var (
- waitTimer = new(mclock.Timer)
- timeoutTimer = new(mclock.Timer)
-
- waitTrigger = make(chan struct{}, 1)
- timeoutTrigger = make(chan struct{}, 1)
- )
- for {
- select {
- case ann := <-f.notify:
- // Drop part of the new announcements if there are too many accumulated.
- // Note, we could but do not filter already known transactions here as
- // the probability of something arriving between this call and the pre-
- // filter outside is essentially zero.
- used := len(f.waitslots[ann.origin]) + len(f.announces[ann.origin])
- if used >= maxTxAnnounces {
- // This can happen if a set of transactions are requested but not
- // all fulfilled, so the remainder are rescheduled without the cap
- // check. Should be fine as the limit is in the thousands and the
- // request size in the hundreds.
- txAnnounceDOSMeter.Mark(int64(len(ann.hashes)))
- break
- }
- want := used + len(ann.hashes)
- if want > maxTxAnnounces {
- txAnnounceDOSMeter.Mark(int64(want - maxTxAnnounces))
-
- ann.hashes = ann.hashes[:want-maxTxAnnounces]
- ann.metas = ann.metas[:want-maxTxAnnounces]
- }
- // All is well, schedule the remainder of the transactions
- idleWait := len(f.waittime) == 0
- _, oldPeer := f.announces[ann.origin]
-
- for i, hash := range ann.hashes {
- // If the transaction is already downloading, add it to the list
- // of possible alternates (in case the current retrieval fails) and
- // also account it for the peer.
- if f.alternates[hash] != nil {
- f.alternates[hash][ann.origin] = struct{}{}
-
- // Stage 2 and 3 share the set of origins per tx
- if announces := f.announces[ann.origin]; announces != nil {
- announces[hash] = ann.metas[i]
- } else {
- f.announces[ann.origin] = map[common.Hash]*txMetadata{hash: ann.metas[i]}
- }
- continue
- }
- // If the transaction is not downloading, but is already queued
- // from a different peer, track it for the new peer too.
- if f.announced[hash] != nil {
- f.announced[hash][ann.origin] = struct{}{}
-
- // Stage 2 and 3 share the set of origins per tx
- if announces := f.announces[ann.origin]; announces != nil {
- announces[hash] = ann.metas[i]
- } else {
- f.announces[ann.origin] = map[common.Hash]*txMetadata{hash: ann.metas[i]}
- }
- continue
- }
- // If the transaction is already known to the fetcher, but not
- // yet downloading, add the peer as an alternate origin in the
- // waiting list.
- if f.waitlist[hash] != nil {
- // Ignore double announcements from the same peer. This is
- // especially important if metadata is also passed along to
- // prevent malicious peers flip-flopping good/bad values.
- if _, ok := f.waitlist[hash][ann.origin]; ok {
- continue
- }
- f.waitlist[hash][ann.origin] = struct{}{}
-
- if waitslots := f.waitslots[ann.origin]; waitslots != nil {
- waitslots[hash] = ann.metas[i]
- } else {
- f.waitslots[ann.origin] = map[common.Hash]*txMetadata{hash: ann.metas[i]}
- }
- continue
- }
- // Transaction unknown to the fetcher, insert it into the waiting list
- f.waitlist[hash] = map[string]struct{}{ann.origin: {}}
- f.waittime[hash] = f.clock.Now()
-
- if waitslots := f.waitslots[ann.origin]; waitslots != nil {
- waitslots[hash] = ann.metas[i]
- } else {
- f.waitslots[ann.origin] = map[common.Hash]*txMetadata{hash: ann.metas[i]}
- }
- }
- // If a new item was added to the waitlist, schedule it into the fetcher
- if idleWait && len(f.waittime) > 0 {
- f.rescheduleWait(waitTimer, waitTrigger)
- }
- // If this peer is new and announced something already queued, maybe
- // request transactions from them
- if !oldPeer && len(f.announces[ann.origin]) > 0 {
- f.scheduleFetches(timeoutTimer, timeoutTrigger, map[string]struct{}{ann.origin: {}})
- }
-
- case <-waitTrigger:
- // At least one transaction's waiting time ran out, push all expired
- // ones into the retrieval queues
- actives := make(map[string]struct{})
- for hash, instance := range f.waittime {
- if time.Duration(f.clock.Now()-instance)+txGatherSlack > txArriveTimeout {
- // Transaction expired without propagation, schedule for retrieval
- if f.announced[hash] != nil {
- panic("announce tracker already contains waitlist item")
- }
- f.announced[hash] = f.waitlist[hash]
- for peer := range f.waitlist[hash] {
- if announces := f.announces[peer]; announces != nil {
- announces[hash] = f.waitslots[peer][hash]
- } else {
- f.announces[peer] = map[common.Hash]*txMetadata{hash: f.waitslots[peer][hash]}
- }
- delete(f.waitslots[peer], hash)
- if len(f.waitslots[peer]) == 0 {
- delete(f.waitslots, peer)
- }
- actives[peer] = struct{}{}
- }
- delete(f.waittime, hash)
- delete(f.waitlist, hash)
- }
- }
- // If transactions are still waiting for propagation, reschedule the wait timer
- if len(f.waittime) > 0 {
- f.rescheduleWait(waitTimer, waitTrigger)
- }
- // If any peers became active and are idle, request transactions from them
- if len(actives) > 0 {
- f.scheduleFetches(timeoutTimer, timeoutTrigger, actives)
- }
-
- case <-timeoutTrigger:
- // Clean up any expired retrievals and avoid re-requesting them from the
- // same peer (either overloaded or malicious, useless in both cases). We
- // could also penalize (Drop), but there's nothing to gain, and if could
- // possibly further increase the load on it.
- for peer, req := range f.requests {
- if time.Duration(f.clock.Now()-req.time)+txGatherSlack > txFetchTimeout {
- txRequestTimeoutMeter.Mark(int64(len(req.hashes)))
-
- // Reschedule all the not-yet-delivered fetches to alternate peers
- for _, hash := range req.hashes {
- // Skip rescheduling hashes already delivered by someone else
- if req.stolen != nil {
- if _, ok := req.stolen[hash]; ok {
- continue
- }
- }
- // Move the delivery back from fetching to queued
- if _, ok := f.announced[hash]; ok {
- panic("announced tracker already contains alternate item")
- }
- if f.alternates[hash] != nil { // nil if tx was broadcast during fetch
- f.announced[hash] = f.alternates[hash]
- }
- delete(f.announced[hash], peer)
- if len(f.announced[hash]) == 0 {
- delete(f.announced, hash)
- }
- delete(f.announces[peer], hash)
- delete(f.alternates, hash)
- delete(f.fetching, hash)
- }
- if len(f.announces[peer]) == 0 {
- delete(f.announces, peer)
- }
- // Keep track of the request as dangling, but never expire
- f.requests[peer].hashes = nil
- }
- }
- // Schedule a new transaction retrieval
- f.scheduleFetches(timeoutTimer, timeoutTrigger, nil)
-
- // No idea if we scheduled something or not, trigger the timer if needed
- // TODO(karalabe): this is kind of lame, can't we dump it into scheduleFetches somehow?
- f.rescheduleTimeout(timeoutTimer, timeoutTrigger)
-
- case delivery := <-f.cleanup:
- // Independent if the delivery was direct or broadcast, remove all
- // traces of the hash from internal trackers. That said, compare any
- // advertised metadata with the real ones and drop bad peers.
- for i, hash := range delivery.hashes {
- if _, ok := f.waitlist[hash]; ok {
- for peer, txset := range f.waitslots {
- if meta := txset[hash]; meta != nil {
- if delivery.metas[i].kind != meta.kind {
- log.Warn("Announced transaction type mismatch", "peer", peer, "tx", hash, "type", delivery.metas[i].kind, "ann", meta.kind)
- f.dropPeer(peer)
- } else if delivery.metas[i].size != meta.size {
- if math.Abs(float64(delivery.metas[i].size)-float64(meta.size)) > 8 {
- log.Warn("Announced transaction size mismatch", "peer", peer, "tx", hash, "size", delivery.metas[i].size, "ann", meta.size)
-
- // Normally we should drop a peer considering this is a protocol violation.
- // However, due to the RLP vs consensus format messyness, allow a few bytes
- // wiggle-room where we only warn, but don't drop.
- //
- // TODO(karalabe): Get rid of this relaxation when clients are proven stable.
- f.dropPeer(peer)
- }
- }
- }
- delete(txset, hash)
- if len(txset) == 0 {
- delete(f.waitslots, peer)
- }
- }
- delete(f.waitlist, hash)
- delete(f.waittime, hash)
- } else {
- for peer, txset := range f.announces {
- if meta := txset[hash]; meta != nil {
- if delivery.metas[i].kind != meta.kind {
- log.Warn("Announced transaction type mismatch", "peer", peer, "tx", hash, "type", delivery.metas[i].kind, "ann", meta.kind)
- f.dropPeer(peer)
- } else if delivery.metas[i].size != meta.size {
- if math.Abs(float64(delivery.metas[i].size)-float64(meta.size)) > 8 {
- log.Warn("Announced transaction size mismatch", "peer", peer, "tx", hash, "size", delivery.metas[i].size, "ann", meta.size)
-
- // Normally we should drop a peer considering this is a protocol violation.
- // However, due to the RLP vs consensus format messyness, allow a few bytes
- // wiggle-room where we only warn, but don't drop.
- //
- // TODO(karalabe): Get rid of this relaxation when clients are proven stable.
- f.dropPeer(peer)
- }
- }
- }
- delete(txset, hash)
- if len(txset) == 0 {
- delete(f.announces, peer)
- }
- }
- delete(f.announced, hash)
- delete(f.alternates, hash)
-
- // If a transaction currently being fetched from a different
- // origin was delivered (delivery stolen), mark it so the
- // actual delivery won't double schedule it.
- if origin, ok := f.fetching[hash]; ok && (origin != delivery.origin || !delivery.direct) {
- stolen := f.requests[origin].stolen
- if stolen == nil {
- f.requests[origin].stolen = make(map[common.Hash]struct{})
- stolen = f.requests[origin].stolen
- }
- stolen[hash] = struct{}{}
- }
- delete(f.fetching, hash)
- }
- }
- // In case of a direct delivery, also reschedule anything missing
- // from the original query
- if delivery.direct {
- // Mark the requesting successful (independent of individual status)
- txRequestDoneMeter.Mark(int64(len(delivery.hashes)))
-
- // Make sure something was pending, nuke it
- req := f.requests[delivery.origin]
- if req == nil {
- log.Warn("Unexpected transaction delivery", "peer", delivery.origin)
- break
- }
- delete(f.requests, delivery.origin)
-
- // Anything not delivered should be re-scheduled (with or without
- // this peer, depending on the response cutoff)
- delivered := make(map[common.Hash]struct{})
- for _, hash := range delivery.hashes {
- delivered[hash] = struct{}{}
- }
- cutoff := len(req.hashes) // If nothing is delivered, assume everything is missing, don't retry!!!
- for i, hash := range req.hashes {
- if _, ok := delivered[hash]; ok {
- cutoff = i
- }
- }
- // Reschedule missing hashes from alternates, not-fulfilled from alt+self
- for i, hash := range req.hashes {
- // Skip rescheduling hashes already delivered by someone else
- if req.stolen != nil {
- if _, ok := req.stolen[hash]; ok {
- continue
- }
- }
- if _, ok := delivered[hash]; !ok {
- if i < cutoff {
- delete(f.alternates[hash], delivery.origin)
- delete(f.announces[delivery.origin], hash)
- if len(f.announces[delivery.origin]) == 0 {
- delete(f.announces, delivery.origin)
- }
- }
- if len(f.alternates[hash]) > 0 {
- if _, ok := f.announced[hash]; ok {
- panic(fmt.Sprintf("announced tracker already contains alternate item: %v", f.announced[hash]))
- }
- f.announced[hash] = f.alternates[hash]
- }
- }
- delete(f.alternates, hash)
- delete(f.fetching, hash)
- }
- // Something was delivered, try to reschedule requests
- f.scheduleFetches(timeoutTimer, timeoutTrigger, nil) // Partial delivery may enable others to deliver too
- }
-
- case drop := <-f.drop:
- // A peer was dropped, remove all traces of it
- if _, ok := f.waitslots[drop.peer]; ok {
- for hash := range f.waitslots[drop.peer] {
- delete(f.waitlist[hash], drop.peer)
- if len(f.waitlist[hash]) == 0 {
- delete(f.waitlist, hash)
- delete(f.waittime, hash)
- }
- }
- delete(f.waitslots, drop.peer)
- if len(f.waitlist) > 0 {
- f.rescheduleWait(waitTimer, waitTrigger)
- }
- }
- // Clean up any active requests
- var request *txRequest
- if request = f.requests[drop.peer]; request != nil {
- for _, hash := range request.hashes {
- // Skip rescheduling hashes already delivered by someone else
- if request.stolen != nil {
- if _, ok := request.stolen[hash]; ok {
- continue
- }
- }
- // Undelivered hash, reschedule if there's an alternative origin available
- delete(f.alternates[hash], drop.peer)
- if len(f.alternates[hash]) == 0 {
- delete(f.alternates, hash)
- } else {
- f.announced[hash] = f.alternates[hash]
- delete(f.alternates, hash)
- }
- delete(f.fetching, hash)
- }
- delete(f.requests, drop.peer)
- }
- // Clean up general announcement tracking
- if _, ok := f.announces[drop.peer]; ok {
- for hash := range f.announces[drop.peer] {
- delete(f.announced[hash], drop.peer)
- if len(f.announced[hash]) == 0 {
- delete(f.announced, hash)
- }
- }
- delete(f.announces, drop.peer)
- }
- // If a request was cancelled, check if anything needs to be rescheduled
- if request != nil {
- f.scheduleFetches(timeoutTimer, timeoutTrigger, nil)
- f.rescheduleTimeout(timeoutTimer, timeoutTrigger)
- }
-
- case <-f.quit:
- return
- }
- // No idea what happened, but bump some sanity metrics
- txFetcherWaitingPeers.Update(int64(len(f.waitslots)))
- txFetcherWaitingHashes.Update(int64(len(f.waitlist)))
- txFetcherQueueingPeers.Update(int64(len(f.announces) - len(f.requests)))
- txFetcherQueueingHashes.Update(int64(len(f.announced)))
- txFetcherFetchingPeers.Update(int64(len(f.requests)))
- txFetcherFetchingHashes.Update(int64(len(f.fetching)))
-
- // Loop did something, ping the step notifier if needed (tests)
- if f.step != nil {
- f.step <- struct{}{}
- }
- }
-}
-
-// rescheduleWait iterates over all the transactions currently in the waitlist
-// and schedules the movement into the fetcher for the earliest.
-//
-// The method has a granularity of 'gatherSlack', since there's not much point in
-// spinning over all the transactions just to maybe find one that should trigger
-// a few ms earlier.
-func (f *TxFetcher) rescheduleWait(timer *mclock.Timer, trigger chan struct{}) {
- if *timer != nil {
- (*timer).Stop()
- }
- now := f.clock.Now()
-
- earliest := now
- for _, instance := range f.waittime {
- if earliest > instance {
- earliest = instance
- if txArriveTimeout-time.Duration(now-earliest) < gatherSlack {
- break
- }
- }
- }
- *timer = f.clock.AfterFunc(txArriveTimeout-time.Duration(now-earliest), func() {
- trigger <- struct{}{}
- })
-}
-
-// rescheduleTimeout iterates over all the transactions currently in flight and
-// schedules a cleanup run when the first would trigger.
-//
-// The method has a granularity of 'gatherSlack', since there's not much point in
-// spinning over all the transactions just to maybe find one that should trigger
-// a few ms earlier.
-//
-// This method is a bit "flaky" "by design". In theory the timeout timer only ever
-// should be rescheduled if some request is pending. In practice, a timeout will
-// cause the timer to be rescheduled every 5 secs (until the peer comes through or
-// disconnects). This is a limitation of the fetcher code because we don't trac
-// pending requests and timed out requests separately. Without double tracking, if
-// we simply didn't reschedule the timer on all-timeout then the timer would never
-// be set again since len(request) > 0 => something's running.
-func (f *TxFetcher) rescheduleTimeout(timer *mclock.Timer, trigger chan struct{}) {
- if *timer != nil {
- (*timer).Stop()
- }
- now := f.clock.Now()
-
- earliest := now
- for _, req := range f.requests {
- // If this request already timed out, skip it altogether
- if req.hashes == nil {
- continue
- }
- if earliest > req.time {
- earliest = req.time
- if txFetchTimeout-time.Duration(now-earliest) < gatherSlack {
- break
- }
- }
- }
- *timer = f.clock.AfterFunc(txFetchTimeout-time.Duration(now-earliest), func() {
- trigger <- struct{}{}
- })
-}
-
-// scheduleFetches starts a batch of retrievals for all available idle peers.
-func (f *TxFetcher) scheduleFetches(timer *mclock.Timer, timeout chan struct{}, whitelist map[string]struct{}) {
- // Gather the set of peers we want to retrieve from (default to all)
- actives := whitelist
- if actives == nil {
- actives = make(map[string]struct{})
- for peer := range f.announces {
- actives[peer] = struct{}{}
- }
- }
- if len(actives) == 0 {
- return
- }
- // For each active peer, try to schedule some transaction fetches
- idle := len(f.requests) == 0
-
- f.forEachPeer(actives, func(peer string) {
- if f.requests[peer] != nil {
- return // continue in the for-each
- }
- if len(f.announces[peer]) == 0 {
- return // continue in the for-each
- }
- var (
- hashes = make([]common.Hash, 0, maxTxRetrievals)
- bytes uint64
- )
- f.forEachAnnounce(f.announces[peer], func(hash common.Hash, meta *txMetadata) bool {
- // If the transaction is already fetching, skip to the next one
- if _, ok := f.fetching[hash]; ok {
- return true
- }
- // Mark the hash as fetching and stash away possible alternates
- f.fetching[hash] = peer
-
- if _, ok := f.alternates[hash]; ok {
- panic(fmt.Sprintf("alternate tracker already contains fetching item: %v", f.alternates[hash]))
- }
- f.alternates[hash] = f.announced[hash]
- delete(f.announced, hash)
-
- // Accumulate the hash and stop if the limit was reached
- hashes = append(hashes, hash)
- if len(hashes) >= maxTxRetrievals {
- return false // break in the for-each
- }
- if meta != nil { // Only set eth/68 and upwards
- bytes += uint64(meta.size)
- if bytes >= maxTxRetrievalSize {
- return false
- }
- }
- return true // scheduled, try to add more
- })
- // If any hashes were allocated, request them from the peer
- if len(hashes) > 0 {
- f.requests[peer] = &txRequest{hashes: hashes, time: f.clock.Now()}
- txRequestOutMeter.Mark(int64(len(hashes)))
-
- go func(peer string, hashes []common.Hash) {
- // Try to fetch the transactions, but in case of a request
- // failure (e.g. peer disconnected), reschedule the hashes.
- if err := f.fetchTxs(peer, hashes); err != nil {
- txRequestFailMeter.Mark(int64(len(hashes)))
- f.Drop(peer)
- }
- }(peer, hashes)
- }
- })
- // If a new request was fired, schedule a timeout timer
- if idle && len(f.requests) > 0 {
- f.rescheduleTimeout(timer, timeout)
- }
-}
-
-// forEachPeer does a range loop over a map of peers in production, but during
-// testing it does a deterministic sorted random to allow reproducing issues.
-func (f *TxFetcher) forEachPeer(peers map[string]struct{}, do func(peer string)) {
- // If we're running production, use whatever Go's map gives us
- if f.rand == nil {
- for peer := range peers {
- do(peer)
- }
- return
- }
- // We're running the test suite, make iteration deterministic
- list := make([]string, 0, len(peers))
- for peer := range peers {
- list = append(list, peer)
- }
- sort.Strings(list)
- rotateStrings(list, f.rand.Intn(len(list)))
- for _, peer := range list {
- do(peer)
- }
-}
-
-// forEachAnnounce does a range loop over a map of announcements in production,
-// but during testing it does a deterministic sorted random to allow reproducing
-// issues.
-func (f *TxFetcher) forEachAnnounce(announces map[common.Hash]*txMetadata, do func(hash common.Hash, meta *txMetadata) bool) {
- // If we're running production, use whatever Go's map gives us
- if f.rand == nil {
- for hash, meta := range announces {
- if !do(hash, meta) {
- return
- }
- }
- return
- }
- // We're running the test suite, make iteration deterministic
- list := make([]common.Hash, 0, len(announces))
- for hash := range announces {
- list = append(list, hash)
- }
- sortHashes(list)
- rotateHashes(list, f.rand.Intn(len(list)))
- for _, hash := range list {
- if !do(hash, announces[hash]) {
- return
- }
- }
-}
-
-// rotateStrings rotates the contents of a slice by n steps. This method is only
-// used in tests to simulate random map iteration but keep it deterministic.
-func rotateStrings(slice []string, n int) {
- orig := make([]string, len(slice))
- copy(orig, slice)
-
- for i := 0; i < len(orig); i++ {
- slice[i] = orig[(i+n)%len(orig)]
- }
-}
-
-// sortHashes sorts a slice of hashes. This method is only used in tests in order
-// to simulate random map iteration but keep it deterministic.
-func sortHashes(slice []common.Hash) {
- for i := 0; i < len(slice); i++ {
- for j := i + 1; j < len(slice); j++ {
- if bytes.Compare(slice[i][:], slice[j][:]) > 0 {
- slice[i], slice[j] = slice[j], slice[i]
- }
- }
- }
-}
-
-// rotateHashes rotates the contents of a slice by n steps. This method is only
-// used in tests to simulate random map iteration but keep it deterministic.
-func rotateHashes(slice []common.Hash, n int) {
- orig := make([]common.Hash, len(slice))
- copy(orig, slice)
-
- for i := 0; i < len(orig); i++ {
- slice[i] = orig[(i+n)%len(orig)]
- }
-}
diff --git a/eth/fetcher/tx_fetcher_test.go b/eth/fetcher/tx_fetcher_test.go
deleted file mode 100644
index 4a62e579b6..0000000000
--- a/eth/fetcher/tx_fetcher_test.go
+++ /dev/null
@@ -1,2030 +0,0 @@
-// 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 fetcher
-
-import (
- "errors"
- "math/big"
- "math/rand"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/core/txpool"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
-)
-
-var (
- // testTxs is a set of transactions to use during testing that have meaningful hashes.
- testTxs = []*types.Transaction{
- types.NewTransaction(5577006791947779410, common.Address{0x0f}, new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(15352856648520921629, common.Address{0xbb}, new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(3916589616287113937, common.Address{0x86}, new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(9828766684487745566, common.Address{0xac}, new(big.Int), 0, new(big.Int), nil),
- }
- // testTxsHashes is the hashes of the test transactions above
- testTxsHashes = []common.Hash{testTxs[0].Hash(), testTxs[1].Hash(), testTxs[2].Hash(), testTxs[3].Hash()}
-)
-
-type announce struct {
- hash common.Hash
- kind *byte
- size *uint32
-}
-
-func typeptr(t byte) *byte { return &t }
-func sizeptr(n uint32) *uint32 { return &n }
-
-type doTxNotify struct {
- peer string
- hashes []common.Hash
- types []byte
- sizes []uint32
-}
-type doTxEnqueue struct {
- peer string
- txs []*types.Transaction
- direct bool
-}
-type doWait struct {
- time time.Duration
- step bool
-}
-type doDrop string
-type doFunc func()
-
-type isWaitingWithMeta map[string][]announce
-type isWaiting map[string][]common.Hash
-
-type isScheduledWithMeta struct {
- tracking map[string][]announce
- fetching map[string][]common.Hash
- dangling map[string][]common.Hash
-}
-type isScheduled struct {
- tracking map[string][]common.Hash
- fetching map[string][]common.Hash
- dangling map[string][]common.Hash
-}
-type isUnderpriced int
-
-// txFetcherTest represents a test scenario that can be executed by the test
-// runner.
-type txFetcherTest struct {
- init func() *TxFetcher
- steps []interface{}
-}
-
-// Tests that transaction announcements are added to a waitlist, and none
-// of them are scheduled for retrieval until the wait expires.
-func TestTransactionFetcherWaiting(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Initial announcement to get something into the waitlist
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- }),
- // Announce from a new peer to check that no overwrite happens
- doTxNotify{peer: "B", hashes: []common.Hash{{0x03}, {0x04}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- "B": {{0x03}, {0x04}},
- }),
- // Announce clashing hashes but unique new peer
- doTxNotify{peer: "C", hashes: []common.Hash{{0x01}, {0x04}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- "B": {{0x03}, {0x04}},
- "C": {{0x01}, {0x04}},
- }),
- // Announce existing and clashing hashes from existing peer
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x03}, {0x05}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}, {0x02}, {0x03}, {0x05}},
- "B": {{0x03}, {0x04}},
- "C": {{0x01}, {0x04}},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- // Wait for the arrival timeout which should move all expired items
- // from the wait list to the scheduler
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}, {0x03}, {0x05}},
- "B": {{0x03}, {0x04}},
- "C": {{0x01}, {0x04}},
- },
- fetching: map[string][]common.Hash{ // Depends on deterministic test randomizer
- "A": {{0x02}, {0x03}, {0x05}},
- "C": {{0x01}, {0x04}},
- },
- },
- // Queue up a non-fetchable transaction and then trigger it with a new
- // peer (weird case to test 1 line in the fetcher)
- doTxNotify{peer: "C", hashes: []common.Hash{{0x06}, {0x07}}},
- isWaiting(map[string][]common.Hash{
- "C": {{0x06}, {0x07}},
- }),
- doWait{time: txArriveTimeout, step: true},
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}, {0x03}, {0x05}},
- "B": {{0x03}, {0x04}},
- "C": {{0x01}, {0x04}, {0x06}, {0x07}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x02}, {0x03}, {0x05}},
- "C": {{0x01}, {0x04}},
- },
- },
- doTxNotify{peer: "D", hashes: []common.Hash{{0x06}, {0x07}}},
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}, {0x03}, {0x05}},
- "B": {{0x03}, {0x04}},
- "C": {{0x01}, {0x04}, {0x06}, {0x07}},
- "D": {{0x06}, {0x07}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x02}, {0x03}, {0x05}},
- "C": {{0x01}, {0x04}},
- "D": {{0x06}, {0x07}},
- },
- },
- },
- })
-}
-
-// Tests that transaction announcements with associated metadata are added to a
-// waitlist, and none of them are scheduled for retrieval until the wait expires.
-//
-// This test is an extended version of TestTransactionFetcherWaiting. It's mostly
-// to cover the metadata checks without bloating up the basic behavioral tests
-// with all the useless extra fields.
-func TestTransactionFetcherWaitingWithMeta(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Initial announcement to get something into the waitlist
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 222}},
- isWaitingWithMeta(map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)},
- },
- }),
- // Announce from a new peer to check that no overwrite happens
- doTxNotify{peer: "B", hashes: []common.Hash{{0x03}, {0x04}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{333, 444}},
- isWaitingWithMeta(map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)},
- },
- "B": {
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- }),
- // Announce clashing hashes but unique new peer
- doTxNotify{peer: "C", hashes: []common.Hash{{0x01}, {0x04}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 444}},
- isWaitingWithMeta(map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)},
- },
- "B": {
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- "C": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- }),
- // Announce existing and clashing hashes from existing peer. Clashes
- // should not overwrite previous announcements.
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x03}, {0x05}}, types: []byte{types.LegacyTxType, types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{999, 333, 555}},
- isWaitingWithMeta(map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)},
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)},
- },
- "B": {
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- "C": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- }),
- // Announce clashing hashes with conflicting metadata. Somebody will
- // be in the wrong, but we don't know yet who.
- doTxNotify{peer: "D", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.BlobTxType}, sizes: []uint32{999, 222}},
- isWaitingWithMeta(map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)},
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)},
- },
- "B": {
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- "C": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- "D": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(999)},
- {common.Hash{0x02}, typeptr(types.BlobTxType), sizeptr(222)},
- },
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- // Wait for the arrival timeout which should move all expired items
- // from the wait list to the scheduler
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduledWithMeta{
- tracking: map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)},
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)},
- },
- "B": {
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- "C": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- "D": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(999)},
- {common.Hash{0x02}, typeptr(types.BlobTxType), sizeptr(222)},
- },
- },
- fetching: map[string][]common.Hash{ // Depends on deterministic test randomizer
- "A": {{0x03}, {0x05}},
- "C": {{0x01}, {0x04}},
- "D": {{0x02}},
- },
- },
- // Queue up a non-fetchable transaction and then trigger it with a new
- // peer (weird case to test 1 line in the fetcher)
- doTxNotify{peer: "C", hashes: []common.Hash{{0x06}, {0x07}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{666, 777}},
- isWaitingWithMeta(map[string][]announce{
- "C": {
- {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(666)},
- {common.Hash{0x07}, typeptr(types.LegacyTxType), sizeptr(777)},
- },
- }),
- doWait{time: txArriveTimeout, step: true},
- isScheduledWithMeta{
- tracking: map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)},
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)},
- },
- "B": {
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- "C": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(666)},
- {common.Hash{0x07}, typeptr(types.LegacyTxType), sizeptr(777)},
- },
- "D": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(999)},
- {common.Hash{0x02}, typeptr(types.BlobTxType), sizeptr(222)},
- },
- },
- fetching: map[string][]common.Hash{
- "A": {{0x03}, {0x05}},
- "C": {{0x01}, {0x04}},
- "D": {{0x02}},
- },
- },
- doTxNotify{peer: "E", hashes: []common.Hash{{0x06}, {0x07}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{666, 777}},
- isScheduledWithMeta{
- tracking: map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(222)},
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(555)},
- },
- "B": {
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(333)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- },
- "C": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(111)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(444)},
- {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(666)},
- {common.Hash{0x07}, typeptr(types.LegacyTxType), sizeptr(777)},
- },
- "D": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(999)},
- {common.Hash{0x02}, typeptr(types.BlobTxType), sizeptr(222)},
- },
- "E": {
- {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(666)},
- {common.Hash{0x07}, typeptr(types.LegacyTxType), sizeptr(777)},
- },
- },
- fetching: map[string][]common.Hash{
- "A": {{0x03}, {0x05}},
- "C": {{0x01}, {0x04}},
- "D": {{0x02}},
- "E": {{0x06}, {0x07}},
- },
- },
- },
- })
-}
-
-// Tests that transaction announcements skip the waiting list if they are
-// already scheduled.
-func TestTransactionFetcherSkipWaiting(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Push an initial announcement through to the scheduled stage
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- },
- // Announce overlaps from the same peer, ensure the new ones end up
- // in stage one, and clashing ones don't get double tracked
- doTxNotify{peer: "A", hashes: []common.Hash{{0x02}, {0x03}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x03}},
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- },
- // Announce overlaps from a new peer, ensure new transactions end up
- // in stage one and clashing ones get tracked for the new peer
- doTxNotify{peer: "B", hashes: []common.Hash{{0x02}, {0x03}, {0x04}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x03}},
- "B": {{0x03}, {0x04}},
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- "B": {{0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- },
- },
- })
-}
-
-// Tests that only a single transaction request gets scheduled to a peer
-// and subsequent announces block or get allotted to someone else.
-func TestTransactionFetcherSingletonRequesting(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Push an initial announcement through to the scheduled stage
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- },
- // Announce a new set of transactions from the same peer and ensure
- // they do not start fetching since the peer is already busy
- doTxNotify{peer: "A", hashes: []common.Hash{{0x03}, {0x04}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x03}, {0x04}},
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- },
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}, {0x03}, {0x04}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- },
- // Announce a duplicate set of transactions from a new peer and ensure
- // uniquely new ones start downloading, even if clashing.
- doTxNotify{peer: "B", hashes: []common.Hash{{0x02}, {0x03}, {0x05}, {0x06}}},
- isWaiting(map[string][]common.Hash{
- "B": {{0x05}, {0x06}},
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}, {0x03}, {0x04}},
- "B": {{0x02}, {0x03}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- "B": {{0x03}},
- },
- },
- },
- })
-}
-
-// Tests that if a transaction retrieval fails, all the transactions get
-// instantly schedule back to someone else or the announcements dropped
-// if no alternate source is available.
-func TestTransactionFetcherFailedRescheduling(t *testing.T) {
- // Create a channel to control when tx requests can fail
- proceed := make(chan struct{})
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(origin string, hashes []common.Hash) error {
- <-proceed
- return errors.New("peer disconnected")
- },
- nil,
- )
- },
- steps: []interface{}{
- // Push an initial announcement through to the scheduled stage
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- },
- // While the original peer is stuck in the request, push in an second
- // data source.
- doTxNotify{peer: "B", hashes: []common.Hash{{0x02}}},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- "B": {{0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- },
- // Wait until the original request fails and check that transactions
- // are either rescheduled or dropped
- doFunc(func() {
- proceed <- struct{}{} // Allow peer A to return the failure
- }),
- doWait{time: 0, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "B": {{0x02}},
- },
- fetching: map[string][]common.Hash{
- "B": {{0x02}},
- },
- },
- doFunc(func() {
- proceed <- struct{}{} // Allow peer B to return the failure
- }),
- doWait{time: 0, step: true},
- isWaiting(nil),
- isScheduled{nil, nil, nil},
- },
- })
-}
-
-// Tests that if a transaction retrieval succeeds, all alternate origins
-// are cleaned up.
-func TestTransactionFetcherCleanup(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Push an initial announcement through to the scheduled stage
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- isWaiting(map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- },
- // Request should be delivered
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}, direct: true},
- isScheduled{nil, nil, nil},
- },
- })
-}
-
-// Tests that if a transaction retrieval succeeds, but the response is empty (no
-// transactions available, then all are nuked instead of being rescheduled (yes,
-// this was a bug)).
-func TestTransactionFetcherCleanupEmpty(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Push an initial announcement through to the scheduled stage
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- isWaiting(map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- },
- // Deliver an empty response and ensure the transaction is cleared, not rescheduled
- doTxEnqueue{peer: "A", txs: []*types.Transaction{}, direct: true},
- isScheduled{nil, nil, nil},
- },
- })
-}
-
-// Tests that non-returned transactions are either re-scheduled from a
-// different peer, or self if they are after the cutoff point.
-func TestTransactionFetcherMissingRescheduling(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Push an initial announcement through to the scheduled stage
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}},
- isWaiting(map[string][]common.Hash{
- "A": {testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]},
- },
- },
- // Deliver the middle transaction requested, the one before which
- // should be dropped and the one after re-requested.
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}, direct: true}, // This depends on the deterministic random
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[2]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[2]},
- },
- },
- },
- })
-}
-
-// Tests that out of two transactions, if one is missing and the last is
-// delivered, the peer gets properly cleaned out from the internal state.
-func TestTransactionFetcherMissingCleanup(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Push an initial announcement through to the scheduled stage
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}},
- isWaiting(map[string][]common.Hash{
- "A": {testTxsHashes[0], testTxsHashes[1]},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[0], testTxsHashes[1]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0], testTxsHashes[1]},
- },
- },
- // Deliver the middle transaction requested, the one before which
- // should be dropped and the one after re-requested.
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[1]}, direct: true}, // This depends on the deterministic random
- isScheduled{nil, nil, nil},
- },
- })
-}
-
-// Tests that transaction broadcasts properly clean up announcements.
-func TestTransactionFetcherBroadcasts(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Set up three transactions to be in different stats, waiting, queued and fetching
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[1]}},
- doWait{time: txArriveTimeout, step: true},
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[2]}},
-
- isWaiting(map[string][]common.Hash{
- "A": {testTxsHashes[2]},
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[0], testTxsHashes[1]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- },
- // Broadcast all the transactions and ensure everything gets cleaned
- // up, but the dangling request is left alone to avoid doing multiple
- // concurrent requests.
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0], testTxs[1], testTxs[2]}, direct: false},
- isWaiting(nil),
- isScheduled{
- tracking: nil,
- fetching: nil,
- dangling: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- },
- // Deliver the requested hashes
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0], testTxs[1], testTxs[2]}, direct: true},
- isScheduled{nil, nil, nil},
- },
- })
-}
-
-// Tests that the waiting list timers properly reset and reschedule.
-func TestTransactionFetcherWaitTimerResets(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}},
- }),
- isScheduled{nil, nil, nil},
- doWait{time: txArriveTimeout / 2, step: false},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}},
- }),
- isScheduled{nil, nil, nil},
-
- doTxNotify{peer: "A", hashes: []common.Hash{{0x02}}},
- isWaiting(map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- }),
- isScheduled{nil, nil, nil},
- doWait{time: txArriveTimeout / 2, step: true},
- isWaiting(map[string][]common.Hash{
- "A": {{0x02}},
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}},
- },
- },
-
- doWait{time: txArriveTimeout / 2, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}},
- },
- },
- },
- })
-}
-
-// Tests that if a transaction request is not replied to, it will time
-// out and be re-scheduled for someone else.
-func TestTransactionFetcherTimeoutRescheduling(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Push an initial announcement through to the scheduled stage
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- isWaiting(map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- }),
- isScheduled{tracking: nil, fetching: nil},
-
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- },
- // Wait until the delivery times out, everything should be cleaned up
- doWait{time: txFetchTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: nil,
- fetching: nil,
- dangling: map[string][]common.Hash{
- "A": {},
- },
- },
- // Ensure that followup announcements don't get scheduled
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[1]}},
- doWait{time: txArriveTimeout, step: true},
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[1]},
- },
- fetching: nil,
- dangling: map[string][]common.Hash{
- "A": {},
- },
- },
- // If the dangling request arrives a bit later, do not choke
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}, direct: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[1]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[1]},
- },
- },
- },
- })
-}
-
-// Tests that the fetching timeout timers properly reset and reschedule.
-func TestTransactionFetcherTimeoutTimerResets(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}},
- doWait{time: txArriveTimeout, step: true},
- doTxNotify{peer: "B", hashes: []common.Hash{{0x02}}},
- doWait{time: txArriveTimeout, step: true},
-
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}},
- "B": {{0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}},
- "B": {{0x02}},
- },
- },
- doWait{time: txFetchTimeout - txArriveTimeout, step: true},
- isScheduled{
- tracking: map[string][]common.Hash{
- "B": {{0x02}},
- },
- fetching: map[string][]common.Hash{
- "B": {{0x02}},
- },
- dangling: map[string][]common.Hash{
- "A": {},
- },
- },
- doWait{time: txArriveTimeout, step: true},
- isScheduled{
- tracking: nil,
- fetching: nil,
- dangling: map[string][]common.Hash{
- "A": {},
- "B": {},
- },
- },
- },
- })
-}
-
-// Tests that if thousands of transactions are announced, only a small
-// number of them will be requested at a time.
-func TestTransactionFetcherRateLimiting(t *testing.T) {
- // Create a slew of transactions and announce them
- var hashes []common.Hash
- for i := 0; i < maxTxAnnounces; i++ {
- hashes = append(hashes, common.Hash{byte(i / 256), byte(i % 256)})
- }
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Announce all the transactions, wait a bit and ensure only a small
- // percentage gets requested
- doTxNotify{peer: "A", hashes: hashes},
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": hashes,
- },
- fetching: map[string][]common.Hash{
- "A": hashes[1643 : 1643+maxTxRetrievals],
- },
- },
- },
- })
-}
-
-// Tests that if huge transactions are announced, only a small number of them will
-// be requested at a time, to keep the responses below a reasonable level.
-func TestTransactionFetcherBandwidthLimiting(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Announce mid size transactions from A to verify that multiple
- // ones can be piled into a single request.
- doTxNotify{peer: "A",
- hashes: []common.Hash{{0x01}, {0x02}, {0x03}, {0x04}},
- types: []byte{types.LegacyTxType, types.LegacyTxType, types.LegacyTxType, types.LegacyTxType},
- sizes: []uint32{48 * 1024, 48 * 1024, 48 * 1024, 48 * 1024},
- },
- // Announce exactly on the limit transactions to see that only one
- // gets requested
- doTxNotify{peer: "B",
- hashes: []common.Hash{{0x05}, {0x06}},
- types: []byte{types.LegacyTxType, types.LegacyTxType},
- sizes: []uint32{maxTxRetrievalSize, maxTxRetrievalSize},
- },
- // Announce oversized blob transactions to see that overflows are ok
- doTxNotify{peer: "C",
- hashes: []common.Hash{{0x07}, {0x08}},
- types: []byte{types.BlobTxType, types.BlobTxType},
- sizes: []uint32{params.MaxBlobGasPerBlock, params.MaxBlobGasPerBlock},
- },
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduledWithMeta{
- tracking: map[string][]announce{
- "A": {
- {common.Hash{0x01}, typeptr(types.LegacyTxType), sizeptr(48 * 1024)},
- {common.Hash{0x02}, typeptr(types.LegacyTxType), sizeptr(48 * 1024)},
- {common.Hash{0x03}, typeptr(types.LegacyTxType), sizeptr(48 * 1024)},
- {common.Hash{0x04}, typeptr(types.LegacyTxType), sizeptr(48 * 1024)},
- },
- "B": {
- {common.Hash{0x05}, typeptr(types.LegacyTxType), sizeptr(maxTxRetrievalSize)},
- {common.Hash{0x06}, typeptr(types.LegacyTxType), sizeptr(maxTxRetrievalSize)},
- },
- "C": {
- {common.Hash{0x07}, typeptr(types.BlobTxType), sizeptr(params.MaxBlobGasPerBlock)},
- {common.Hash{0x08}, typeptr(types.BlobTxType), sizeptr(params.MaxBlobGasPerBlock)},
- },
- },
- fetching: map[string][]common.Hash{
- "A": {{0x02}, {0x03}, {0x04}},
- "B": {{0x06}},
- "C": {{0x08}},
- },
- },
- },
- })
-}
-
-// Tests that then number of transactions a peer is allowed to announce and/or
-// request at the same time is hard capped.
-func TestTransactionFetcherDoSProtection(t *testing.T) {
- // Create a slew of transactions and to announce them
- var hashesA []common.Hash
- for i := 0; i < maxTxAnnounces+1; i++ {
- hashesA = append(hashesA, common.Hash{0x01, byte(i / 256), byte(i % 256)})
- }
- var hashesB []common.Hash
- for i := 0; i < maxTxAnnounces+1; i++ {
- hashesB = append(hashesB, common.Hash{0x02, byte(i / 256), byte(i % 256)})
- }
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- nil,
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Announce half of the transaction and wait for them to be scheduled
- doTxNotify{peer: "A", hashes: hashesA[:maxTxAnnounces/2]},
- doTxNotify{peer: "B", hashes: hashesB[:maxTxAnnounces/2-1]},
- doWait{time: txArriveTimeout, step: true},
-
- // Announce the second half and keep them in the wait list
- doTxNotify{peer: "A", hashes: hashesA[maxTxAnnounces/2 : maxTxAnnounces]},
- doTxNotify{peer: "B", hashes: hashesB[maxTxAnnounces/2-1 : maxTxAnnounces-1]},
-
- // Ensure the hashes are split half and half
- isWaiting(map[string][]common.Hash{
- "A": hashesA[maxTxAnnounces/2 : maxTxAnnounces],
- "B": hashesB[maxTxAnnounces/2-1 : maxTxAnnounces-1],
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": hashesA[:maxTxAnnounces/2],
- "B": hashesB[:maxTxAnnounces/2-1],
- },
- fetching: map[string][]common.Hash{
- "A": hashesA[1643 : 1643+maxTxRetrievals],
- "B": append(append([]common.Hash{}, hashesB[maxTxAnnounces/2-3:maxTxAnnounces/2-1]...), hashesB[:maxTxRetrievals-2]...),
- },
- },
- // Ensure that adding even one more hash results in dropping the hash
- doTxNotify{peer: "A", hashes: []common.Hash{hashesA[maxTxAnnounces]}},
- doTxNotify{peer: "B", hashes: hashesB[maxTxAnnounces-1 : maxTxAnnounces+1]},
-
- isWaiting(map[string][]common.Hash{
- "A": hashesA[maxTxAnnounces/2 : maxTxAnnounces],
- "B": hashesB[maxTxAnnounces/2-1 : maxTxAnnounces],
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": hashesA[:maxTxAnnounces/2],
- "B": hashesB[:maxTxAnnounces/2-1],
- },
- fetching: map[string][]common.Hash{
- "A": hashesA[1643 : 1643+maxTxRetrievals],
- "B": append(append([]common.Hash{}, hashesB[maxTxAnnounces/2-3:maxTxAnnounces/2-1]...), hashesB[:maxTxRetrievals-2]...),
- },
- },
- },
- })
-}
-
-// Tests that underpriced transactions don't get rescheduled after being rejected.
-func TestTransactionFetcherUnderpricedDedup(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- errs := make([]error, len(txs))
- for i := 0; i < len(errs); i++ {
- if i%2 == 0 {
- errs[i] = txpool.ErrUnderpriced
- } else {
- errs[i] = txpool.ErrReplaceUnderpriced
- }
- }
- return errs
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Deliver a transaction through the fetcher, but reject as underpriced
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}},
- doWait{time: txArriveTimeout, step: true},
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0], testTxs[1]}, direct: true},
- isScheduled{nil, nil, nil},
-
- // Try to announce the transaction again, ensure it's not scheduled back
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1], testTxsHashes[2]}}, // [2] is needed to force a step in the fetcher
- isWaiting(map[string][]common.Hash{
- "A": {testTxsHashes[2]},
- }),
- isScheduled{nil, nil, nil},
- },
- })
-}
-
-// Tests that underpriced transactions don't get rescheduled after being rejected,
-// but at the same time there's a hard cap on the number of transactions that are
-// tracked.
-func TestTransactionFetcherUnderpricedDoSProtection(t *testing.T) {
- // Temporarily disable fetch timeouts as they massively mess up the simulated clock
- defer func(timeout time.Duration) { txFetchTimeout = timeout }(txFetchTimeout)
- txFetchTimeout = 24 * time.Hour
-
- // Create a slew of transactions to max out the underpriced set
- var txs []*types.Transaction
- for i := 0; i < maxTxUnderpricedSetSize+1; i++ {
- txs = append(txs, types.NewTransaction(rand.Uint64(), common.Address{byte(rand.Intn(256))}, new(big.Int), 0, new(big.Int), nil))
- }
- hashes := make([]common.Hash, len(txs))
- for i, tx := range txs {
- hashes[i] = tx.Hash()
- }
- // Generate a set of steps to announce and deliver the entire set of transactions
- var steps []interface{}
- for i := 0; i < maxTxUnderpricedSetSize/maxTxRetrievals; i++ {
- steps = append(steps, doTxNotify{peer: "A", hashes: hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals]})
- steps = append(steps, isWaiting(map[string][]common.Hash{
- "A": hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals],
- }))
- steps = append(steps, doWait{time: txArriveTimeout, step: true})
- steps = append(steps, isScheduled{
- tracking: map[string][]common.Hash{
- "A": hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals],
- },
- fetching: map[string][]common.Hash{
- "A": hashes[i*maxTxRetrievals : (i+1)*maxTxRetrievals],
- },
- })
- steps = append(steps, doTxEnqueue{peer: "A", txs: txs[i*maxTxRetrievals : (i+1)*maxTxRetrievals], direct: true})
- steps = append(steps, isWaiting(nil))
- steps = append(steps, isScheduled{nil, nil, nil})
- steps = append(steps, isUnderpriced((i+1)*maxTxRetrievals))
- }
- testTransactionFetcher(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- errs := make([]error, len(txs))
- for i := 0; i < len(errs); i++ {
- errs[i] = txpool.ErrUnderpriced
- }
- return errs
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: append(steps, []interface{}{
- // The preparation of the test has already been done in `steps`, add the last check
- doTxNotify{peer: "A", hashes: []common.Hash{hashes[maxTxUnderpricedSetSize]}},
- doWait{time: txArriveTimeout, step: true},
- doTxEnqueue{peer: "A", txs: []*types.Transaction{txs[maxTxUnderpricedSetSize]}, direct: true},
- isUnderpriced(maxTxUnderpricedSetSize),
- }...),
- })
-}
-
-// Tests that unexpected deliveries don't corrupt the internal state.
-func TestTransactionFetcherOutOfBoundDeliveries(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Deliver something out of the blue
- isWaiting(nil),
- isScheduled{nil, nil, nil},
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}, direct: false},
- isWaiting(nil),
- isScheduled{nil, nil, nil},
-
- // Set up a few hashes into various stages
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[1]}},
- doWait{time: txArriveTimeout, step: true},
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[2]}},
-
- isWaiting(map[string][]common.Hash{
- "A": {testTxsHashes[2]},
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[0], testTxsHashes[1]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- },
- // Deliver everything and more out of the blue
- doTxEnqueue{peer: "B", txs: []*types.Transaction{testTxs[0], testTxs[1], testTxs[2], testTxs[3]}, direct: true},
- isWaiting(nil),
- isScheduled{
- tracking: nil,
- fetching: nil,
- dangling: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- },
- },
- })
-}
-
-// Tests that dropping a peer cleans out all internal data structures in all the
-// live or dangling stages.
-func TestTransactionFetcherDrop(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Set up a few hashes into various stages
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}},
- doWait{time: txArriveTimeout, step: true},
- doTxNotify{peer: "A", hashes: []common.Hash{{0x02}}},
- doWait{time: txArriveTimeout, step: true},
- doTxNotify{peer: "A", hashes: []common.Hash{{0x03}}},
-
- isWaiting(map[string][]common.Hash{
- "A": {{0x03}},
- }),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}, {0x02}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}},
- },
- },
- // Drop the peer and ensure everything's cleaned out
- doDrop("A"),
- isWaiting(nil),
- isScheduled{nil, nil, nil},
-
- // Push the node into a dangling (timeout) state
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- },
- },
- doWait{time: txFetchTimeout, step: true},
- isWaiting(nil),
- isScheduled{
- tracking: nil,
- fetching: nil,
- dangling: map[string][]common.Hash{
- "A": {},
- },
- },
- // Drop the peer and ensure everything's cleaned out
- doDrop("A"),
- isWaiting(nil),
- isScheduled{nil, nil, nil},
- },
- })
-}
-
-// Tests that dropping a peer instantly reschedules failed announcements to any
-// available peer.
-func TestTransactionFetcherDropRescheduling(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Set up a few hashes into various stages
- doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}},
- doWait{time: txArriveTimeout, step: true},
- doTxNotify{peer: "B", hashes: []common.Hash{{0x01}}},
-
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "A": {{0x01}},
- "B": {{0x01}},
- },
- fetching: map[string][]common.Hash{
- "A": {{0x01}},
- },
- },
- // Drop the peer and ensure everything's cleaned out
- doDrop("A"),
- isWaiting(nil),
- isScheduled{
- tracking: map[string][]common.Hash{
- "B": {{0x01}},
- },
- fetching: map[string][]common.Hash{
- "B": {{0x01}},
- },
- },
- },
- })
-}
-
-// Tests that announced transactions with the wrong transaction type or size will
-// result in a dropped peer.
-func TestInvalidAnnounceMetadata(t *testing.T) {
- drop := make(chan string, 2)
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- func(peer string) { drop <- peer },
- )
- },
- steps: []interface{}{
- // Initial announcement to get something into the waitlist
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}, types: []byte{testTxs[0].Type(), testTxs[1].Type()}, sizes: []uint32{uint32(testTxs[0].Size()), uint32(testTxs[1].Size())}},
- isWaitingWithMeta(map[string][]announce{
- "A": {
- {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(uint32(testTxs[0].Size()))},
- {testTxsHashes[1], typeptr(testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))},
- },
- }),
- // Announce from new peers conflicting transactions
- doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{1024 + uint32(testTxs[0].Size())}},
- doTxNotify{peer: "C", hashes: []common.Hash{testTxsHashes[1]}, types: []byte{1 + testTxs[1].Type()}, sizes: []uint32{uint32(testTxs[1].Size())}},
- isWaitingWithMeta(map[string][]announce{
- "A": {
- {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(uint32(testTxs[0].Size()))},
- {testTxsHashes[1], typeptr(testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))},
- },
- "B": {
- {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(1024 + uint32(testTxs[0].Size()))},
- },
- "C": {
- {testTxsHashes[1], typeptr(1 + testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))},
- },
- }),
- // Schedule all the transactions for retrieval
- doWait{time: txArriveTimeout, step: true},
- isWaitingWithMeta(nil),
- isScheduledWithMeta{
- tracking: map[string][]announce{
- "A": {
- {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(uint32(testTxs[0].Size()))},
- {testTxsHashes[1], typeptr(testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))},
- },
- "B": {
- {testTxsHashes[0], typeptr(testTxs[0].Type()), sizeptr(1024 + uint32(testTxs[0].Size()))},
- },
- "C": {
- {testTxsHashes[1], typeptr(1 + testTxs[1].Type()), sizeptr(uint32(testTxs[1].Size()))},
- },
- },
- fetching: map[string][]common.Hash{
- "A": {testTxsHashes[0]},
- "C": {testTxsHashes[1]},
- },
- },
- // Deliver the transactions and wait for B to be dropped
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0], testTxs[1]}},
- doFunc(func() { <-drop }),
- doFunc(func() { <-drop }),
- },
- })
-}
-
-// This test reproduces a crash caught by the fuzzer. The root cause was a
-// dangling transaction timing out and clashing on re-add with a concurrently
-// announced one.
-func TestTransactionFetcherFuzzCrash01(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Get a transaction into fetching mode and make it dangling with a broadcast
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}},
-
- // Notify the dangling transaction once more and crash via a timeout
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txFetchTimeout, step: true},
- },
- })
-}
-
-// This test reproduces a crash caught by the fuzzer. The root cause was a
-// dangling transaction getting peer-dropped and clashing on re-add with a
-// concurrently announced one.
-func TestTransactionFetcherFuzzCrash02(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Get a transaction into fetching mode and make it dangling with a broadcast
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}},
-
- // Notify the dangling transaction once more, re-fetch, and crash via a drop and timeout
- doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
- doDrop("A"),
- doWait{time: txFetchTimeout, step: true},
- },
- })
-}
-
-// This test reproduces a crash caught by the fuzzer. The root cause was a
-// dangling transaction getting rescheduled via a partial delivery, clashing
-// with a concurrent notify.
-func TestTransactionFetcherFuzzCrash03(t *testing.T) {
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error { return nil },
- nil,
- )
- },
- steps: []interface{}{
- // Get a transaction into fetching mode and make it dangling with a broadcast
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0], testTxsHashes[1]}},
- doWait{time: txFetchTimeout, step: true},
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0], testTxs[1]}},
-
- // Notify the dangling transaction once more, partially deliver, clash&crash with a timeout
- doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
-
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[1]}, direct: true},
- doWait{time: txFetchTimeout, step: true},
- },
- })
-}
-
-// This test reproduces a crash caught by the fuzzer. The root cause was a
-// dangling transaction getting rescheduled via a disconnect, clashing with
-// a concurrent notify.
-func TestTransactionFetcherFuzzCrash04(t *testing.T) {
- // Create a channel to control when tx requests can fail
- proceed := make(chan struct{})
-
- testTransactionFetcherParallel(t, txFetcherTest{
- init: func() *TxFetcher {
- return NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- return make([]error, len(txs))
- },
- func(string, []common.Hash) error {
- <-proceed
- return errors.New("peer disconnected")
- },
- nil,
- )
- },
- steps: []interface{}{
- // Get a transaction into fetching mode and make it dangling with a broadcast
- doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
- doTxEnqueue{peer: "A", txs: []*types.Transaction{testTxs[0]}},
-
- // Notify the dangling transaction once more, re-fetch, and crash via an in-flight disconnect
- doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}},
- doWait{time: txArriveTimeout, step: true},
- doFunc(func() {
- proceed <- struct{}{} // Allow peer A to return the failure
- }),
- doWait{time: 0, step: true},
- doWait{time: txFetchTimeout, step: true},
- },
- })
-}
-
-func testTransactionFetcherParallel(t *testing.T, tt txFetcherTest) {
- t.Parallel()
- testTransactionFetcher(t, tt)
-}
-
-func testTransactionFetcher(t *testing.T, tt txFetcherTest) {
- // Create a fetcher and hook into it's simulated fields
- clock := new(mclock.Simulated)
- wait := make(chan struct{})
-
- fetcher := tt.init()
- fetcher.clock = clock
- fetcher.step = wait
- fetcher.rand = rand.New(rand.NewSource(0x3a29))
-
- fetcher.Start()
- defer fetcher.Stop()
-
- defer func() { // drain the wait chan on exit
- for {
- select {
- case <-wait:
- default:
- return
- }
- }
- }()
-
- // Crunch through all the test steps and execute them
- for i, step := range tt.steps {
- // Auto-expand certain steps to ones with metadata
- switch old := step.(type) {
- case isWaiting:
- new := make(isWaitingWithMeta)
- for peer, hashes := range old {
- for _, hash := range hashes {
- new[peer] = append(new[peer], announce{hash, nil, nil})
- }
- }
- step = new
-
- case isScheduled:
- new := isScheduledWithMeta{
- tracking: make(map[string][]announce),
- fetching: old.fetching,
- dangling: old.dangling,
- }
- for peer, hashes := range old.tracking {
- for _, hash := range hashes {
- new.tracking[peer] = append(new.tracking[peer], announce{hash, nil, nil})
- }
- }
- step = new
- }
- // Process the original or expanded steps
- switch step := step.(type) {
- case doTxNotify:
- if err := fetcher.Notify(step.peer, step.types, step.sizes, step.hashes); err != nil {
- t.Errorf("step %d: %v", i, err)
- }
- <-wait // Fetcher needs to process this, wait until it's done
- select {
- case <-wait:
- panic("wtf")
- case <-time.After(time.Millisecond):
- }
-
- case doTxEnqueue:
- if err := fetcher.Enqueue(step.peer, step.txs, step.direct); err != nil {
- t.Errorf("step %d: %v", i, err)
- }
- <-wait // Fetcher needs to process this, wait until it's done
-
- case doWait:
- clock.Run(step.time)
- if step.step {
- <-wait // Fetcher supposed to do something, wait until it's done
- }
-
- case doDrop:
- if err := fetcher.Drop(string(step)); err != nil {
- t.Errorf("step %d: %v", i, err)
- }
- <-wait // Fetcher needs to process this, wait until it's done
-
- case doFunc:
- step()
-
- case isWaitingWithMeta:
- // We need to check that the waiting list (stage 1) internals
- // match with the expected set. Check the peer->hash mappings
- // first.
- for peer, announces := range step {
- waiting := fetcher.waitslots[peer]
- if waiting == nil {
- t.Errorf("step %d: peer %s missing from waitslots", i, peer)
- continue
- }
- for _, ann := range announces {
- if meta, ok := waiting[ann.hash]; !ok {
- t.Errorf("step %d, peer %s: hash %x missing from waitslots", i, peer, ann.hash)
- } else {
- if (meta == nil && (ann.kind != nil || ann.size != nil)) ||
- (meta != nil && (ann.kind == nil || ann.size == nil)) ||
- (meta != nil && (meta.kind != *ann.kind || meta.size != *ann.size)) {
- t.Errorf("step %d, peer %s, hash %x: waitslot metadata mismatch: want %v, have %v/%v", i, peer, ann.hash, meta, *ann.kind, *ann.size)
- }
- }
- }
- for hash, meta := range waiting {
- ann := announce{hash: hash}
- if meta != nil {
- ann.kind, ann.size = &meta.kind, &meta.size
- }
- if !containsAnnounce(announces, ann) {
- t.Errorf("step %d, peer %s: announce %v extra in waitslots", i, peer, ann)
- }
- }
- }
- for peer := range fetcher.waitslots {
- if _, ok := step[peer]; !ok {
- t.Errorf("step %d: peer %s extra in waitslots", i, peer)
- }
- }
- // Peer->hash sets correct, check the hash->peer and timeout sets
- for peer, announces := range step {
- for _, ann := range announces {
- if _, ok := fetcher.waitlist[ann.hash][peer]; !ok {
- t.Errorf("step %d, hash %x: peer %s missing from waitlist", i, ann.hash, peer)
- }
- if _, ok := fetcher.waittime[ann.hash]; !ok {
- t.Errorf("step %d: hash %x missing from waittime", i, ann.hash)
- }
- }
- }
- for hash, peers := range fetcher.waitlist {
- if len(peers) == 0 {
- t.Errorf("step %d, hash %x: empty peerset in waitlist", i, hash)
- }
- for peer := range peers {
- if !containsHashInAnnounces(step[peer], hash) {
- t.Errorf("step %d, hash %x: peer %s extra in waitlist", i, hash, peer)
- }
- }
- }
- for hash := range fetcher.waittime {
- var found bool
- for _, announces := range step {
- if containsHashInAnnounces(announces, hash) {
- found = true
- break
- }
- }
- if !found {
- t.Errorf("step %d,: hash %x extra in waittime", i, hash)
- }
- }
-
- case isScheduledWithMeta:
- // Check that all scheduled announces are accounted for and no
- // extra ones are present.
- for peer, announces := range step.tracking {
- scheduled := fetcher.announces[peer]
- if scheduled == nil {
- t.Errorf("step %d: peer %s missing from announces", i, peer)
- continue
- }
- for _, ann := range announces {
- if meta, ok := scheduled[ann.hash]; !ok {
- t.Errorf("step %d, peer %s: hash %x missing from announces", i, peer, ann.hash)
- } else {
- if (meta == nil && (ann.kind != nil || ann.size != nil)) ||
- (meta != nil && (ann.kind == nil || ann.size == nil)) ||
- (meta != nil && (meta.kind != *ann.kind || meta.size != *ann.size)) {
- t.Errorf("step %d, peer %s, hash %x: announce metadata mismatch: want %v, have %v/%v", i, peer, ann.hash, meta, *ann.kind, *ann.size)
- }
- }
- }
- for hash, meta := range scheduled {
- ann := announce{hash: hash}
- if meta != nil {
- ann.kind, ann.size = &meta.kind, &meta.size
- }
- if !containsAnnounce(announces, ann) {
- t.Errorf("step %d, peer %s: announce %x extra in announces", i, peer, hash)
- }
- }
- }
- for peer := range fetcher.announces {
- if _, ok := step.tracking[peer]; !ok {
- t.Errorf("step %d: peer %s extra in announces", i, peer)
- }
- }
- // Check that all announces required to be fetching are in the
- // appropriate sets
- for peer, hashes := range step.fetching {
- request := fetcher.requests[peer]
- if request == nil {
- t.Errorf("step %d: peer %s missing from requests", i, peer)
- continue
- }
- for _, hash := range hashes {
- if !containsHash(request.hashes, hash) {
- t.Errorf("step %d, peer %s: hash %x missing from requests", i, peer, hash)
- }
- }
- for _, hash := range request.hashes {
- if !containsHash(hashes, hash) {
- t.Errorf("step %d, peer %s: hash %x extra in requests", i, peer, hash)
- }
- }
- }
- for peer := range fetcher.requests {
- if _, ok := step.fetching[peer]; !ok {
- if _, ok := step.dangling[peer]; !ok {
- t.Errorf("step %d: peer %s extra in requests", i, peer)
- }
- }
- }
- for peer, hashes := range step.fetching {
- for _, hash := range hashes {
- if _, ok := fetcher.fetching[hash]; !ok {
- t.Errorf("step %d, peer %s: hash %x missing from fetching", i, peer, hash)
- }
- }
- }
- for hash := range fetcher.fetching {
- var found bool
- for _, req := range fetcher.requests {
- if containsHash(req.hashes, hash) {
- found = true
- break
- }
- }
- if !found {
- t.Errorf("step %d: hash %x extra in fetching", i, hash)
- }
- }
- for _, hashes := range step.fetching {
- for _, hash := range hashes {
- alternates := fetcher.alternates[hash]
- if alternates == nil {
- t.Errorf("step %d: hash %x missing from alternates", i, hash)
- continue
- }
- for peer := range alternates {
- if _, ok := fetcher.announces[peer]; !ok {
- t.Errorf("step %d: peer %s extra in alternates", i, peer)
- continue
- }
- if _, ok := fetcher.announces[peer][hash]; !ok {
- t.Errorf("step %d, peer %s: hash %x extra in alternates", i, hash, peer)
- continue
- }
- }
- for p := range fetcher.announced[hash] {
- if _, ok := alternates[p]; !ok {
- t.Errorf("step %d, hash %x: peer %s missing from alternates", i, hash, p)
- continue
- }
- }
- }
- }
- for peer, hashes := range step.dangling {
- request := fetcher.requests[peer]
- if request == nil {
- t.Errorf("step %d: peer %s missing from requests", i, peer)
- continue
- }
- for _, hash := range hashes {
- if !containsHash(request.hashes, hash) {
- t.Errorf("step %d, peer %s: hash %x missing from requests", i, peer, hash)
- }
- }
- for _, hash := range request.hashes {
- if !containsHash(hashes, hash) {
- t.Errorf("step %d, peer %s: hash %x extra in requests", i, peer, hash)
- }
- }
- }
- // Check that all transaction announces that are scheduled for
- // retrieval but not actively being downloaded are tracked only
- // in the stage 2 `announced` map.
- var queued []common.Hash
- for _, announces := range step.tracking {
- for _, ann := range announces {
- var found bool
- for _, hs := range step.fetching {
- if containsHash(hs, ann.hash) {
- found = true
- break
- }
- }
- if !found {
- queued = append(queued, ann.hash)
- }
- }
- }
- for _, hash := range queued {
- if _, ok := fetcher.announced[hash]; !ok {
- t.Errorf("step %d: hash %x missing from announced", i, hash)
- }
- }
- for hash := range fetcher.announced {
- if !containsHash(queued, hash) {
- t.Errorf("step %d: hash %x extra in announced", i, hash)
- }
- }
-
- case isUnderpriced:
- if fetcher.underpriced.Len() != int(step) {
- t.Errorf("step %d: underpriced set size mismatch: have %d, want %d", i, fetcher.underpriced.Len(), step)
- }
-
- default:
- t.Fatalf("step %d: unknown step type %T", i, step)
- }
- // After every step, cross validate the internal uniqueness invariants
- // between stage one and stage two.
- for hash := range fetcher.waittime {
- if _, ok := fetcher.announced[hash]; ok {
- t.Errorf("step %d: hash %s present in both stage 1 and 2", i, hash)
- }
- }
- }
-}
-
-// containsAnnounce returns whether an announcement is contained within a slice
-// of announcements.
-func containsAnnounce(slice []announce, ann announce) bool {
- for _, have := range slice {
- if have.hash == ann.hash {
- if have.kind == nil || ann.kind == nil {
- if have.kind != ann.kind {
- return false
- }
- } else if *have.kind != *ann.kind {
- return false
- }
- if have.size == nil || ann.size == nil {
- if have.size != ann.size {
- return false
- }
- } else if *have.size != *ann.size {
- return false
- }
- return true
- }
- }
- return false
-}
-
-// containsHashInAnnounces returns whether a hash is contained within a slice
-// of announcements.
-func containsHashInAnnounces(slice []announce, hash common.Hash) bool {
- for _, have := range slice {
- if have.hash == hash {
- return true
- }
- }
- return false
-}
-
-// containsHash returns whether a hash is contained within a hash slice.
-func containsHash(slice []common.Hash, hash common.Hash) bool {
- for _, have := range slice {
- if have == hash {
- return true
- }
- }
- return false
-}
-
-// Tests that a transaction is forgotten after the timeout.
-func TestTransactionForgotten(t *testing.T) {
- fetcher := NewTxFetcher(
- func(common.Hash) bool { return false },
- func(txs []*types.Transaction) []error {
- errs := make([]error, len(txs))
- for i := 0; i < len(errs); i++ {
- errs[i] = txpool.ErrUnderpriced
- }
- return errs
- },
- func(string, []common.Hash) error { return nil },
- func(string) {},
- )
- fetcher.Start()
- defer fetcher.Stop()
- // Create one TX which is 5 minutes old, and one which is recent
- tx1 := types.NewTx(&types.LegacyTx{Nonce: 0})
- tx1.SetTime(time.Now().Add(-maxTxUnderpricedTimeout - 1*time.Second))
- tx2 := types.NewTx(&types.LegacyTx{Nonce: 1})
-
- // Enqueue both in the fetcher. They will be immediately tagged as underpriced
- if err := fetcher.Enqueue("asdf", []*types.Transaction{tx1, tx2}, false); err != nil {
- t.Fatal(err)
- }
- // isKnownUnderpriced should trigger removal of the first tx (no longer be known underpriced)
- if fetcher.isKnownUnderpriced(tx1.Hash()) {
- t.Fatal("transaction should be forgotten by now")
- }
- // isKnownUnderpriced should not trigger removal of the second
- if !fetcher.isKnownUnderpriced(tx2.Hash()) {
- t.Fatal("transaction should be known underpriced")
- }
-}
diff --git a/eth/filters/api.go b/eth/filters/api.go
deleted file mode 100644
index a4eaa9cec8..0000000000
--- a/eth/filters/api.go
+++ /dev/null
@@ -1,609 +0,0 @@
-// Copyright 2015 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 filters
-
-import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-var (
- errInvalidTopic = errors.New("invalid topic(s)")
- errFilterNotFound = errors.New("filter not found")
- errInvalidBlockRange = errors.New("invalid block range params")
- errExceedMaxTopics = errors.New("exceed max topics")
-)
-
-// The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0
-const maxTopics = 4
-
-// filter is a helper struct that holds meta information over the filter type
-// and associated subscription in the event system.
-type filter struct {
- typ Type
- deadline *time.Timer // filter is inactive when deadline triggers
- hashes []common.Hash
- fullTx bool
- txs []*types.Transaction
- crit FilterCriteria
- logs []*types.Log
- s *Subscription // associated subscription in event system
-}
-
-// FilterAPI offers support to create and manage filters. This will allow external clients to retrieve various
-// information related to the Ethereum protocol such as blocks, transactions and logs.
-type FilterAPI struct {
- sys *FilterSystem
- events *EventSystem
- filtersMu sync.Mutex
- filters map[rpc.ID]*filter
- timeout time.Duration
-}
-
-// NewFilterAPI returns a new FilterAPI instance.
-func NewFilterAPI(system *FilterSystem, lightMode bool) *FilterAPI {
- api := &FilterAPI{
- sys: system,
- events: NewEventSystem(system, lightMode),
- filters: make(map[rpc.ID]*filter),
- timeout: system.cfg.Timeout,
- }
- go api.timeoutLoop(system.cfg.Timeout)
-
- return api
-}
-
-// timeoutLoop runs at the interval set by 'timeout' and deletes filters
-// that have not been recently used. It is started when the API is created.
-func (api *FilterAPI) timeoutLoop(timeout time.Duration) {
- var toUninstall []*Subscription
- ticker := time.NewTicker(timeout)
- defer ticker.Stop()
- for {
- <-ticker.C
- api.filtersMu.Lock()
- for id, f := range api.filters {
- select {
- case <-f.deadline.C:
- toUninstall = append(toUninstall, f.s)
- delete(api.filters, id)
- default:
- continue
- }
- }
- api.filtersMu.Unlock()
-
- // Unsubscribes are processed outside the lock to avoid the following scenario:
- // event loop attempts broadcasting events to still active filters while
- // Unsubscribe is waiting for it to process the uninstall request.
- for _, s := range toUninstall {
- s.Unsubscribe()
- }
- toUninstall = nil
- }
-}
-
-// NewPendingTransactionFilter creates a filter that fetches pending transactions
-// as transactions enter the pending state.
-//
-// It is part of the filter package because this filter can be used through the
-// `eth_getFilterChanges` polling method that is also used for log filters.
-func (api *FilterAPI) NewPendingTransactionFilter(fullTx *bool) rpc.ID {
- var (
- pendingTxs = make(chan []*types.Transaction)
- pendingTxSub = api.events.SubscribePendingTxs(pendingTxs)
- )
-
- api.filtersMu.Lock()
- api.filters[pendingTxSub.ID] = &filter{typ: PendingTransactionsSubscription, fullTx: fullTx != nil && *fullTx, deadline: time.NewTimer(api.timeout), txs: make([]*types.Transaction, 0), s: pendingTxSub}
- api.filtersMu.Unlock()
-
- go func() {
- for {
- select {
- case pTx := <-pendingTxs:
- api.filtersMu.Lock()
- if f, found := api.filters[pendingTxSub.ID]; found {
- f.txs = append(f.txs, pTx...)
- }
- api.filtersMu.Unlock()
- case <-pendingTxSub.Err():
- api.filtersMu.Lock()
- delete(api.filters, pendingTxSub.ID)
- api.filtersMu.Unlock()
- return
- }
- }
- }()
-
- return pendingTxSub.ID
-}
-
-// NewPendingTransactions creates a subscription that is triggered each time a
-// transaction enters the transaction pool. If fullTx is true the full tx is
-// sent to the client, otherwise the hash is sent.
-func (api *FilterAPI) NewPendingTransactions(ctx context.Context, fullTx *bool) (*rpc.Subscription, error) {
- notifier, supported := rpc.NotifierFromContext(ctx)
- if !supported {
- return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
- }
-
- rpcSub := notifier.CreateSubscription()
-
- go func() {
- txs := make(chan []*types.Transaction, 128)
- pendingTxSub := api.events.SubscribePendingTxs(txs)
- chainConfig := api.sys.backend.ChainConfig()
-
- for {
- select {
- case txs := <-txs:
- // To keep the original behaviour, send a single tx hash in one notification.
- // TODO(rjl493456442) Send a batch of tx hashes in one notification
- latest := api.sys.backend.CurrentHeader()
- for _, tx := range txs {
- if fullTx != nil && *fullTx {
- rpcTx := ethapi.NewRPCPendingTransaction(tx, latest, chainConfig)
- notifier.Notify(rpcSub.ID, rpcTx)
- } else {
- notifier.Notify(rpcSub.ID, tx.Hash())
- }
- }
- case <-rpcSub.Err():
- pendingTxSub.Unsubscribe()
- return
- case <-notifier.Closed():
- pendingTxSub.Unsubscribe()
- return
- }
- }
- }()
-
- return rpcSub, nil
-}
-
-// NewBlockFilter creates a filter that fetches blocks that are imported into the chain.
-// It is part of the filter package since polling goes with eth_getFilterChanges.
-func (api *FilterAPI) NewBlockFilter() rpc.ID {
- var (
- headers = make(chan *types.Header)
- headerSub = api.events.SubscribeNewHeads(headers)
- )
-
- api.filtersMu.Lock()
- api.filters[headerSub.ID] = &filter{typ: BlocksSubscription, deadline: time.NewTimer(api.timeout), hashes: make([]common.Hash, 0), s: headerSub}
- api.filtersMu.Unlock()
-
- go func() {
- for {
- select {
- case h := <-headers:
- api.filtersMu.Lock()
- if f, found := api.filters[headerSub.ID]; found {
- f.hashes = append(f.hashes, h.Hash())
- }
- api.filtersMu.Unlock()
- case <-headerSub.Err():
- api.filtersMu.Lock()
- delete(api.filters, headerSub.ID)
- api.filtersMu.Unlock()
- return
- }
- }
- }()
-
- return headerSub.ID
-}
-
-// NewHeads send a notification each time a new (header) block is appended to the chain.
-func (api *FilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, error) {
- notifier, supported := rpc.NotifierFromContext(ctx)
- if !supported {
- return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
- }
-
- rpcSub := notifier.CreateSubscription()
-
- go func() {
- headers := make(chan *types.Header)
- headersSub := api.events.SubscribeNewHeads(headers)
-
- for {
- select {
- case h := <-headers:
- notifier.Notify(rpcSub.ID, h)
- case <-rpcSub.Err():
- headersSub.Unsubscribe()
- return
- case <-notifier.Closed():
- headersSub.Unsubscribe()
- return
- }
- }
- }()
-
- return rpcSub, nil
-}
-
-// Logs creates a subscription that fires for all new log that match the given filter criteria.
-func (api *FilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subscription, error) {
- notifier, supported := rpc.NotifierFromContext(ctx)
- if !supported {
- return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
- }
-
- var (
- rpcSub = notifier.CreateSubscription()
- matchedLogs = make(chan []*types.Log)
- )
-
- logsSub, err := api.events.SubscribeLogs(ethereum.FilterQuery(crit), matchedLogs)
- if err != nil {
- return nil, err
- }
-
- go func() {
- for {
- select {
- case logs := <-matchedLogs:
- for _, log := range logs {
- log := log
- notifier.Notify(rpcSub.ID, &log)
- }
- case <-rpcSub.Err(): // client send an unsubscribe request
- logsSub.Unsubscribe()
- return
- case <-notifier.Closed(): // connection dropped
- logsSub.Unsubscribe()
- return
- }
- }
- }()
-
- return rpcSub, nil
-}
-
-// FilterCriteria represents a request to create a new filter.
-// Same as ethereum.FilterQuery but with UnmarshalJSON() method.
-type FilterCriteria ethereum.FilterQuery
-
-// NewFilter creates a new filter and returns the filter id. It can be
-// used to retrieve logs when the state changes. This method cannot be
-// used to fetch logs that are already stored in the state.
-//
-// Default criteria for the from and to block are "latest".
-// Using "latest" as block number will return logs for mined blocks.
-// Using "pending" as block number returns logs for not yet mined (pending) blocks.
-// In case logs are removed (chain reorg) previously returned logs are returned
-// again but with the removed property set to true.
-//
-// In case "fromBlock" > "toBlock" an error is returned.
-func (api *FilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) {
- logs := make(chan []*types.Log)
- logsSub, err := api.events.SubscribeLogs(ethereum.FilterQuery(crit), logs)
- if err != nil {
- return "", err
- }
-
- api.filtersMu.Lock()
- api.filters[logsSub.ID] = &filter{typ: LogsSubscription, crit: crit, deadline: time.NewTimer(api.timeout), logs: make([]*types.Log, 0), s: logsSub}
- api.filtersMu.Unlock()
-
- go func() {
- for {
- select {
- case l := <-logs:
- api.filtersMu.Lock()
- if f, found := api.filters[logsSub.ID]; found {
- f.logs = append(f.logs, l...)
- }
- api.filtersMu.Unlock()
- case <-logsSub.Err():
- api.filtersMu.Lock()
- delete(api.filters, logsSub.ID)
- api.filtersMu.Unlock()
- return
- }
- }
- }()
-
- return logsSub.ID, nil
-}
-
-// GetLogs returns logs matching the given argument that are stored within the state.
-func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) {
- if len(crit.Topics) > maxTopics {
- return nil, errExceedMaxTopics
- }
- var filter *Filter
- if crit.BlockHash != nil {
- // Block filter requested, construct a single-shot filter
- filter = api.sys.NewBlockFilter(*crit.BlockHash, crit.Addresses, crit.Topics)
- } else {
- // Convert the RPC block numbers into internal representations
- begin := rpc.LatestBlockNumber.Int64()
- if crit.FromBlock != nil {
- begin = crit.FromBlock.Int64()
- }
- end := rpc.LatestBlockNumber.Int64()
- if crit.ToBlock != nil {
- end = crit.ToBlock.Int64()
- }
- if begin > 0 && end > 0 && begin > end {
- return nil, errInvalidBlockRange
- }
- // Construct the range filter
- filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics)
- }
- // Run the filter and return all the logs
- logs, err := filter.Logs(ctx)
- if err != nil {
- return nil, err
- }
- return returnLogs(logs), err
-}
-
-// UninstallFilter removes the filter with the given filter id.
-func (api *FilterAPI) UninstallFilter(id rpc.ID) bool {
- api.filtersMu.Lock()
- f, found := api.filters[id]
- if found {
- delete(api.filters, id)
- }
- api.filtersMu.Unlock()
- if found {
- f.s.Unsubscribe()
- }
-
- return found
-}
-
-// GetFilterLogs returns the logs for the filter with the given id.
-// If the filter could not be found an empty array of logs is returned.
-func (api *FilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*types.Log, error) {
- api.filtersMu.Lock()
- f, found := api.filters[id]
- api.filtersMu.Unlock()
-
- if !found || f.typ != LogsSubscription {
- return nil, errFilterNotFound
- }
-
- var filter *Filter
- if f.crit.BlockHash != nil {
- // Block filter requested, construct a single-shot filter
- filter = api.sys.NewBlockFilter(*f.crit.BlockHash, f.crit.Addresses, f.crit.Topics)
- } else {
- // Convert the RPC block numbers into internal representations
- begin := rpc.LatestBlockNumber.Int64()
- if f.crit.FromBlock != nil {
- begin = f.crit.FromBlock.Int64()
- }
- end := rpc.LatestBlockNumber.Int64()
- if f.crit.ToBlock != nil {
- end = f.crit.ToBlock.Int64()
- }
- // Construct the range filter
- filter = api.sys.NewRangeFilter(begin, end, f.crit.Addresses, f.crit.Topics)
- }
- // Run the filter and return all the logs
- logs, err := filter.Logs(ctx)
- if err != nil {
- return nil, err
- }
- return returnLogs(logs), nil
-}
-
-// GetFilterChanges returns the logs for the filter with the given id since
-// last time it was called. This can be used for polling.
-//
-// For pending transaction and block filters the result is []common.Hash.
-// (pending)Log filters return []Log.
-func (api *FilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) {
- api.filtersMu.Lock()
- defer api.filtersMu.Unlock()
-
- chainConfig := api.sys.backend.ChainConfig()
- latest := api.sys.backend.CurrentHeader()
-
- if f, found := api.filters[id]; found {
- if !f.deadline.Stop() {
- // timer expired but filter is not yet removed in timeout loop
- // receive timer value and reset timer
- <-f.deadline.C
- }
- f.deadline.Reset(api.timeout)
-
- switch f.typ {
- case BlocksSubscription:
- hashes := f.hashes
- f.hashes = nil
- return returnHashes(hashes), nil
- case PendingTransactionsSubscription:
- if f.fullTx {
- txs := make([]*ethapi.RPCTransaction, 0, len(f.txs))
- for _, tx := range f.txs {
- txs = append(txs, ethapi.NewRPCPendingTransaction(tx, latest, chainConfig))
- }
- f.txs = nil
- return txs, nil
- } else {
- hashes := make([]common.Hash, 0, len(f.txs))
- for _, tx := range f.txs {
- hashes = append(hashes, tx.Hash())
- }
- f.txs = nil
- return hashes, nil
- }
- case LogsSubscription, MinedAndPendingLogsSubscription:
- logs := f.logs
- f.logs = nil
- return returnLogs(logs), nil
- }
- }
-
- return []interface{}{}, errFilterNotFound
-}
-
-// returnHashes is a helper that will return an empty hash array case the given hash array is nil,
-// otherwise the given hashes array is returned.
-func returnHashes(hashes []common.Hash) []common.Hash {
- if hashes == nil {
- return []common.Hash{}
- }
- return hashes
-}
-
-// returnLogs is a helper that will return an empty log array in case the given logs array is nil,
-// otherwise the given logs array is returned.
-func returnLogs(logs []*types.Log) []*types.Log {
- if logs == nil {
- return []*types.Log{}
- }
- return logs
-}
-
-// UnmarshalJSON sets *args fields with given data.
-func (args *FilterCriteria) UnmarshalJSON(data []byte) error {
- type input struct {
- BlockHash *common.Hash `json:"blockHash"`
- FromBlock *rpc.BlockNumber `json:"fromBlock"`
- ToBlock *rpc.BlockNumber `json:"toBlock"`
- Addresses interface{} `json:"address"`
- Topics []interface{} `json:"topics"`
- }
-
- var raw input
- if err := json.Unmarshal(data, &raw); err != nil {
- return err
- }
-
- if raw.BlockHash != nil {
- if raw.FromBlock != nil || raw.ToBlock != nil {
- // BlockHash is mutually exclusive with FromBlock/ToBlock criteria
- return errors.New("cannot specify both BlockHash and FromBlock/ToBlock, choose one or the other")
- }
- args.BlockHash = raw.BlockHash
- } else {
- if raw.FromBlock != nil {
- args.FromBlock = big.NewInt(raw.FromBlock.Int64())
- }
-
- if raw.ToBlock != nil {
- args.ToBlock = big.NewInt(raw.ToBlock.Int64())
- }
- }
-
- args.Addresses = []common.Address{}
-
- if raw.Addresses != nil {
- // raw.Address can contain a single address or an array of addresses
- switch rawAddr := raw.Addresses.(type) {
- case []interface{}:
- for i, addr := range rawAddr {
- if strAddr, ok := addr.(string); ok {
- addr, err := decodeAddress(strAddr)
- if err != nil {
- return fmt.Errorf("invalid address at index %d: %v", i, err)
- }
- args.Addresses = append(args.Addresses, addr)
- } else {
- return fmt.Errorf("non-string address at index %d", i)
- }
- }
- case string:
- addr, err := decodeAddress(rawAddr)
- if err != nil {
- return fmt.Errorf("invalid address: %v", err)
- }
- args.Addresses = []common.Address{addr}
- default:
- return errors.New("invalid addresses in query")
- }
- }
-
- // topics is an array consisting of strings and/or arrays of strings.
- // JSON null values are converted to common.Hash{} and ignored by the filter manager.
- if len(raw.Topics) > 0 {
- args.Topics = make([][]common.Hash, len(raw.Topics))
- for i, t := range raw.Topics {
- switch topic := t.(type) {
- case nil:
- // ignore topic when matching logs
-
- case string:
- // match specific topic
- top, err := decodeTopic(topic)
- if err != nil {
- return err
- }
- args.Topics[i] = []common.Hash{top}
-
- case []interface{}:
- // or case e.g. [null, "topic0", "topic1"]
- for _, rawTopic := range topic {
- if rawTopic == nil {
- // null component, match all
- args.Topics[i] = nil
- break
- }
- if topic, ok := rawTopic.(string); ok {
- parsed, err := decodeTopic(topic)
- if err != nil {
- return err
- }
- args.Topics[i] = append(args.Topics[i], parsed)
- } else {
- return errInvalidTopic
- }
- }
- default:
- return errInvalidTopic
- }
- }
- }
-
- return nil
-}
-
-func decodeAddress(s string) (common.Address, error) {
- b, err := hexutil.Decode(s)
- if err == nil && len(b) != common.AddressLength {
- err = fmt.Errorf("hex has invalid length %d after decoding; expected %d for address", len(b), common.AddressLength)
- }
- return common.BytesToAddress(b), err
-}
-
-func decodeTopic(s string) (common.Hash, error) {
- b, err := hexutil.Decode(s)
- if err == nil && len(b) != common.HashLength {
- err = fmt.Errorf("hex has invalid length %d after decoding; expected %d for topic", len(b), common.HashLength)
- }
- return common.BytesToHash(b), err
-}
diff --git a/eth/filters/api_test.go b/eth/filters/api_test.go
deleted file mode 100644
index 822bc826f6..0000000000
--- a/eth/filters/api_test.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// 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 filters
-
-import (
- "encoding/json"
- "fmt"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-func TestUnmarshalJSONNewFilterArgs(t *testing.T) {
- var (
- fromBlock rpc.BlockNumber = 0x123435
- toBlock rpc.BlockNumber = 0xabcdef
- address0 = common.HexToAddress("70c87d191324e6712a591f304b4eedef6ad9bb9d")
- address1 = common.HexToAddress("9b2055d370f73ec7d8a03e965129118dc8f5bf83")
- topic0 = common.HexToHash("3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1ca")
- topic1 = common.HexToHash("9084a792d2f8b16a62b882fd56f7860c07bf5fa91dd8a2ae7e809e5180fef0b3")
- topic2 = common.HexToHash("6ccae1c4af4152f460ff510e573399795dfab5dcf1fa60d1f33ac8fdc1e480ce")
- )
-
- // default values
- var test0 FilterCriteria
- if err := json.Unmarshal([]byte("{}"), &test0); err != nil {
- t.Fatal(err)
- }
- if test0.FromBlock != nil {
- t.Fatalf("expected nil, got %d", test0.FromBlock)
- }
- if test0.ToBlock != nil {
- t.Fatalf("expected nil, got %d", test0.ToBlock)
- }
- if len(test0.Addresses) != 0 {
- t.Fatalf("expected 0 addresses, got %d", len(test0.Addresses))
- }
- if len(test0.Topics) != 0 {
- t.Fatalf("expected 0 topics, got %d topics", len(test0.Topics))
- }
-
- // from, to block number
- var test1 FilterCriteria
- vector := fmt.Sprintf(`{"fromBlock":"%v","toBlock":"%v"}`, fromBlock, toBlock)
- if err := json.Unmarshal([]byte(vector), &test1); err != nil {
- t.Fatal(err)
- }
- if test1.FromBlock.Int64() != fromBlock.Int64() {
- t.Fatalf("expected FromBlock %d, got %d", fromBlock, test1.FromBlock)
- }
- if test1.ToBlock.Int64() != toBlock.Int64() {
- t.Fatalf("expected ToBlock %d, got %d", toBlock, test1.ToBlock)
- }
-
- // single address
- var test2 FilterCriteria
- vector = fmt.Sprintf(`{"address": "%s"}`, address0.Hex())
- if err := json.Unmarshal([]byte(vector), &test2); err != nil {
- t.Fatal(err)
- }
- if len(test2.Addresses) != 1 {
- t.Fatalf("expected 1 address, got %d address(es)", len(test2.Addresses))
- }
- if test2.Addresses[0] != address0 {
- t.Fatalf("expected address %x, got %x", address0, test2.Addresses[0])
- }
-
- // multiple address
- var test3 FilterCriteria
- vector = fmt.Sprintf(`{"address": ["%s", "%s"]}`, address0.Hex(), address1.Hex())
- if err := json.Unmarshal([]byte(vector), &test3); err != nil {
- t.Fatal(err)
- }
- if len(test3.Addresses) != 2 {
- t.Fatalf("expected 2 addresses, got %d address(es)", len(test3.Addresses))
- }
- if test3.Addresses[0] != address0 {
- t.Fatalf("expected address %x, got %x", address0, test3.Addresses[0])
- }
- if test3.Addresses[1] != address1 {
- t.Fatalf("expected address %x, got %x", address1, test3.Addresses[1])
- }
-
- // single topic
- var test4 FilterCriteria
- vector = fmt.Sprintf(`{"topics": ["%s"]}`, topic0.Hex())
- if err := json.Unmarshal([]byte(vector), &test4); err != nil {
- t.Fatal(err)
- }
- if len(test4.Topics) != 1 {
- t.Fatalf("expected 1 topic, got %d", len(test4.Topics))
- }
- if len(test4.Topics[0]) != 1 {
- t.Fatalf("expected len(topics[0]) to be 1, got %d", len(test4.Topics[0]))
- }
- if test4.Topics[0][0] != topic0 {
- t.Fatalf("got %x, expected %x", test4.Topics[0][0], topic0)
- }
-
- // test multiple "AND" topics
- var test5 FilterCriteria
- vector = fmt.Sprintf(`{"topics": ["%s", "%s"]}`, topic0.Hex(), topic1.Hex())
- if err := json.Unmarshal([]byte(vector), &test5); err != nil {
- t.Fatal(err)
- }
- if len(test5.Topics) != 2 {
- t.Fatalf("expected 2 topics, got %d", len(test5.Topics))
- }
- if len(test5.Topics[0]) != 1 {
- t.Fatalf("expected 1 topic, got %d", len(test5.Topics[0]))
- }
- if test5.Topics[0][0] != topic0 {
- t.Fatalf("got %x, expected %x", test5.Topics[0][0], topic0)
- }
- if len(test5.Topics[1]) != 1 {
- t.Fatalf("expected 1 topic, got %d", len(test5.Topics[1]))
- }
- if test5.Topics[1][0] != topic1 {
- t.Fatalf("got %x, expected %x", test5.Topics[1][0], topic1)
- }
-
- // test optional topic
- var test6 FilterCriteria
- vector = fmt.Sprintf(`{"topics": ["%s", null, "%s"]}`, topic0.Hex(), topic2.Hex())
- if err := json.Unmarshal([]byte(vector), &test6); err != nil {
- t.Fatal(err)
- }
- if len(test6.Topics) != 3 {
- t.Fatalf("expected 3 topics, got %d", len(test6.Topics))
- }
- if len(test6.Topics[0]) != 1 {
- t.Fatalf("expected 1 topic, got %d", len(test6.Topics[0]))
- }
- if test6.Topics[0][0] != topic0 {
- t.Fatalf("got %x, expected %x", test6.Topics[0][0], topic0)
- }
- if len(test6.Topics[1]) != 0 {
- t.Fatalf("expected 0 topic, got %d", len(test6.Topics[1]))
- }
- if len(test6.Topics[2]) != 1 {
- t.Fatalf("expected 1 topic, got %d", len(test6.Topics[2]))
- }
- if test6.Topics[2][0] != topic2 {
- t.Fatalf("got %x, expected %x", test6.Topics[2][0], topic2)
- }
-
- // test OR topics
- var test7 FilterCriteria
- vector = fmt.Sprintf(`{"topics": [["%s", "%s"], null, ["%s", null]]}`, topic0.Hex(), topic1.Hex(), topic2.Hex())
- if err := json.Unmarshal([]byte(vector), &test7); err != nil {
- t.Fatal(err)
- }
- if len(test7.Topics) != 3 {
- t.Fatalf("expected 3 topics, got %d topics", len(test7.Topics))
- }
- if len(test7.Topics[0]) != 2 {
- t.Fatalf("expected 2 topics, got %d topics", len(test7.Topics[0]))
- }
- if test7.Topics[0][0] != topic0 || test7.Topics[0][1] != topic1 {
- t.Fatalf("invalid topics expected [%x,%x], got [%x,%x]",
- topic0, topic1, test7.Topics[0][0], test7.Topics[0][1],
- )
- }
- if len(test7.Topics[1]) != 0 {
- t.Fatalf("expected 0 topic, got %d topics", len(test7.Topics[1]))
- }
- if len(test7.Topics[2]) != 0 {
- t.Fatalf("expected 0 topics, got %d topics", len(test7.Topics[2]))
- }
-}
diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go
deleted file mode 100644
index 73b96b77af..0000000000
--- a/eth/filters/bench_test.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2017 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 filters
-
-import (
- "context"
- "fmt"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/node"
-)
-
-func BenchmarkBloomBits512(b *testing.B) {
- benchmarkBloomBits(b, 512)
-}
-
-func BenchmarkBloomBits1k(b *testing.B) {
- benchmarkBloomBits(b, 1024)
-}
-
-func BenchmarkBloomBits2k(b *testing.B) {
- benchmarkBloomBits(b, 2048)
-}
-
-func BenchmarkBloomBits4k(b *testing.B) {
- benchmarkBloomBits(b, 4096)
-}
-
-func BenchmarkBloomBits8k(b *testing.B) {
- benchmarkBloomBits(b, 8192)
-}
-
-func BenchmarkBloomBits16k(b *testing.B) {
- benchmarkBloomBits(b, 16384)
-}
-
-func BenchmarkBloomBits32k(b *testing.B) {
- benchmarkBloomBits(b, 32768)
-}
-
-const benchFilterCnt = 2000
-
-func benchmarkBloomBits(b *testing.B, sectionSize uint64) {
- b.Skip("test disabled: this tests presume (and modify) an existing datadir.")
- benchDataDir := node.DefaultDataDir() + "/geth/chaindata"
- b.Log("Running bloombits benchmark section size:", sectionSize)
-
- db, err := rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "", false)
- if err != nil {
- b.Fatalf("error opening database at %v: %v", benchDataDir, err)
- }
- head := rawdb.ReadHeadBlockHash(db)
- if head == (common.Hash{}) {
- b.Fatalf("chain data not found at %v", benchDataDir)
- }
-
- clearBloomBits(db)
- b.Log("Generating bloombits data...")
- headNum := rawdb.ReadHeaderNumber(db, head)
- if headNum == nil || *headNum < sectionSize+512 {
- b.Fatalf("not enough blocks for running a benchmark")
- }
-
- start := time.Now()
- cnt := (*headNum - 512) / sectionSize
- var dataSize, compSize uint64
- for sectionIdx := uint64(0); sectionIdx < cnt; sectionIdx++ {
- bc, err := bloombits.NewGenerator(uint(sectionSize))
- if err != nil {
- b.Fatalf("failed to create generator: %v", err)
- }
- var header *types.Header
- for i := sectionIdx * sectionSize; i < (sectionIdx+1)*sectionSize; i++ {
- hash := rawdb.ReadCanonicalHash(db, i)
- if header = rawdb.ReadHeader(db, hash, i); header == nil {
- b.Fatalf("Error creating bloomBits data")
- return
- }
- bc.AddBloom(uint(i-sectionIdx*sectionSize), header.Bloom)
- }
- sectionHead := rawdb.ReadCanonicalHash(db, (sectionIdx+1)*sectionSize-1)
- for i := 0; i < types.BloomBitLength; i++ {
- data, err := bc.Bitset(uint(i))
- if err != nil {
- b.Fatalf("failed to retrieve bitset: %v", err)
- }
- comp := bitutil.CompressBytes(data)
- dataSize += uint64(len(data))
- compSize += uint64(len(comp))
- rawdb.WriteBloomBits(db, uint(i), sectionIdx, sectionHead, comp)
- }
- //if sectionIdx%50 == 0 {
- // b.Log(" section", sectionIdx, "/", cnt)
- //}
- }
-
- d := time.Since(start)
- b.Log("Finished generating bloombits data")
- b.Log(" ", d, "total ", d/time.Duration(cnt*sectionSize), "per block")
- b.Log(" data size:", dataSize, " compressed size:", compSize, " compression ratio:", float64(compSize)/float64(dataSize))
-
- b.Log("Running filter benchmarks...")
- start = time.Now()
-
- var (
- backend *testBackend
- sys *FilterSystem
- )
- for i := 0; i < benchFilterCnt; i++ {
- if i%20 == 0 {
- db.Close()
- db, _ = rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "", false)
- backend = &testBackend{db: db, sections: cnt}
- sys = NewFilterSystem(backend, Config{})
- }
- var addr common.Address
- addr[0] = byte(i)
- addr[1] = byte(i / 256)
- filter := sys.NewRangeFilter(0, int64(cnt*sectionSize-1), []common.Address{addr}, nil)
- if _, err := filter.Logs(context.Background()); err != nil {
- b.Error("filter.Logs error:", err)
- }
- }
-
- d = time.Since(start)
- b.Log("Finished running filter benchmarks")
- b.Log(" ", d, "total ", d/time.Duration(benchFilterCnt), "per address", d*time.Duration(1000000)/time.Duration(benchFilterCnt*cnt*sectionSize), "per million blocks")
- db.Close()
-}
-
-//nolint:unused
-func clearBloomBits(db ethdb.Database) {
- var bloomBitsPrefix = []byte("bloomBits-")
- fmt.Println("Clearing bloombits data...")
- it := db.NewIterator(bloomBitsPrefix, nil)
- for it.Next() {
- db.Delete(it.Key())
- }
- it.Release()
-}
-
-func BenchmarkNoBloomBits(b *testing.B) {
- b.Skip("test disabled: this tests presume (and modify) an existing datadir.")
- benchDataDir := node.DefaultDataDir() + "/geth/chaindata"
- b.Log("Running benchmark without bloombits")
- db, err := rawdb.NewLevelDBDatabase(benchDataDir, 128, 1024, "", false)
- if err != nil {
- b.Fatalf("error opening database at %v: %v", benchDataDir, err)
- }
- head := rawdb.ReadHeadBlockHash(db)
- if head == (common.Hash{}) {
- b.Fatalf("chain data not found at %v", benchDataDir)
- }
- headNum := rawdb.ReadHeaderNumber(db, head)
-
- clearBloomBits(db)
-
- _, sys := newTestFilterSystem(b, db, Config{})
-
- b.Log("Running filter benchmarks...")
- start := time.Now()
- filter := sys.NewRangeFilter(0, int64(*headNum), []common.Address{{}}, nil)
- filter.Logs(context.Background())
- d := time.Since(start)
- b.Log("Finished running filter benchmarks")
- b.Log(" ", d, "total ", d*time.Duration(1000000)/time.Duration(*headNum+1), "per million blocks")
- db.Close()
-}
diff --git a/eth/filters/filter.go b/eth/filters/filter.go
deleted file mode 100644
index 83e3284a2b..0000000000
--- a/eth/filters/filter.go
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright 2014 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 filters
-
-import (
- "context"
- "errors"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-// Filter can be used to retrieve and filter logs.
-type Filter struct {
- sys *FilterSystem
-
- addresses []common.Address
- topics [][]common.Hash
-
- block *common.Hash // Block hash if filtering a single block
- begin, end int64 // Range interval if filtering multiple blocks
-
- matcher *bloombits.Matcher
-}
-
-// NewRangeFilter creates a new filter which uses a bloom filter on blocks to
-// figure out whether a particular block is interesting or not.
-func (sys *FilterSystem) NewRangeFilter(begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter {
- // Flatten the address and topic filter clauses into a single bloombits filter
- // system. Since the bloombits are not positional, nil topics are permitted,
- // which get flattened into a nil byte slice.
- var filters [][][]byte
- if len(addresses) > 0 {
- filter := make([][]byte, len(addresses))
- for i, address := range addresses {
- filter[i] = address.Bytes()
- }
- filters = append(filters, filter)
- }
- for _, topicList := range topics {
- filter := make([][]byte, len(topicList))
- for i, topic := range topicList {
- filter[i] = topic.Bytes()
- }
- filters = append(filters, filter)
- }
- size, _ := sys.backend.BloomStatus()
-
- // Create a generic filter and convert it into a range filter
- filter := newFilter(sys, addresses, topics)
-
- filter.matcher = bloombits.NewMatcher(size, filters)
- filter.begin = begin
- filter.end = end
-
- return filter
-}
-
-// NewBlockFilter creates a new filter which directly inspects the contents of
-// a block to figure out whether it is interesting or not.
-func (sys *FilterSystem) NewBlockFilter(block common.Hash, addresses []common.Address, topics [][]common.Hash) *Filter {
- // Create a generic filter and convert it into a block filter
- filter := newFilter(sys, addresses, topics)
- filter.block = &block
- return filter
-}
-
-// newFilter creates a generic filter that can either filter based on a block hash,
-// or based on range queries. The search criteria needs to be explicitly set.
-func newFilter(sys *FilterSystem, addresses []common.Address, topics [][]common.Hash) *Filter {
- return &Filter{
- sys: sys,
- addresses: addresses,
- topics: topics,
- }
-}
-
-// Logs searches the blockchain for matching log entries, returning all from the
-// first block that contains matches, updating the start of the filter accordingly.
-func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
- // If we're doing singleton block filtering, execute and return
- if f.block != nil {
- header, err := f.sys.backend.HeaderByHash(ctx, *f.block)
- if err != nil {
- return nil, err
- }
- if header == nil {
- return nil, errors.New("unknown block")
- }
- return f.blockLogs(ctx, header)
- }
-
- var (
- beginPending = f.begin == rpc.PendingBlockNumber.Int64()
- endPending = f.end == rpc.PendingBlockNumber.Int64()
- )
-
- // special case for pending logs
- if beginPending && !endPending {
- return nil, errInvalidBlockRange
- }
-
- // Short-cut if all we care about is pending logs
- if beginPending && endPending {
- return f.pendingLogs(), nil
- }
-
- resolveSpecial := func(number int64) (int64, error) {
- var hdr *types.Header
- switch number {
- case rpc.LatestBlockNumber.Int64(), rpc.PendingBlockNumber.Int64():
- // we should return head here since we've already captured
- // that we need to get the pending logs in the pending boolean above
- hdr, _ = f.sys.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
- if hdr == nil {
- return 0, errors.New("latest header not found")
- }
- case rpc.FinalizedBlockNumber.Int64():
- hdr, _ = f.sys.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber)
- if hdr == nil {
- return 0, errors.New("finalized header not found")
- }
- case rpc.SafeBlockNumber.Int64():
- hdr, _ = f.sys.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber)
- if hdr == nil {
- return 0, errors.New("safe header not found")
- }
- default:
- return number, nil
- }
- return hdr.Number.Int64(), nil
- }
-
- var err error
- // range query need to resolve the special begin/end block number
- if f.begin, err = resolveSpecial(f.begin); err != nil {
- return nil, err
- }
- if f.end, err = resolveSpecial(f.end); err != nil {
- return nil, err
- }
-
- logChan, errChan := f.rangeLogsAsync(ctx)
- var logs []*types.Log
- for {
- select {
- case log := <-logChan:
- logs = append(logs, log)
- case err := <-errChan:
- if err != nil {
- // if an error occurs during extraction, we do return the extracted data
- return logs, err
- }
- // Append the pending ones
- if endPending {
- pendingLogs := f.pendingLogs()
- logs = append(logs, pendingLogs...)
- }
- return logs, nil
- }
- }
-}
-
-// rangeLogsAsync retrieves block-range logs that match the filter criteria asynchronously,
-// it creates and returns two channels: one for delivering log data, and one for reporting errors.
-func (f *Filter) rangeLogsAsync(ctx context.Context) (chan *types.Log, chan error) {
- var (
- logChan = make(chan *types.Log)
- errChan = make(chan error)
- )
-
- go func() {
- defer func() {
- close(errChan)
- close(logChan)
- }()
-
- // Gather all indexed logs, and finish with non indexed ones
- var (
- end = uint64(f.end)
- size, sections = f.sys.backend.BloomStatus()
- err error
- )
- if indexed := sections * size; indexed > uint64(f.begin) {
- if indexed > end {
- indexed = end + 1
- }
- if err = f.indexedLogs(ctx, indexed-1, logChan); err != nil {
- errChan <- err
- return
- }
- }
-
- if err := f.unindexedLogs(ctx, end, logChan); err != nil {
- errChan <- err
- return
- }
-
- errChan <- nil
- }()
-
- return logChan, errChan
-}
-
-// indexedLogs returns the logs matching the filter criteria based on the bloom
-// bits indexed available locally or via the network.
-func (f *Filter) indexedLogs(ctx context.Context, end uint64, logChan chan *types.Log) error {
- // Create a matcher session and request servicing from the backend
- matches := make(chan uint64, 64)
-
- session, err := f.matcher.Start(ctx, uint64(f.begin), end, matches)
- if err != nil {
- return err
- }
- defer session.Close()
-
- f.sys.backend.ServiceFilter(ctx, session)
-
- for {
- select {
- case number, ok := <-matches:
- // Abort if all matches have been fulfilled
- if !ok {
- err := session.Error()
- if err == nil {
- f.begin = int64(end) + 1
- }
- return err
- }
- f.begin = int64(number) + 1
-
- // Retrieve the suggested block and pull any truly matching logs
- header, err := f.sys.backend.HeaderByNumber(ctx, rpc.BlockNumber(number))
- if header == nil || err != nil {
- return err
- }
- found, err := f.checkMatches(ctx, header)
- if err != nil {
- return err
- }
- for _, log := range found {
- logChan <- log
- }
-
- case <-ctx.Done():
- return ctx.Err()
- }
- }
-}
-
-// unindexedLogs returns the logs matching the filter criteria based on raw block
-// iteration and bloom matching.
-func (f *Filter) unindexedLogs(ctx context.Context, end uint64, logChan chan *types.Log) error {
- for ; f.begin <= int64(end); f.begin++ {
- header, err := f.sys.backend.HeaderByNumber(ctx, rpc.BlockNumber(f.begin))
- if header == nil || err != nil {
- return err
- }
- found, err := f.blockLogs(ctx, header)
- if err != nil {
- return err
- }
- for _, log := range found {
- select {
- case logChan <- log:
- case <-ctx.Done():
- return ctx.Err()
- }
- }
- }
- return nil
-}
-
-// blockLogs returns the logs matching the filter criteria within a single block.
-func (f *Filter) blockLogs(ctx context.Context, header *types.Header) ([]*types.Log, error) {
- if bloomFilter(header.Bloom, f.addresses, f.topics) {
- return f.checkMatches(ctx, header)
- }
- return nil, nil
-}
-
-// checkMatches checks if the receipts belonging to the given header contain any log events that
-// match the filter criteria. This function is called when the bloom filter signals a potential match.
-// skipFilter signals all logs of the given block are requested.
-func (f *Filter) checkMatches(ctx context.Context, header *types.Header) ([]*types.Log, error) {
- hash := header.Hash()
- // Logs in cache are partially filled with context data
- // such as tx index, block hash, etc.
- // Notably tx hash is NOT filled in because it needs
- // access to block body data.
- cached, err := f.sys.cachedLogElem(ctx, hash, header.Number.Uint64())
- if err != nil {
- return nil, err
- }
- logs := filterLogs(cached.logs, nil, nil, f.addresses, f.topics)
- if len(logs) == 0 {
- return nil, nil
- }
- // Most backends will deliver un-derived logs, but check nevertheless.
- if len(logs) > 0 && logs[0].TxHash != (common.Hash{}) {
- return logs, nil
- }
-
- body, err := f.sys.cachedGetBody(ctx, cached, hash, header.Number.Uint64())
- if err != nil {
- return nil, err
- }
- for i, log := range logs {
- // Copy log not to modify cache elements
- logcopy := *log
- logcopy.TxHash = body.Transactions[logcopy.TxIndex].Hash()
- logs[i] = &logcopy
- }
- return logs, nil
-}
-
-// pendingLogs returns the logs matching the filter criteria within the pending block.
-func (f *Filter) pendingLogs() []*types.Log {
- block, receipts := f.sys.backend.PendingBlockAndReceipts()
- if block == nil || receipts == nil {
- return nil
- }
- if bloomFilter(block.Bloom(), f.addresses, f.topics) {
- var unfiltered []*types.Log
- for _, r := range receipts {
- unfiltered = append(unfiltered, r.Logs...)
- }
- return filterLogs(unfiltered, nil, nil, f.addresses, f.topics)
- }
- return nil
-}
-
-// includes returns true if the element is present in the list.
-func includes[T comparable](things []T, element T) bool {
- for _, thing := range things {
- if thing == element {
- return true
- }
- }
- return false
-}
-
-// filterLogs creates a slice of logs matching the given criteria.
-func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log {
- var check = func(log *types.Log) bool {
- if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > log.BlockNumber {
- return false
- }
- if toBlock != nil && toBlock.Int64() >= 0 && toBlock.Uint64() < log.BlockNumber {
- return false
- }
- if len(addresses) > 0 && !includes(addresses, log.Address) {
- return false
- }
- // If the to filtered topics is greater than the amount of topics in logs, skip.
- if len(topics) > len(log.Topics) {
- return false
- }
- for i, sub := range topics {
- if len(sub) == 0 {
- continue // empty rule set == wildcard
- }
- if !includes(sub, log.Topics[i]) {
- return false
- }
- }
- return true
- }
- var ret []*types.Log
- for _, log := range logs {
- if check(log) {
- ret = append(ret, log)
- }
- }
- return ret
-}
-
-func bloomFilter(bloom types.Bloom, addresses []common.Address, topics [][]common.Hash) bool {
- if len(addresses) > 0 {
- var included bool
- for _, addr := range addresses {
- if types.BloomLookup(bloom, addr) {
- included = true
- break
- }
- }
- if !included {
- return false
- }
- }
-
- for _, sub := range topics {
- included := len(sub) == 0 // empty rule set == wildcard
- for _, topic := range sub {
- if types.BloomLookup(bloom, topic) {
- included = true
- break
- }
- }
- if !included {
- return false
- }
- }
- return true
-}
diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go
deleted file mode 100644
index f98a1f84ce..0000000000
--- a/eth/filters/filter_system.go
+++ /dev/null
@@ -1,606 +0,0 @@
-// Copyright 2015 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 filters implements an ethereum filtering system for block,
-// transactions and log events.
-package filters
-
-import (
- "context"
- "fmt"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/lru"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-// Config represents the configuration of the filter system.
-type Config struct {
- LogCacheSize int // maximum number of cached blocks (default: 32)
- Timeout time.Duration // how long filters stay active (default: 5min)
-}
-
-func (cfg Config) withDefaults() Config {
- if cfg.Timeout == 0 {
- cfg.Timeout = 5 * time.Minute
- }
- if cfg.LogCacheSize == 0 {
- cfg.LogCacheSize = 32
- }
- return cfg
-}
-
-type Backend interface {
- ChainDb() ethdb.Database
- HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)
- HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error)
- GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error)
- GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
- GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error)
- PendingBlockAndReceipts() (*types.Block, types.Receipts)
-
- CurrentHeader() *types.Header
- ChainConfig() *params.ChainConfig
- SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
- SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
- SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription
- SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription
- SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription
-
- BloomStatus() (uint64, uint64)
- ServiceFilter(ctx context.Context, session *bloombits.MatcherSession)
-}
-
-// FilterSystem holds resources shared by all filters.
-type FilterSystem struct {
- backend Backend
- logsCache *lru.Cache[common.Hash, *logCacheElem]
- cfg *Config
-}
-
-// NewFilterSystem creates a filter system.
-func NewFilterSystem(backend Backend, config Config) *FilterSystem {
- config = config.withDefaults()
- return &FilterSystem{
- backend: backend,
- logsCache: lru.NewCache[common.Hash, *logCacheElem](config.LogCacheSize),
- cfg: &config,
- }
-}
-
-type logCacheElem struct {
- logs []*types.Log
- body atomic.Value
-}
-
-// cachedLogElem loads block logs from the backend and caches the result.
-func (sys *FilterSystem) cachedLogElem(ctx context.Context, blockHash common.Hash, number uint64) (*logCacheElem, error) {
- cached, ok := sys.logsCache.Get(blockHash)
- if ok {
- return cached, nil
- }
-
- logs, err := sys.backend.GetLogs(ctx, blockHash, number)
- if err != nil {
- return nil, err
- }
- if logs == nil {
- return nil, fmt.Errorf("failed to get logs for block #%d (0x%s)", number, blockHash.TerminalString())
- }
- // Database logs are un-derived.
- // Fill in whatever we can (txHash is inaccessible at this point).
- flattened := make([]*types.Log, 0)
- var logIdx uint
- for i, txLogs := range logs {
- for _, log := range txLogs {
- log.BlockHash = blockHash
- log.BlockNumber = number
- log.TxIndex = uint(i)
- log.Index = logIdx
- logIdx++
- flattened = append(flattened, log)
- }
- }
- elem := &logCacheElem{logs: flattened}
- sys.logsCache.Add(blockHash, elem)
- return elem, nil
-}
-
-func (sys *FilterSystem) cachedGetBody(ctx context.Context, elem *logCacheElem, hash common.Hash, number uint64) (*types.Body, error) {
- if body := elem.body.Load(); body != nil {
- return body.(*types.Body), nil
- }
- body, err := sys.backend.GetBody(ctx, hash, rpc.BlockNumber(number))
- if err != nil {
- return nil, err
- }
- elem.body.Store(body)
- return body, nil
-}
-
-// Type determines the kind of filter and is used to put the filter in to
-// the correct bucket when added.
-type Type byte
-
-const (
- // UnknownSubscription indicates an unknown subscription type
- UnknownSubscription Type = iota
- // LogsSubscription queries for new or removed (chain reorg) logs
- LogsSubscription
- // PendingLogsSubscription queries for logs in pending blocks
- PendingLogsSubscription
- // MinedAndPendingLogsSubscription queries for logs in mined and pending blocks.
- MinedAndPendingLogsSubscription
- // PendingTransactionsSubscription queries for pending transactions entering
- // the pending state
- PendingTransactionsSubscription
- // BlocksSubscription queries hashes for blocks that are imported
- BlocksSubscription
- // LastIndexSubscription keeps track of the last index
- LastIndexSubscription
-)
-
-const (
- // txChanSize is the size of channel listening to NewTxsEvent.
- // The number is referenced from the size of tx pool.
- txChanSize = 4096
- // rmLogsChanSize is the size of channel listening to RemovedLogsEvent.
- rmLogsChanSize = 10
- // logsChanSize is the size of channel listening to LogsEvent.
- logsChanSize = 10
- // chainEvChanSize is the size of channel listening to ChainEvent.
- chainEvChanSize = 10
-)
-
-type subscription struct {
- id rpc.ID
- typ Type
- created time.Time
- logsCrit ethereum.FilterQuery
- logs chan []*types.Log
- txs chan []*types.Transaction
- headers chan *types.Header
- installed chan struct{} // closed when the filter is installed
- err chan error // closed when the filter is uninstalled
-}
-
-// EventSystem creates subscriptions, processes events and broadcasts them to the
-// subscription which match the subscription criteria.
-type EventSystem struct {
- backend Backend
- sys *FilterSystem
- lightMode bool
- lastHead *types.Header
-
- // Subscriptions
- txsSub event.Subscription // Subscription for new transaction event
- logsSub event.Subscription // Subscription for new log event
- rmLogsSub event.Subscription // Subscription for removed log event
- pendingLogsSub event.Subscription // Subscription for pending log event
- chainSub event.Subscription // Subscription for new chain event
-
- // Channels
- install chan *subscription // install filter for event notification
- uninstall chan *subscription // remove filter for event notification
- txsCh chan core.NewTxsEvent // Channel to receive new transactions event
- logsCh chan []*types.Log // Channel to receive new log event
- pendingLogsCh chan []*types.Log // Channel to receive new log event
- rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event
- chainCh chan core.ChainEvent // Channel to receive new chain event
-}
-
-// NewEventSystem creates a new manager that listens for event on the given mux,
-// parses and filters them. It uses the all map to retrieve filter changes. The
-// work loop holds its own index that is used to forward events to filters.
-//
-// The returned manager has a loop that needs to be stopped with the Stop function
-// or by stopping the given mux.
-func NewEventSystem(sys *FilterSystem, lightMode bool) *EventSystem {
- m := &EventSystem{
- sys: sys,
- backend: sys.backend,
- lightMode: lightMode,
- install: make(chan *subscription),
- uninstall: make(chan *subscription),
- txsCh: make(chan core.NewTxsEvent, txChanSize),
- logsCh: make(chan []*types.Log, logsChanSize),
- rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize),
- pendingLogsCh: make(chan []*types.Log, logsChanSize),
- chainCh: make(chan core.ChainEvent, chainEvChanSize),
- }
-
- // Subscribe events
- m.txsSub = m.backend.SubscribeNewTxsEvent(m.txsCh)
- m.logsSub = m.backend.SubscribeLogsEvent(m.logsCh)
- m.rmLogsSub = m.backend.SubscribeRemovedLogsEvent(m.rmLogsCh)
- m.chainSub = m.backend.SubscribeChainEvent(m.chainCh)
- m.pendingLogsSub = m.backend.SubscribePendingLogsEvent(m.pendingLogsCh)
-
- // Make sure none of the subscriptions are empty
- if m.txsSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil || m.pendingLogsSub == nil {
- log.Crit("Subscribe for event system failed")
- }
-
- go m.eventLoop()
- return m
-}
-
-// Subscription is created when the client registers itself for a particular event.
-type Subscription struct {
- ID rpc.ID
- f *subscription
- es *EventSystem
- unsubOnce sync.Once
-}
-
-// Err returns a channel that is closed when unsubscribed.
-func (sub *Subscription) Err() <-chan error {
- return sub.f.err
-}
-
-// Unsubscribe uninstalls the subscription from the event broadcast loop.
-func (sub *Subscription) Unsubscribe() {
- sub.unsubOnce.Do(func() {
- uninstallLoop:
- for {
- // write uninstall request and consume logs/hashes. This prevents
- // the eventLoop broadcast method to deadlock when writing to the
- // filter event channel while the subscription loop is waiting for
- // this method to return (and thus not reading these events).
- select {
- case sub.es.uninstall <- sub.f:
- break uninstallLoop
- case <-sub.f.logs:
- case <-sub.f.txs:
- case <-sub.f.headers:
- }
- }
-
- // wait for filter to be uninstalled in work loop before returning
- // this ensures that the manager won't use the event channel which
- // will probably be closed by the client asap after this method returns.
- <-sub.Err()
- })
-}
-
-// subscribe installs the subscription in the event broadcast loop.
-func (es *EventSystem) subscribe(sub *subscription) *Subscription {
- es.install <- sub
- <-sub.installed
- return &Subscription{ID: sub.id, f: sub, es: es}
-}
-
-// SubscribeLogs creates a subscription that will write all logs matching the
-// given criteria to the given logs channel. Default value for the from and to
-// block is "latest". If the fromBlock > toBlock an error is returned.
-func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) (*Subscription, error) {
- if len(crit.Topics) > maxTopics {
- return nil, errExceedMaxTopics
- }
- var from, to rpc.BlockNumber
- if crit.FromBlock == nil {
- from = rpc.LatestBlockNumber
- } else {
- from = rpc.BlockNumber(crit.FromBlock.Int64())
- }
- if crit.ToBlock == nil {
- to = rpc.LatestBlockNumber
- } else {
- to = rpc.BlockNumber(crit.ToBlock.Int64())
- }
-
- // only interested in pending logs
- if from == rpc.PendingBlockNumber && to == rpc.PendingBlockNumber {
- return es.subscribePendingLogs(crit, logs), nil
- }
- // only interested in new mined logs
- if from == rpc.LatestBlockNumber && to == rpc.LatestBlockNumber {
- return es.subscribeLogs(crit, logs), nil
- }
- // only interested in mined logs within a specific block range
- if from >= 0 && to >= 0 && to >= from {
- return es.subscribeLogs(crit, logs), nil
- }
- // interested in mined logs from a specific block number, new logs and pending logs
- if from >= rpc.LatestBlockNumber && to == rpc.PendingBlockNumber {
- return es.subscribeMinedPendingLogs(crit, logs), nil
- }
- // interested in logs from a specific block number to new mined blocks
- if from >= 0 && to == rpc.LatestBlockNumber {
- return es.subscribeLogs(crit, logs), nil
- }
- return nil, errInvalidBlockRange
-}
-
-// subscribeMinedPendingLogs creates a subscription that returned mined and
-// pending logs that match the given criteria.
-func (es *EventSystem) subscribeMinedPendingLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription {
- sub := &subscription{
- id: rpc.NewID(),
- typ: MinedAndPendingLogsSubscription,
- logsCrit: crit,
- created: time.Now(),
- logs: logs,
- txs: make(chan []*types.Transaction),
- headers: make(chan *types.Header),
- installed: make(chan struct{}),
- err: make(chan error),
- }
- return es.subscribe(sub)
-}
-
-// subscribeLogs creates a subscription that will write all logs matching the
-// given criteria to the given logs channel.
-func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription {
- sub := &subscription{
- id: rpc.NewID(),
- typ: LogsSubscription,
- logsCrit: crit,
- created: time.Now(),
- logs: logs,
- txs: make(chan []*types.Transaction),
- headers: make(chan *types.Header),
- installed: make(chan struct{}),
- err: make(chan error),
- }
- return es.subscribe(sub)
-}
-
-// subscribePendingLogs creates a subscription that writes contract event logs for
-// transactions that enter the transaction pool.
-func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription {
- sub := &subscription{
- id: rpc.NewID(),
- typ: PendingLogsSubscription,
- logsCrit: crit,
- created: time.Now(),
- logs: logs,
- txs: make(chan []*types.Transaction),
- headers: make(chan *types.Header),
- installed: make(chan struct{}),
- err: make(chan error),
- }
- return es.subscribe(sub)
-}
-
-// SubscribeNewHeads creates a subscription that writes the header of a block that is
-// imported in the chain.
-func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscription {
- sub := &subscription{
- id: rpc.NewID(),
- typ: BlocksSubscription,
- created: time.Now(),
- logs: make(chan []*types.Log),
- txs: make(chan []*types.Transaction),
- headers: headers,
- installed: make(chan struct{}),
- err: make(chan error),
- }
- return es.subscribe(sub)
-}
-
-// SubscribePendingTxs creates a subscription that writes transactions for
-// transactions that enter the transaction pool.
-func (es *EventSystem) SubscribePendingTxs(txs chan []*types.Transaction) *Subscription {
- sub := &subscription{
- id: rpc.NewID(),
- typ: PendingTransactionsSubscription,
- created: time.Now(),
- logs: make(chan []*types.Log),
- txs: txs,
- headers: make(chan *types.Header),
- installed: make(chan struct{}),
- err: make(chan error),
- }
- return es.subscribe(sub)
-}
-
-type filterIndex map[Type]map[rpc.ID]*subscription
-
-func (es *EventSystem) handleLogs(filters filterIndex, ev []*types.Log) {
- if len(ev) == 0 {
- return
- }
- for _, f := range filters[LogsSubscription] {
- matchedLogs := filterLogs(ev, f.logsCrit.FromBlock, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics)
- if len(matchedLogs) > 0 {
- f.logs <- matchedLogs
- }
- }
-}
-
-func (es *EventSystem) handlePendingLogs(filters filterIndex, ev []*types.Log) {
- if len(ev) == 0 {
- return
- }
- for _, f := range filters[PendingLogsSubscription] {
- matchedLogs := filterLogs(ev, nil, f.logsCrit.ToBlock, f.logsCrit.Addresses, f.logsCrit.Topics)
- if len(matchedLogs) > 0 {
- f.logs <- matchedLogs
- }
- }
-}
-
-func (es *EventSystem) handleTxsEvent(filters filterIndex, ev core.NewTxsEvent) {
- for _, f := range filters[PendingTransactionsSubscription] {
- f.txs <- ev.Txs
- }
-}
-
-func (es *EventSystem) handleChainEvent(filters filterIndex, ev core.ChainEvent) {
- for _, f := range filters[BlocksSubscription] {
- f.headers <- ev.Block.Header()
- }
- if es.lightMode && len(filters[LogsSubscription]) > 0 {
- es.lightFilterNewHead(ev.Block.Header(), func(header *types.Header, remove bool) {
- for _, f := range filters[LogsSubscription] {
- if f.logsCrit.FromBlock != nil && header.Number.Cmp(f.logsCrit.FromBlock) < 0 {
- continue
- }
- if f.logsCrit.ToBlock != nil && header.Number.Cmp(f.logsCrit.ToBlock) > 0 {
- continue
- }
- if matchedLogs := es.lightFilterLogs(header, f.logsCrit.Addresses, f.logsCrit.Topics, remove); len(matchedLogs) > 0 {
- f.logs <- matchedLogs
- }
- }
- })
- }
-}
-
-func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func(*types.Header, bool)) {
- oldh := es.lastHead
- es.lastHead = newHeader
- if oldh == nil {
- return
- }
- newh := newHeader
- // find common ancestor, create list of rolled back and new block hashes
- var oldHeaders, newHeaders []*types.Header
- for oldh.Hash() != newh.Hash() {
- if oldh.Number.Uint64() >= newh.Number.Uint64() {
- oldHeaders = append(oldHeaders, oldh)
- oldh = rawdb.ReadHeader(es.backend.ChainDb(), oldh.ParentHash, oldh.Number.Uint64()-1)
- }
- if oldh.Number.Uint64() < newh.Number.Uint64() {
- newHeaders = append(newHeaders, newh)
- newh = rawdb.ReadHeader(es.backend.ChainDb(), newh.ParentHash, newh.Number.Uint64()-1)
- if newh == nil {
- // happens when CHT syncing, nothing to do
- newh = oldh
- }
- }
- }
- // roll back old blocks
- for _, h := range oldHeaders {
- callBack(h, true)
- }
- // check new blocks (array is in reverse order)
- for i := len(newHeaders) - 1; i >= 0; i-- {
- callBack(newHeaders[i], false)
- }
-}
-
-// filter logs of a single header in light client mode
-func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common.Address, topics [][]common.Hash, remove bool) []*types.Log {
- if !bloomFilter(header.Bloom, addresses, topics) {
- return nil
- }
- // Get the logs of the block
- ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
- defer cancel()
- cached, err := es.sys.cachedLogElem(ctx, header.Hash(), header.Number.Uint64())
- if err != nil {
- return nil
- }
- unfiltered := append([]*types.Log{}, cached.logs...)
- for i, log := range unfiltered {
- // Don't modify in-cache elements
- logcopy := *log
- logcopy.Removed = remove
- // Swap copy in-place
- unfiltered[i] = &logcopy
- }
- logs := filterLogs(unfiltered, nil, nil, addresses, topics)
- // Txhash is already resolved
- if len(logs) > 0 && logs[0].TxHash != (common.Hash{}) {
- return logs
- }
- // Resolve txhash
- body, err := es.sys.cachedGetBody(ctx, cached, header.Hash(), header.Number.Uint64())
- if err != nil {
- return nil
- }
- for _, log := range logs {
- // logs are already copied, safe to modify
- log.TxHash = body.Transactions[log.TxIndex].Hash()
- }
- return logs
-}
-
-// eventLoop (un)installs filters and processes mux events.
-func (es *EventSystem) eventLoop() {
- // Ensure all subscriptions get cleaned up
- defer func() {
- es.txsSub.Unsubscribe()
- es.logsSub.Unsubscribe()
- es.rmLogsSub.Unsubscribe()
- es.pendingLogsSub.Unsubscribe()
- es.chainSub.Unsubscribe()
- }()
-
- index := make(filterIndex)
- for i := UnknownSubscription; i < LastIndexSubscription; i++ {
- index[i] = make(map[rpc.ID]*subscription)
- }
-
- for {
- select {
- case ev := <-es.txsCh:
- es.handleTxsEvent(index, ev)
- case ev := <-es.logsCh:
- es.handleLogs(index, ev)
- case ev := <-es.rmLogsCh:
- es.handleLogs(index, ev.Logs)
- case ev := <-es.pendingLogsCh:
- es.handlePendingLogs(index, ev)
- case ev := <-es.chainCh:
- es.handleChainEvent(index, ev)
-
- case f := <-es.install:
- if f.typ == MinedAndPendingLogsSubscription {
- // the type are logs and pending logs subscriptions
- index[LogsSubscription][f.id] = f
- index[PendingLogsSubscription][f.id] = f
- } else {
- index[f.typ][f.id] = f
- }
- close(f.installed)
-
- case f := <-es.uninstall:
- if f.typ == MinedAndPendingLogsSubscription {
- // the type are logs and pending logs subscriptions
- delete(index[LogsSubscription], f.id)
- delete(index[PendingLogsSubscription], f.id)
- } else {
- delete(index[f.typ], f.id)
- }
- close(f.err)
-
- // System stopped
- case <-es.txsSub.Err():
- return
- case <-es.logsSub.Err():
- return
- case <-es.rmLogsSub.Err():
- return
- case <-es.chainSub.Err():
- return
- }
- }
-}
diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go
deleted file mode 100644
index 27cad8826a..0000000000
--- a/eth/filters/filter_system_test.go
+++ /dev/null
@@ -1,977 +0,0 @@
-// 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 filters
-
-import (
- "context"
- "errors"
- "fmt"
- "math/big"
- "math/rand"
- "reflect"
- "runtime"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum"
- "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/bloombits"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-type testBackend struct {
- db ethdb.Database
- sections uint64
- txFeed event.Feed
- logsFeed event.Feed
- rmLogsFeed event.Feed
- pendingLogsFeed event.Feed
- chainFeed event.Feed
- pendingBlock *types.Block
- pendingReceipts types.Receipts
-}
-
-func (b *testBackend) ChainConfig() *params.ChainConfig {
- return params.TestChainConfig
-}
-
-func (b *testBackend) CurrentHeader() *types.Header {
- hdr, _ := b.HeaderByNumber(context.TODO(), rpc.LatestBlockNumber)
- return hdr
-}
-
-func (b *testBackend) ChainDb() ethdb.Database {
- return b.db
-}
-
-func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) {
- var (
- hash common.Hash
- num uint64
- )
- switch blockNr {
- case rpc.LatestBlockNumber:
- hash = rawdb.ReadHeadBlockHash(b.db)
- number := rawdb.ReadHeaderNumber(b.db, hash)
- if number == nil {
- return nil, nil
- }
- num = *number
- case rpc.FinalizedBlockNumber:
- hash = rawdb.ReadFinalizedBlockHash(b.db)
- number := rawdb.ReadHeaderNumber(b.db, hash)
- if number == nil {
- return nil, nil
- }
- num = *number
- case rpc.SafeBlockNumber:
- return nil, errors.New("safe block not found")
- default:
- num = uint64(blockNr)
- hash = rawdb.ReadCanonicalHash(b.db, num)
- }
- return rawdb.ReadHeader(b.db, hash, num), nil
-}
-
-func (b *testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
- number := rawdb.ReadHeaderNumber(b.db, hash)
- if number == nil {
- return nil, nil
- }
- return rawdb.ReadHeader(b.db, hash, *number), nil
-}
-
-func (b *testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
- if body := rawdb.ReadBody(b.db, hash, uint64(number)); body != nil {
- return body, nil
- }
- return nil, errors.New("block body not found")
-}
-
-func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
- if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil {
- if header := rawdb.ReadHeader(b.db, hash, *number); header != nil {
- return rawdb.ReadReceipts(b.db, hash, *number, header.Time, params.TestChainConfig), nil
- }
- }
- return nil, nil
-}
-
-func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash, number uint64) ([][]*types.Log, error) {
- logs := rawdb.ReadLogs(b.db, hash, number)
- return logs, nil
-}
-
-func (b *testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
- return b.pendingBlock, b.pendingReceipts
-}
-
-func (b *testBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
- return b.txFeed.Subscribe(ch)
-}
-
-func (b *testBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
- return b.rmLogsFeed.Subscribe(ch)
-}
-
-func (b *testBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
- return b.logsFeed.Subscribe(ch)
-}
-
-func (b *testBackend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription {
- return b.pendingLogsFeed.Subscribe(ch)
-}
-
-func (b *testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
- return b.chainFeed.Subscribe(ch)
-}
-
-func (b *testBackend) BloomStatus() (uint64, uint64) {
- return params.BloomBitsBlocks, b.sections
-}
-
-func (b *testBackend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) {
- requests := make(chan chan *bloombits.Retrieval)
-
- go session.Multiplex(16, 0, requests)
- go func() {
- for {
- // Wait for a service request or a shutdown
- select {
- case <-ctx.Done():
- return
-
- case request := <-requests:
- task := <-request
-
- task.Bitsets = make([][]byte, len(task.Sections))
- for i, section := range task.Sections {
- if rand.Int()%4 != 0 { // Handle occasional missing deliveries
- head := rawdb.ReadCanonicalHash(b.db, (section+1)*params.BloomBitsBlocks-1)
- task.Bitsets[i], _ = rawdb.ReadBloomBits(b.db, task.Bit, section, head)
- }
- }
- request <- task
- }
- }
- }()
-}
-
-func newTestFilterSystem(t testing.TB, db ethdb.Database, cfg Config) (*testBackend, *FilterSystem) {
- backend := &testBackend{db: db}
- sys := NewFilterSystem(backend, cfg)
- return backend, sys
-}
-
-// TestBlockSubscription tests if a block subscription returns block hashes for posted chain events.
-// It creates multiple subscriptions:
-// - one at the start and should receive all posted chain events and a second (blockHashes)
-// - one that is created after a cutoff moment and uninstalled after a second cutoff moment (blockHashes[cutoff1:cutoff2])
-// - one that is created after the second cutoff moment (blockHashes[cutoff2:])
-func TestBlockSubscription(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- backend, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
- genesis = &core.Genesis{
- Config: params.TestChainConfig,
- BaseFee: big.NewInt(params.InitialBaseFee),
- }
- _, chain, _ = core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 10, func(i int, gen *core.BlockGen) {})
- chainEvents = []core.ChainEvent{}
- )
-
- for _, blk := range chain {
- chainEvents = append(chainEvents, core.ChainEvent{Hash: blk.Hash(), Block: blk})
- }
-
- chan0 := make(chan *types.Header)
- sub0 := api.events.SubscribeNewHeads(chan0)
- chan1 := make(chan *types.Header)
- sub1 := api.events.SubscribeNewHeads(chan1)
-
- go func() { // simulate client
- i1, i2 := 0, 0
- for i1 != len(chainEvents) || i2 != len(chainEvents) {
- select {
- case header := <-chan0:
- if chainEvents[i1].Hash != header.Hash() {
- t.Errorf("sub0 received invalid hash on index %d, want %x, got %x", i1, chainEvents[i1].Hash, header.Hash())
- }
- i1++
- case header := <-chan1:
- if chainEvents[i2].Hash != header.Hash() {
- t.Errorf("sub1 received invalid hash on index %d, want %x, got %x", i2, chainEvents[i2].Hash, header.Hash())
- }
- i2++
- }
- }
-
- sub0.Unsubscribe()
- sub1.Unsubscribe()
- }()
-
- time.Sleep(1 * time.Second)
- for _, e := range chainEvents {
- backend.chainFeed.Send(e)
- }
-
- <-sub0.Err()
- <-sub1.Err()
-}
-
-// TestPendingTxFilter tests whether pending tx filters retrieve all pending transactions that are posted to the event mux.
-func TestPendingTxFilter(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- backend, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
-
- transactions = []*types.Transaction{
- types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(1, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(2, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(3, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- }
-
- hashes []common.Hash
- )
-
- fid0 := api.NewPendingTransactionFilter(nil)
-
- time.Sleep(1 * time.Second)
- backend.txFeed.Send(core.NewTxsEvent{Txs: transactions})
-
- timeout := time.Now().Add(1 * time.Second)
- for {
- results, err := api.GetFilterChanges(fid0)
- if err != nil {
- t.Fatalf("Unable to retrieve logs: %v", err)
- }
-
- h := results.([]common.Hash)
- hashes = append(hashes, h...)
- if len(hashes) >= len(transactions) {
- break
- }
- // check timeout
- if time.Now().After(timeout) {
- break
- }
-
- time.Sleep(100 * time.Millisecond)
- }
-
- if len(hashes) != len(transactions) {
- t.Errorf("invalid number of transactions, want %d transactions(s), got %d", len(transactions), len(hashes))
- return
- }
- for i := range hashes {
- if hashes[i] != transactions[i].Hash() {
- t.Errorf("hashes[%d] invalid, want %x, got %x", i, transactions[i].Hash(), hashes[i])
- }
- }
-}
-
-// TestPendingTxFilterFullTx tests whether pending tx filters retrieve all pending transactions that are posted to the event mux.
-func TestPendingTxFilterFullTx(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- backend, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
-
- transactions = []*types.Transaction{
- types.NewTransaction(0, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(1, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(2, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(3, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- types.NewTransaction(4, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil),
- }
-
- txs []*ethapi.RPCTransaction
- )
-
- fullTx := true
- fid0 := api.NewPendingTransactionFilter(&fullTx)
-
- time.Sleep(1 * time.Second)
- backend.txFeed.Send(core.NewTxsEvent{Txs: transactions})
-
- timeout := time.Now().Add(1 * time.Second)
- for {
- results, err := api.GetFilterChanges(fid0)
- if err != nil {
- t.Fatalf("Unable to retrieve logs: %v", err)
- }
-
- tx := results.([]*ethapi.RPCTransaction)
- txs = append(txs, tx...)
- if len(txs) >= len(transactions) {
- break
- }
- // check timeout
- if time.Now().After(timeout) {
- break
- }
-
- time.Sleep(100 * time.Millisecond)
- }
-
- if len(txs) != len(transactions) {
- t.Errorf("invalid number of transactions, want %d transactions(s), got %d", len(transactions), len(txs))
- return
- }
- for i := range txs {
- if txs[i].Hash != transactions[i].Hash() {
- t.Errorf("hashes[%d] invalid, want %x, got %x", i, transactions[i].Hash(), txs[i].Hash)
- }
- }
-}
-
-// TestLogFilterCreation test whether a given filter criteria makes sense.
-// If not it must return an error.
-func TestLogFilterCreation(t *testing.T) {
- var (
- db = rawdb.NewMemoryDatabase()
- _, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
-
- testCases = []struct {
- crit FilterCriteria
- success bool
- }{
- // defaults
- {FilterCriteria{}, true},
- // valid block number range
- {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2)}, true},
- // "mined" block range to pending
- {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, true},
- // new mined and pending blocks
- {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, true},
- // from block "higher" than to block
- {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(1)}, false},
- // from block "higher" than to block
- {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)}, false},
- // from block "higher" than to block
- {FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, false},
- // from block "higher" than to block
- {FilterCriteria{FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, false},
- // topics more then 4
- {FilterCriteria{Topics: [][]common.Hash{{}, {}, {}, {}, {}}}, false},
- }
- )
-
- for i, test := range testCases {
- id, err := api.NewFilter(test.crit)
- if err != nil && test.success {
- t.Errorf("expected filter creation for case %d to success, got %v", i, err)
- }
- if err == nil {
- api.UninstallFilter(id)
- if !test.success {
- t.Errorf("expected testcase %d to fail with an error", i)
- }
- }
- }
-}
-
-// TestInvalidLogFilterCreation tests whether invalid filter log criteria results in an error
-// when the filter is created.
-func TestInvalidLogFilterCreation(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- _, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
- )
-
- // different situations where log filter creation should fail.
- // Reason: fromBlock > toBlock
- testCases := []FilterCriteria{
- 0: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
- 1: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)},
- 2: {FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)},
- 3: {Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
- }
-
- for i, test := range testCases {
- if _, err := api.NewFilter(test); err == nil {
- t.Errorf("Expected NewFilter for case #%d to fail", i)
- }
- }
-}
-
-// TestLogFilterUninstall tests invalid getLogs requests
-func TestInvalidGetLogsRequest(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- _, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
- blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
- )
-
- // Reason: Cannot specify both BlockHash and FromBlock/ToBlock)
- testCases := []FilterCriteria{
- 0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)},
- 1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)},
- 2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
- 3: {BlockHash: &blockHash, Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
- }
-
- for i, test := range testCases {
- if _, err := api.GetLogs(context.Background(), test); err == nil {
- t.Errorf("Expected Logs for case #%d to fail", i)
- }
- }
-}
-
-// TestInvalidGetRangeLogsRequest tests getLogs with invalid block range
-func TestInvalidGetRangeLogsRequest(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- _, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
- )
-
- if _, err := api.GetLogs(context.Background(), FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(1)}); err != errInvalidBlockRange {
- t.Errorf("Expected Logs for invalid range return error, but got: %v", err)
- }
-}
-
-// TestLogFilter tests whether log filters match the correct logs that are posted to the event feed.
-func TestLogFilter(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- backend, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
-
- firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
- secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
- thirdAddress = common.HexToAddress("0x3333333333333333333333333333333333333333")
- notUsedAddress = common.HexToAddress("0x9999999999999999999999999999999999999999")
- firstTopic = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
- secondTopic = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222")
- notUsedTopic = common.HexToHash("0x9999999999999999999999999999999999999999999999999999999999999999")
-
- // posted twice, once as regular logs and once as pending logs.
- allLogs = []*types.Log{
- {Address: firstAddr},
- {Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1},
- {Address: secondAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1},
- {Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 2},
- {Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 3},
- }
-
- expectedCase7 = []*types.Log{allLogs[3], allLogs[4], allLogs[0], allLogs[1], allLogs[2], allLogs[3], allLogs[4]}
- expectedCase11 = []*types.Log{allLogs[1], allLogs[2], allLogs[1], allLogs[2]}
-
- testCases = []struct {
- crit FilterCriteria
- expected []*types.Log
- id rpc.ID
- }{
- // match all
- 0: {FilterCriteria{}, allLogs, ""},
- // match none due to no matching addresses
- 1: {FilterCriteria{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}}, []*types.Log{}, ""},
- // match logs based on addresses, ignore topics
- 2: {FilterCriteria{Addresses: []common.Address{firstAddr}}, allLogs[:2], ""},
- // match none due to no matching topics (match with address)
- 3: {FilterCriteria{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}}, []*types.Log{}, ""},
- // match logs based on addresses and topics
- 4: {FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[3:5], ""},
- // match logs based on multiple addresses and "or" topics
- 5: {FilterCriteria{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[2:5], ""},
- // logs in the pending block
- 6: {FilterCriteria{Addresses: []common.Address{firstAddr}, FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, allLogs[:2], ""},
- // mined logs with block num >= 2 or pending logs
- 7: {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, expectedCase7, ""},
- // all "mined" logs with block num >= 2
- 8: {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs[3:], ""},
- // all "mined" logs
- 9: {FilterCriteria{ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, allLogs, ""},
- // all "mined" logs with 1>= block num <=2 and topic secondTopic
- 10: {FilterCriteria{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2), Topics: [][]common.Hash{{secondTopic}}}, allLogs[3:4], ""},
- // all "mined" and pending logs with topic firstTopic
- 11: {FilterCriteria{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), Topics: [][]common.Hash{{firstTopic}}}, expectedCase11, ""},
- // match all logs due to wildcard topic
- 12: {FilterCriteria{Topics: [][]common.Hash{nil}}, allLogs[1:], ""},
- }
- )
-
- // create all filters
- for i := range testCases {
- testCases[i].id, _ = api.NewFilter(testCases[i].crit)
- }
-
- // raise events
- time.Sleep(1 * time.Second)
- if nsend := backend.logsFeed.Send(allLogs); nsend == 0 {
- t.Fatal("Logs event not delivered")
- }
- if nsend := backend.pendingLogsFeed.Send(allLogs); nsend == 0 {
- t.Fatal("Pending logs event not delivered")
- }
-
- for i, tt := range testCases {
- var fetched []*types.Log
- timeout := time.Now().Add(1 * time.Second)
- for { // fetch all expected logs
- results, err := api.GetFilterChanges(tt.id)
- if err != nil {
- t.Fatalf("Unable to fetch logs: %v", err)
- }
-
- fetched = append(fetched, results.([]*types.Log)...)
- if len(fetched) >= len(tt.expected) {
- break
- }
- // check timeout
- if time.Now().After(timeout) {
- break
- }
-
- time.Sleep(100 * time.Millisecond)
- }
-
- if len(fetched) != len(tt.expected) {
- t.Errorf("invalid number of logs for case %d, want %d log(s), got %d", i, len(tt.expected), len(fetched))
- return
- }
-
- for l := range fetched {
- if fetched[l].Removed {
- t.Errorf("expected log not to be removed for log %d in case %d", l, i)
- }
- if !reflect.DeepEqual(fetched[l], tt.expected[l]) {
- t.Errorf("invalid log on index %d for case %d", l, i)
- }
- }
- }
-}
-
-// TestPendingLogsSubscription tests if a subscription receives the correct pending logs that are posted to the event feed.
-func TestPendingLogsSubscription(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- backend, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, false)
-
- firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
- secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
- thirdAddress = common.HexToAddress("0x3333333333333333333333333333333333333333")
- notUsedAddress = common.HexToAddress("0x9999999999999999999999999999999999999999")
- firstTopic = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
- secondTopic = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222")
- thirdTopic = common.HexToHash("0x3333333333333333333333333333333333333333333333333333333333333333")
- fourthTopic = common.HexToHash("0x4444444444444444444444444444444444444444444444444444444444444444")
- notUsedTopic = common.HexToHash("0x9999999999999999999999999999999999999999999999999999999999999999")
-
- allLogs = [][]*types.Log{
- {{Address: firstAddr, Topics: []common.Hash{}, BlockNumber: 0}},
- {{Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 1}},
- {{Address: secondAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 2}},
- {{Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 3}},
- {{Address: thirdAddress, Topics: []common.Hash{secondTopic}, BlockNumber: 4}},
- {
- {Address: thirdAddress, Topics: []common.Hash{firstTopic}, BlockNumber: 5},
- {Address: thirdAddress, Topics: []common.Hash{thirdTopic}, BlockNumber: 5},
- {Address: thirdAddress, Topics: []common.Hash{fourthTopic}, BlockNumber: 5},
- {Address: firstAddr, Topics: []common.Hash{firstTopic}, BlockNumber: 5},
- },
- }
-
- pendingBlockNumber = big.NewInt(rpc.PendingBlockNumber.Int64())
-
- testCases = []struct {
- crit ethereum.FilterQuery
- expected []*types.Log
- c chan []*types.Log
- sub *Subscription
- err chan error
- }{
- // match all
- {
- ethereum.FilterQuery{FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber},
- flattenLogs(allLogs),
- nil, nil, nil,
- },
- // match none due to no matching addresses
- {
- ethereum.FilterQuery{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber},
- nil,
- nil, nil, nil,
- },
- // match logs based on addresses, ignore topics
- {
- ethereum.FilterQuery{Addresses: []common.Address{firstAddr}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber},
- append(flattenLogs(allLogs[:2]), allLogs[5][3]),
- nil, nil, nil,
- },
- // match none due to no matching topics (match with address)
- {
- ethereum.FilterQuery{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber},
- nil,
- nil, nil, nil,
- },
- // match logs based on addresses and topics
- {
- ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber},
- append(flattenLogs(allLogs[3:5]), allLogs[5][0]),
- nil, nil, nil,
- },
- // match logs based on multiple addresses and "or" topics
- {
- ethereum.FilterQuery{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber},
- append(flattenLogs(allLogs[2:5]), allLogs[5][0]),
- nil, nil, nil,
- },
- // multiple pending logs, should match only 2 topics from the logs in block 5
- {
- ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, fourthTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber},
- []*types.Log{allLogs[5][0], allLogs[5][2]},
- nil, nil, nil,
- },
- // match none due to only matching new mined logs
- {
- ethereum.FilterQuery{},
- nil,
- nil, nil, nil,
- },
- // match none due to only matching mined logs within a specific block range
- {
- ethereum.FilterQuery{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2)},
- nil,
- nil, nil, nil,
- },
- // match all due to matching mined and pending logs
- {
- ethereum.FilterQuery{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())},
- flattenLogs(allLogs),
- nil, nil, nil,
- },
- // match none due to matching logs from a specific block number to new mined blocks
- {
- ethereum.FilterQuery{FromBlock: big.NewInt(1), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
- nil,
- nil, nil, nil,
- },
- }
- )
-
- // create all subscriptions, this ensures all subscriptions are created before the events are posted.
- // on slow machines this could otherwise lead to missing events when the subscription is created after
- // (some) events are posted.
- for i := range testCases {
- testCases[i].c = make(chan []*types.Log)
- testCases[i].err = make(chan error, 1)
-
- var err error
- testCases[i].sub, err = api.events.SubscribeLogs(testCases[i].crit, testCases[i].c)
- if err != nil {
- t.Fatalf("SubscribeLogs %d failed: %v\n", i, err)
- }
- }
-
- for n, test := range testCases {
- i := n
- tt := test
- go func() {
- defer tt.sub.Unsubscribe()
-
- var fetched []*types.Log
-
- timeout := time.After(1 * time.Second)
- fetchLoop:
- for {
- select {
- case logs := <-tt.c:
- // Do not break early if we've fetched greater, or equal,
- // to the number of logs expected. This ensures we do not
- // deadlock the filter system because it will do a blocking
- // send on this channel if another log arrives.
- fetched = append(fetched, logs...)
- case <-timeout:
- break fetchLoop
- }
- }
-
- if len(fetched) != len(tt.expected) {
- tt.err <- fmt.Errorf("invalid number of logs for case %d, want %d log(s), got %d", i, len(tt.expected), len(fetched))
- return
- }
-
- for l := range fetched {
- if fetched[l].Removed {
- tt.err <- fmt.Errorf("expected log not to be removed for log %d in case %d", l, i)
- return
- }
- if !reflect.DeepEqual(fetched[l], tt.expected[l]) {
- tt.err <- fmt.Errorf("invalid log on index %d for case %d\n", l, i)
- return
- }
- }
- tt.err <- nil
- }()
- }
-
- // raise events
- for _, ev := range allLogs {
- backend.pendingLogsFeed.Send(ev)
- }
-
- for i := range testCases {
- err := <-testCases[i].err
- if err != nil {
- t.Fatalf("test %d failed: %v", i, err)
- }
- <-testCases[i].sub.Err()
- }
-}
-
-func TestLightFilterLogs(t *testing.T) {
- t.Parallel()
-
- var (
- db = rawdb.NewMemoryDatabase()
- backend, sys = newTestFilterSystem(t, db, Config{})
- api = NewFilterAPI(sys, true)
- signer = types.HomesteadSigner{}
-
- firstAddr = common.HexToAddress("0x1111111111111111111111111111111111111111")
- secondAddr = common.HexToAddress("0x2222222222222222222222222222222222222222")
- thirdAddress = common.HexToAddress("0x3333333333333333333333333333333333333333")
- notUsedAddress = common.HexToAddress("0x9999999999999999999999999999999999999999")
- firstTopic = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
- secondTopic = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222")
-
- // posted twice, once as regular logs and once as pending logs.
- allLogs = []*types.Log{
- // Block 1
- {Address: firstAddr, Topics: []common.Hash{}, Data: []byte{}, BlockNumber: 2, Index: 0},
- // Block 2
- {Address: firstAddr, Topics: []common.Hash{firstTopic}, Data: []byte{}, BlockNumber: 3, Index: 0},
- {Address: secondAddr, Topics: []common.Hash{firstTopic}, Data: []byte{}, BlockNumber: 3, Index: 1},
- {Address: thirdAddress, Topics: []common.Hash{secondTopic}, Data: []byte{}, BlockNumber: 3, Index: 2},
- // Block 3
- {Address: thirdAddress, Topics: []common.Hash{secondTopic}, Data: []byte{}, BlockNumber: 4, Index: 0},
- }
-
- testCases = []struct {
- crit FilterCriteria
- expected []*types.Log
- id rpc.ID
- }{
- // match all
- 0: {FilterCriteria{}, allLogs, ""},
- // match none due to no matching addresses
- 1: {FilterCriteria{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}}, []*types.Log{}, ""},
- // match logs based on addresses, ignore topics
- 2: {FilterCriteria{Addresses: []common.Address{firstAddr}}, allLogs[:2], ""},
- // match logs based on addresses and topics
- 3: {FilterCriteria{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}}, allLogs[3:5], ""},
- // all logs with block num >= 3
- 4: {FilterCriteria{FromBlock: big.NewInt(3), ToBlock: big.NewInt(5)}, allLogs[1:], ""},
- // all logs
- 5: {FilterCriteria{FromBlock: big.NewInt(0), ToBlock: big.NewInt(5)}, allLogs, ""},
- // all logs with 1>= block num <=2 and topic secondTopic
- 6: {FilterCriteria{FromBlock: big.NewInt(2), ToBlock: big.NewInt(3), Topics: [][]common.Hash{{secondTopic}}}, allLogs[3:4], ""},
- }
-
- key, _ = crypto.GenerateKey()
- addr = crypto.PubkeyToAddress(key.PublicKey)
- genesis = &core.Genesis{Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{
- addr: {Balance: big.NewInt(params.Ether)},
- },
- }
- receipts = []*types.Receipt{{
- Logs: []*types.Log{allLogs[0]},
- }, {
- Logs: []*types.Log{allLogs[1], allLogs[2], allLogs[3]},
- }, {
- Logs: []*types.Log{allLogs[4]},
- }}
- )
-
- _, blocks, _ := core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 4, func(i int, b *core.BlockGen) {
- if i == 0 {
- return
- }
- receipts[i-1].Bloom = types.CreateBloom(types.Receipts{receipts[i-1]})
- b.AddUncheckedReceipt(receipts[i-1])
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i - 1), To: &common.Address{}, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, key)
- b.AddTx(tx)
- })
- for i, block := range blocks {
- rawdb.WriteBlock(db, block)
- rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
- rawdb.WriteHeadBlockHash(db, block.Hash())
- if i > 0 {
- rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), []*types.Receipt{receipts[i-1]})
- }
- }
- // create all filters
- for i := range testCases {
- id, err := api.NewFilter(testCases[i].crit)
- if err != nil {
- t.Fatal(err)
- }
- testCases[i].id = id
- }
-
- // raise events
- time.Sleep(1 * time.Second)
- for _, block := range blocks {
- backend.chainFeed.Send(core.ChainEvent{Block: block, Hash: common.Hash{}, Logs: allLogs})
- }
-
- for i, tt := range testCases {
- var fetched []*types.Log
- timeout := time.Now().Add(1 * time.Second)
- for { // fetch all expected logs
- results, err := api.GetFilterChanges(tt.id)
- if err != nil {
- t.Fatalf("Unable to fetch logs: %v", err)
- }
- fetched = append(fetched, results.([]*types.Log)...)
- if len(fetched) >= len(tt.expected) {
- break
- }
- // check timeout
- if time.Now().After(timeout) {
- break
- }
-
- time.Sleep(100 * time.Millisecond)
- }
-
- if len(fetched) != len(tt.expected) {
- t.Errorf("invalid number of logs for case %d, want %d log(s), got %d", i, len(tt.expected), len(fetched))
- return
- }
-
- for l := range fetched {
- if fetched[l].Removed {
- t.Errorf("expected log not to be removed for log %d in case %d", l, i)
- }
- expected := *tt.expected[l]
- blockNum := expected.BlockNumber - 1
- expected.BlockHash = blocks[blockNum].Hash()
- expected.TxHash = blocks[blockNum].Transactions()[0].Hash()
- if !reflect.DeepEqual(fetched[l], &expected) {
- t.Errorf("invalid log on index %d for case %d", l, i)
- }
- }
- }
-}
-
-// TestPendingTxFilterDeadlock tests if the event loop hangs when pending
-// txes arrive at the same time that one of multiple filters is timing out.
-// Please refer to #22131 for more details.
-func TestPendingTxFilterDeadlock(t *testing.T) {
- t.Parallel()
- timeout := 100 * time.Millisecond
-
- var (
- db = rawdb.NewMemoryDatabase()
- backend, sys = newTestFilterSystem(t, db, Config{Timeout: timeout})
- api = NewFilterAPI(sys, false)
- done = make(chan struct{})
- )
-
- go func() {
- // Bombard feed with txes until signal was received to stop
- i := uint64(0)
- for {
- select {
- case <-done:
- return
- default:
- }
-
- tx := types.NewTransaction(i, common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268"), new(big.Int), 0, new(big.Int), nil)
- backend.txFeed.Send(core.NewTxsEvent{Txs: []*types.Transaction{tx}})
- i++
- }
- }()
-
- // Create a bunch of filters that will
- // timeout either in 100ms or 200ms
- subs := make([]*Subscription, 20)
- for i := 0; i < len(subs); i++ {
- fid := api.NewPendingTransactionFilter(nil)
- f, ok := api.filters[fid]
- if !ok {
- t.Fatalf("Filter %s should exist", fid)
- }
- subs[i] = f.s
- // Wait for at least one tx to arrive in filter
- for {
- hashes, err := api.GetFilterChanges(fid)
- if err != nil {
- t.Fatalf("Filter should exist: %v\n", err)
- }
- if len(hashes.([]common.Hash)) > 0 {
- break
- }
- runtime.Gosched()
- }
- }
-
- // Wait until filters have timed out and have been uninstalled.
- for _, sub := range subs {
- select {
- case <-sub.Err():
- case <-time.After(1 * time.Second):
- t.Fatalf("Filter timeout is hanging")
- }
- }
-}
-
-func flattenLogs(pl [][]*types.Log) []*types.Log {
- var logs []*types.Log
- for _, l := range pl {
- logs = append(logs, l...)
- }
- return logs
-}
diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go
deleted file mode 100644
index 1db917c960..0000000000
--- a/eth/filters/filter_test.go
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright 2015 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 filters
-
-import (
- "context"
- "encoding/json"
- "math/big"
- "strings"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/accounts/abi"
- "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/params"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-func makeReceipt(addr common.Address) *types.Receipt {
- receipt := types.NewReceipt(nil, false, 0)
- receipt.Logs = []*types.Log{
- {Address: addr},
- }
- receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
- return receipt
-}
-
-func BenchmarkFilters(b *testing.B) {
- var (
- db, _ = rawdb.NewLevelDBDatabase(b.TempDir(), 0, 0, "", false)
- _, sys = newTestFilterSystem(b, db, Config{})
- key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- addr1 = crypto.PubkeyToAddress(key1.PublicKey)
- addr2 = common.BytesToAddress([]byte("jeff"))
- addr3 = common.BytesToAddress([]byte("ethereum"))
- addr4 = common.BytesToAddress([]byte("random addresses please"))
-
- gspec = &core.Genesis{
- Alloc: core.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}},
- BaseFee: big.NewInt(params.InitialBaseFee),
- Config: params.TestChainConfig,
- }
- )
- defer db.Close()
- _, chain, receipts := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 100010, func(i int, gen *core.BlockGen) {
- switch i {
- case 2403:
- receipt := makeReceipt(addr1)
- gen.AddUncheckedReceipt(receipt)
- gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
- case 1034:
- receipt := makeReceipt(addr2)
- gen.AddUncheckedReceipt(receipt)
- gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
- case 34:
- receipt := makeReceipt(addr3)
- gen.AddUncheckedReceipt(receipt)
- gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
- case 99999:
- receipt := makeReceipt(addr4)
- gen.AddUncheckedReceipt(receipt)
- gen.AddUncheckedTx(types.NewTransaction(999, common.HexToAddress("0x999"), big.NewInt(999), 999, gen.BaseFee(), nil))
- }
- })
- // The test txs are not properly signed, can't simply create a chain
- // and then import blocks. TODO(rjl493456442) try to get rid of the
- // manual database writes.
- gspec.MustCommit(db, trie.NewDatabase(db, trie.HashDefaults))
-
- for i, block := range chain {
- rawdb.WriteBlock(db, block)
- rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
- rawdb.WriteHeadBlockHash(db, block.Hash())
- rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), receipts[i])
- }
- b.ResetTimer()
-
- filter := sys.NewRangeFilter(0, -1, []common.Address{addr1, addr2, addr3, addr4}, nil)
-
- for i := 0; i < b.N; i++ {
- logs, _ := filter.Logs(context.Background())
- if len(logs) != 4 {
- b.Fatal("expected 4 logs, got", len(logs))
- }
- }
-}
-
-func TestFilters(t *testing.T) {
- var (
- db = rawdb.NewMemoryDatabase()
- _, sys = newTestFilterSystem(t, db, Config{})
- // Sender account
- key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- addr = crypto.PubkeyToAddress(key1.PublicKey)
- signer = types.NewLondonSigner(big.NewInt(1))
- // Logging contract
- contract = common.Address{0xfe}
- contract2 = common.Address{0xff}
- abiStr = `[{"inputs":[],"name":"log0","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"}],"name":"log1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"}],"name":"log2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"},{"internalType":"uint256","name":"t3","type":"uint256"}],"name":"log3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"t1","type":"uint256"},{"internalType":"uint256","name":"t2","type":"uint256"},{"internalType":"uint256","name":"t3","type":"uint256"},{"internalType":"uint256","name":"t4","type":"uint256"}],"name":"log4","outputs":[],"stateMutability":"nonpayable","type":"function"}]`
- /*
- // SPDX-License-Identifier: GPL-3.0
- pragma solidity >=0.7.0 <0.9.0;
-
- contract Logger {
- function log0() external {
- assembly {
- log0(0, 0)
- }
- }
-
- function log1(uint t1) external {
- assembly {
- log1(0, 0, t1)
- }
- }
-
- function log2(uint t1, uint t2) external {
- assembly {
- log2(0, 0, t1, t2)
- }
- }
-
- function log3(uint t1, uint t2, uint t3) external {
- assembly {
- log3(0, 0, t1, t2, t3)
- }
- }
-
- function log4(uint t1, uint t2, uint t3, uint t4) external {
- assembly {
- log4(0, 0, t1, t2, t3, t4)
- }
- }
- }
- */
- bytecode = common.FromHex("608060405234801561001057600080fd5b50600436106100575760003560e01c80630aa731851461005c5780632a4c08961461006657806378b9a1f314610082578063c670f8641461009e578063c683d6a3146100ba575b600080fd5b6100646100d6565b005b610080600480360381019061007b9190610143565b6100dc565b005b61009c60048036038101906100979190610196565b6100e8565b005b6100b860048036038101906100b391906101d6565b6100f2565b005b6100d460048036038101906100cf9190610203565b6100fa565b005b600080a0565b808284600080a3505050565b8082600080a25050565b80600080a150565b80828486600080a450505050565b600080fd5b6000819050919050565b6101208161010d565b811461012b57600080fd5b50565b60008135905061013d81610117565b92915050565b60008060006060848603121561015c5761015b610108565b5b600061016a8682870161012e565b935050602061017b8682870161012e565b925050604061018c8682870161012e565b9150509250925092565b600080604083850312156101ad576101ac610108565b5b60006101bb8582860161012e565b92505060206101cc8582860161012e565b9150509250929050565b6000602082840312156101ec576101eb610108565b5b60006101fa8482850161012e565b91505092915050565b6000806000806080858703121561021d5761021c610108565b5b600061022b8782880161012e565b945050602061023c8782880161012e565b935050604061024d8782880161012e565b925050606061025e8782880161012e565b9150509295919450925056fea264697066735822122073a4b156f487e59970dc1ef449cc0d51467268f676033a17188edafcee861f9864736f6c63430008110033")
-
- hash1 = common.BytesToHash([]byte("topic1"))
- hash2 = common.BytesToHash([]byte("topic2"))
- hash3 = common.BytesToHash([]byte("topic3"))
- hash4 = common.BytesToHash([]byte("topic4"))
- hash5 = common.BytesToHash([]byte("topic5"))
-
- gspec = &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{
- addr: {Balance: big.NewInt(0).Mul(big.NewInt(100), big.NewInt(params.Ether))},
- contract: {Balance: big.NewInt(0), Code: bytecode},
- contract2: {Balance: big.NewInt(0), Code: bytecode},
- },
- BaseFee: big.NewInt(params.InitialBaseFee),
- }
- )
-
- contractABI, err := abi.JSON(strings.NewReader(abiStr))
- if err != nil {
- t.Fatal(err)
- }
-
- // Hack: GenerateChainWithGenesis creates a new db.
- // Commit the genesis manually and use GenerateChain.
- _, err = gspec.Commit(db, trie.NewDatabase(db, nil))
- if err != nil {
- t.Fatal(err)
- }
- chain, _ := core.GenerateChain(gspec.Config, gspec.ToBlock(), ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) {
- switch i {
- case 1:
- data, err := contractABI.Pack("log1", hash1.Big())
- if err != nil {
- t.Fatal(err)
- }
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: 0,
- GasPrice: gen.BaseFee(),
- Gas: 30000,
- To: &contract,
- Data: data,
- }), signer, key1)
- gen.AddTx(tx)
- tx2, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: 1,
- GasPrice: gen.BaseFee(),
- Gas: 30000,
- To: &contract2,
- Data: data,
- }), signer, key1)
- gen.AddTx(tx2)
- case 2:
- data, err := contractABI.Pack("log2", hash2.Big(), hash1.Big())
- if err != nil {
- t.Fatal(err)
- }
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: 2,
- GasPrice: gen.BaseFee(),
- Gas: 30000,
- To: &contract,
- Data: data,
- }), signer, key1)
- gen.AddTx(tx)
- case 998:
- data, err := contractABI.Pack("log1", hash3.Big())
- if err != nil {
- t.Fatal(err)
- }
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: 3,
- GasPrice: gen.BaseFee(),
- Gas: 30000,
- To: &contract2,
- Data: data,
- }), signer, key1)
- gen.AddTx(tx)
- case 999:
- data, err := contractABI.Pack("log1", hash4.Big())
- if err != nil {
- t.Fatal(err)
- }
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: 4,
- GasPrice: gen.BaseFee(),
- Gas: 30000,
- To: &contract,
- Data: data,
- }), signer, key1)
- gen.AddTx(tx)
- }
- })
- var l uint64
- bc, err := core.NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, &l)
- if err != nil {
- t.Fatal(err)
- }
- _, err = bc.InsertChain(chain)
- if err != nil {
- t.Fatal(err)
- }
-
- // Set block 998 as Finalized (-3)
- bc.SetFinalized(chain[998].Header())
-
- // Generate pending block
- pchain, preceipts := core.GenerateChain(gspec.Config, chain[len(chain)-1], ethash.NewFaker(), db, 1, func(i int, gen *core.BlockGen) {
- data, err := contractABI.Pack("log1", hash5.Big())
- if err != nil {
- t.Fatal(err)
- }
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: 5,
- GasPrice: gen.BaseFee(),
- Gas: 30000,
- To: &contract,
- Data: data,
- }), signer, key1)
- gen.AddTx(tx)
- })
- sys.backend.(*testBackend).pendingBlock = pchain[0]
- sys.backend.(*testBackend).pendingReceipts = preceipts[0]
-
- for i, tc := range []struct {
- f *Filter
- want string
- err string
- }{
- {
- f: sys.NewBlockFilter(chain[2].Hash(), []common.Address{contract}, nil),
- want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}),
- want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}),
- },
- {
- f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}),
- want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}),
- want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}),
- want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xdba3e2ea9a7d690b722d70ee605fd67ba4c00d1d3aecd5cf187a7b92ad8eb3df","transactionIndex":"0x1","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}),
- },
- {
- f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil),
- },
- {
- f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}),
- },
- {
- f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
- want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
- want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
- want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
- },
- {
- f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
- err: "safe header not found",
- },
- {
- f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
- err: "safe header not found",
- },
- {
- f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
- err: "safe header not found",
- },
- {
- f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil),
- want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xd5e8d4e4eb51a2a2a6ec20ef68a4c2801240743c8deb77a6a1d118ac3eefb725","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil),
- want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xd5e8d4e4eb51a2a2a6ec20ef68a4c2801240743c8deb77a6a1d118ac3eefb725","logIndex":"0x0","removed":false}]`,
- },
- {
- f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
- err: errInvalidBlockRange.Error(),
- },
- } {
- logs, err := tc.f.Logs(context.Background())
- if err == nil && tc.err != "" {
- t.Fatalf("test %d, expected error %q, got nil", i, tc.err)
- } else if err != nil && err.Error() != tc.err {
- t.Fatalf("test %d, expected error %q, got %q", i, tc.err, err.Error())
- }
- if tc.want == "" && len(logs) == 0 {
- continue
- }
- have, err := json.Marshal(logs)
- if err != nil {
- t.Fatal(err)
- }
- if string(have) != tc.want {
- t.Fatalf("test %d, have:\n%s\nwant:\n%s", i, have, tc.want)
- }
- }
-
- t.Run("timeout", func(t *testing.T) {
- f := sys.NewRangeFilter(0, -1, nil, nil)
- ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Hour))
- defer cancel()
- _, err := f.Logs(ctx)
- if err == nil {
- t.Fatal("expected error")
- }
- if err != context.DeadlineExceeded {
- t.Fatalf("expected context.DeadlineExceeded, got %v", err)
- }
- })
-}
diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go
deleted file mode 100644
index a36c670747..0000000000
--- a/eth/gasestimator/gasestimator.go
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright 2023 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 gasestimator
-
-import (
- "context"
- "errors"
- "fmt"
- "math"
- "math/big"
-
- "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/core/vm"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
-)
-
-// Options are the contextual parameters to execute the requested call.
-//
-// Whilst it would be possible to pass a blockchain object that aggregates all
-// these together, it would be excessively hard to test. Splitting the parts out
-// allows testing without needing a proper live chain.
-type Options struct {
- Config *params.ChainConfig // Chain configuration for hard fork selection
- Chain core.ChainContext // Chain context to access past block hashes
- Header *types.Header // Header defining the block context to execute in
- State *state.StateDB // Pre-state on top of which to estimate the gas
-
- ErrorRatio float64 // Allowed overestimation ratio for faster estimation termination
-}
-
-// Estimate returns the lowest possible gas limit that allows the transaction to
-// run successfully with the provided context options. It returns an error if the
-// transaction would always revert, or if there are unexpected failures.
-func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uint64) (uint64, []byte, error) {
- // Binary search the gas limit, as it may need to be higher than the amount used
- var (
- lo uint64 // lowest-known gas limit where tx execution fails
- hi uint64 // lowest-known gas limit where tx execution succeeds
- )
- // Determine the highest gas limit can be used during the estimation.
- hi = opts.Header.GasLimit
- if call.GasLimit >= params.TxGas {
- hi = call.GasLimit
- }
- // Normalize the max fee per gas the call is willing to spend.
- var feeCap *big.Int
- if call.GasFeeCap != nil {
- feeCap = call.GasFeeCap
- } else if call.GasPrice != nil {
- feeCap = call.GasPrice
- } else {
- feeCap = common.Big0
- }
- // Recap the highest gas limit with account's available balance.
- if feeCap.BitLen() != 0 {
- balance := opts.State.GetBalance(call.From)
-
- available := new(big.Int).Set(balance)
- if call.Value != nil {
- if call.Value.Cmp(available) >= 0 {
- return 0, nil, core.ErrInsufficientFundsForTransfer
- }
- available.Sub(available, call.Value)
- }
- allowance := new(big.Int).Div(available, feeCap)
-
- // If the allowance is larger than maximum uint64, skip checking
- if allowance.IsUint64() && hi > allowance.Uint64() {
- transfer := call.Value
- if transfer == nil {
- transfer = new(big.Int)
- }
- log.Debug("Gas estimation capped by limited funds", "original", hi, "balance", balance,
- "sent", transfer, "maxFeePerGas", feeCap, "fundable", allowance)
- hi = allowance.Uint64()
- }
- }
- // Recap the highest gas allowance with specified gascap.
- if gasCap != 0 && hi > gasCap {
- log.Debug("Caller gas above allowance, capping", "requested", hi, "cap", gasCap)
- hi = gasCap
- }
- // If the transaction is a plain value transfer, short circuit estimation and
- // directly try 21000. Returning 21000 without any execution is dangerous as
- // some tx field combos might bump the price up even for plain transfers (e.g.
- // unused access list items). Ever so slightly wasteful, but safer overall.
- if len(call.Data) == 0 {
- if call.To != nil && opts.State.GetCodeSize(*call.To) == 0 {
- failed, _, err := execute(ctx, call, opts, params.TxGas)
- if !failed && err == nil {
- return params.TxGas, nil, nil
- }
- }
- }
- // We first execute the transaction at the highest allowable gas limit, since if this fails we
- // can return error immediately.
- failed, result, err := execute(ctx, call, opts, hi)
- if err != nil {
- return 0, nil, err
- }
- if failed {
- if result != nil && !errors.Is(result.Err, vm.ErrOutOfGas) {
- return 0, result.Revert(), result.Err
- }
- return 0, nil, fmt.Errorf("gas required exceeds allowance (%d)", hi)
- }
- // For almost any transaction, the gas consumed by the unconstrained execution
- // above lower-bounds the gas limit required for it to succeed. One exception
- // is those that explicitly check gas remaining in order to execute within a
- // given limit, but we probably don't want to return the lowest possible gas
- // limit for these cases anyway.
- lo = result.UsedGas - 1
-
- // There's a fairly high chance for the transaction to execute successfully
- // with gasLimit set to the first execution's usedGas + gasRefund. Explicitly
- // check that gas amount and use as a limit for the binary search.
- optimisticGasLimit := (result.UsedGas + result.RefundedGas + params.CallStipend) * 64 / 63
- if optimisticGasLimit < hi {
- failed, _, err = execute(ctx, call, opts, optimisticGasLimit)
- if err != nil {
- // This should not happen under normal conditions since if we make it this far the
- // transaction had run without error at least once before.
- log.Error("Execution error in estimate gas", "err", err)
- return 0, nil, err
- }
- if failed {
- lo = optimisticGasLimit
- } else {
- hi = optimisticGasLimit
- }
- }
- // Binary search for the smallest gas limit that allows the tx to execute successfully.
- for lo+1 < hi {
- if opts.ErrorRatio > 0 {
- // It is a bit pointless to return a perfect estimation, as changing
- // network conditions require the caller to bump it up anyway. Since
- // wallets tend to use 20-25% bump, allowing a small approximation
- // error is fine (as long as it's upwards).
- if float64(hi-lo)/float64(hi) < opts.ErrorRatio {
- break
- }
- }
- mid := (hi + lo) / 2
- if mid > lo*2 {
- // Most txs don't need much higher gas limit than their gas used, and most txs don't
- // require near the full block limit of gas, so the selection of where to bisect the
- // range here is skewed to favor the low side.
- mid = lo * 2
- }
- failed, _, err = execute(ctx, call, opts, mid)
- if err != nil {
- // This should not happen under normal conditions since if we make it this far the
- // transaction had run without error at least once before.
- log.Error("Execution error in estimate gas", "err", err)
- return 0, nil, err
- }
- if failed {
- lo = mid
- } else {
- hi = mid
- }
- }
- return hi, nil, nil
-}
-
-// execute is a helper that executes the transaction under a given gas limit and
-// returns true if the transaction fails for a reason that might be related to
-// not enough gas. A non-nil error means execution failed due to reasons unrelated
-// to the gas limit.
-func execute(ctx context.Context, call *core.Message, opts *Options, gasLimit uint64) (bool, *core.ExecutionResult, error) {
- // Configure the call for this specific execution (and revert the change after)
- defer func(gas uint64) { call.GasLimit = gas }(call.GasLimit)
- call.GasLimit = gasLimit
-
- // Execute the call and separate execution faults caused by a lack of gas or
- // other non-fixable conditions
- result, err := run(ctx, call, opts)
- if err != nil {
- if errors.Is(err, core.ErrIntrinsicGas) {
- return true, nil, nil // Special case, raise gas limit
- }
- return true, nil, err // Bail out
- }
- return result.Failed(), result, nil
-}
-
-// run assembles the EVM as defined by the consensus rules and runs the requested
-// call invocation.
-func run(ctx context.Context, call *core.Message, opts *Options) (*core.ExecutionResult, error) {
- // Assemble the call and the call context
- var (
- msgContext = core.NewEVMTxContext(call)
- evmContext = core.NewEVMBlockContext(opts.Header, opts.Chain, nil)
-
- dirtyState = opts.State.Copy()
- evm = vm.NewEVM(evmContext, msgContext, dirtyState, opts.Config, vm.Config{NoBaseFee: true})
- )
- // Monitor the outer context and interrupt the EVM upon cancellation. To avoid
- // a dangling goroutine until the outer estimation finishes, create an internal
- // context for the lifetime of this method call.
- ctx, cancel := context.WithCancel(ctx)
- defer cancel()
-
- go func() {
- <-ctx.Done()
- evm.Cancel()
- }()
- // Execute the call, returning a wrapped error or the result
- result, err := core.ApplyMessage(evm, call, new(core.GasPool).AddGas(math.MaxUint64))
- if vmerr := dirtyState.Error(); vmerr != nil {
- return nil, vmerr
- }
- if err != nil {
- return result, fmt.Errorf("failed with %d gas: %w", call.GasLimit, err)
- }
- return result, nil
-}
diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go
deleted file mode 100644
index 226991b24b..0000000000
--- a/eth/gasprice/feehistory.go
+++ /dev/null
@@ -1,328 +0,0 @@
-// Copyright 2021 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 gasprice
-
-import (
- "context"
- "encoding/binary"
- "errors"
- "fmt"
- "math"
- "math/big"
- "sync/atomic"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/misc/eip1559"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rpc"
- "golang.org/x/exp/slices"
-)
-
-var (
- errInvalidPercentile = errors.New("invalid reward percentile")
- errRequestBeyondHead = errors.New("request beyond head block")
-)
-
-const (
- // maxBlockFetchers is the max number of goroutines to spin up to pull blocks
- // for the fee history calculation (mostly relevant for LES).
- maxBlockFetchers = 4
-)
-
-// blockFees represents a single block for processing
-type blockFees struct {
- // set by the caller
- blockNumber uint64
- header *types.Header
- block *types.Block // only set if reward percentiles are requested
- receipts types.Receipts
- // filled by processBlock
- results processedFees
- err error
-}
-
-type cacheKey struct {
- number uint64
- percentiles string
-}
-
-// processedFees contains the results of a processed block.
-type processedFees struct {
- reward []*big.Int
- baseFee, nextBaseFee *big.Int
- gasUsedRatio float64
-}
-
-// txGasAndReward is sorted in ascending order based on reward
-type txGasAndReward struct {
- gasUsed uint64
- reward *big.Int
-}
-
-// processBlock takes a blockFees structure with the blockNumber, the header and optionally
-// the block field filled in, retrieves the block from the backend if not present yet and
-// fills in the rest of the fields.
-func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
- chainconfig := oracle.backend.ChainConfig()
- if bf.results.baseFee = bf.header.BaseFee; bf.results.baseFee == nil {
- bf.results.baseFee = new(big.Int)
- }
- if chainconfig.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) {
- bf.results.nextBaseFee = eip1559.CalcBaseFee(chainconfig, bf.header)
- } else {
- bf.results.nextBaseFee = new(big.Int)
- }
- bf.results.gasUsedRatio = float64(bf.header.GasUsed) / float64(bf.header.GasLimit)
- if len(percentiles) == 0 {
- // rewards were not requested, return null
- return
- }
- if bf.block == nil || (bf.receipts == nil && len(bf.block.Transactions()) != 0) {
- log.Error("Block or receipts are missing while reward percentiles are requested")
- return
- }
-
- bf.results.reward = make([]*big.Int, len(percentiles))
- if len(bf.block.Transactions()) == 0 {
- // return an all zero row if there are no transactions to gather data from
- for i := range bf.results.reward {
- bf.results.reward[i] = new(big.Int)
- }
- return
- }
-
- sorter := make([]txGasAndReward, len(bf.block.Transactions()))
- for i, tx := range bf.block.Transactions() {
- reward, _ := tx.EffectiveGasTip(bf.block.BaseFee())
- sorter[i] = txGasAndReward{gasUsed: bf.receipts[i].GasUsed, reward: reward}
- }
- slices.SortStableFunc(sorter, func(a, b txGasAndReward) int {
- return a.reward.Cmp(b.reward)
- })
-
- var txIndex int
- sumGasUsed := sorter[0].gasUsed
-
- for i, p := range percentiles {
- thresholdGasUsed := uint64(float64(bf.block.GasUsed()) * p / 100)
- for sumGasUsed < thresholdGasUsed && txIndex < len(bf.block.Transactions())-1 {
- txIndex++
- sumGasUsed += sorter[txIndex].gasUsed
- }
- bf.results.reward[i] = sorter[txIndex].reward
- }
-}
-
-// resolveBlockRange resolves the specified block range to absolute block numbers while also
-// enforcing backend specific limitations. The pending block and corresponding receipts are
-// also returned if requested and available.
-// Note: an error is only returned if retrieving the head header has failed. If there are no
-// retrievable blocks in the specified range then zero block count is returned with no error.
-func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNumber, blocks uint64) (*types.Block, []*types.Receipt, uint64, uint64, error) {
- var (
- headBlock *types.Header
- pendingBlock *types.Block
- pendingReceipts types.Receipts
- err error
- )
-
- // Get the chain's current head.
- if headBlock, err = oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err != nil {
- return nil, nil, 0, 0, err
- }
- head := rpc.BlockNumber(headBlock.Number.Uint64())
-
- // Fail if request block is beyond the chain's current head.
- if head < reqEnd {
- return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, reqEnd, head)
- }
-
- // Resolve block tag.
- if reqEnd < 0 {
- var (
- resolved *types.Header
- err error
- )
- switch reqEnd {
- case rpc.PendingBlockNumber:
- if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil {
- resolved = pendingBlock.Header()
- } else {
- // Pending block not supported by backend, process only until latest block.
- resolved = headBlock
-
- // Update total blocks to return to account for this.
- blocks--
- }
- case rpc.LatestBlockNumber:
- // Retrieved above.
- resolved = headBlock
- case rpc.SafeBlockNumber:
- resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber)
- case rpc.FinalizedBlockNumber:
- resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber)
- case rpc.EarliestBlockNumber:
- resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.EarliestBlockNumber)
- }
- if resolved == nil || err != nil {
- return nil, nil, 0, 0, err
- }
- // Absolute number resolved.
- reqEnd = rpc.BlockNumber(resolved.Number.Uint64())
- }
-
- // If there are no blocks to return, short circuit.
- if blocks == 0 {
- return nil, nil, 0, 0, nil
- }
- // Ensure not trying to retrieve before genesis.
- if uint64(reqEnd+1) < blocks {
- blocks = uint64(reqEnd + 1)
- }
- return pendingBlock, pendingReceipts, uint64(reqEnd), blocks, nil
-}
-
-// FeeHistory returns data relevant for fee estimation based on the specified range of blocks.
-// The range can be specified either with absolute block numbers or ending with the latest
-// or pending block. Backends may or may not support gathering data from the pending block
-// or blocks older than a certain age (specified in maxHistory). The first block of the
-// actually processed range is returned to avoid ambiguity when parts of the requested range
-// are not available or when the head has changed during processing this request.
-// Three arrays are returned based on the processed blocks:
-// - reward: the requested percentiles of effective priority fees per gas of transactions in each
-// block, sorted in ascending order and weighted by gas used.
-// - baseFee: base fee per gas in the given block
-// - gasUsedRatio: gasUsed/gasLimit in the given block
-//
-// Note: baseFee includes the next block after the newest of the returned range, because this
-// value can be derived from the newest block.
-func (oracle *Oracle) FeeHistory(ctx context.Context, blocks uint64, unresolvedLastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
- if blocks < 1 {
- return common.Big0, nil, nil, nil, nil // returning with no data and no error means there are no retrievable blocks
- }
- maxFeeHistory := oracle.maxHeaderHistory
- if len(rewardPercentiles) != 0 {
- maxFeeHistory = oracle.maxBlockHistory
- }
- if blocks > maxFeeHistory {
- log.Warn("Sanitizing fee history length", "requested", blocks, "truncated", maxFeeHistory)
- blocks = maxFeeHistory
- }
- for i, p := range rewardPercentiles {
- if p < 0 || p > 100 {
- return common.Big0, nil, nil, nil, fmt.Errorf("%w: %f", errInvalidPercentile, p)
- }
- if i > 0 && p < rewardPercentiles[i-1] {
- return common.Big0, nil, nil, nil, fmt.Errorf("%w: #%d:%f > #%d:%f", errInvalidPercentile, i-1, rewardPercentiles[i-1], i, p)
- }
- }
- var (
- pendingBlock *types.Block
- pendingReceipts []*types.Receipt
- err error
- )
- pendingBlock, pendingReceipts, lastBlock, blocks, err := oracle.resolveBlockRange(ctx, unresolvedLastBlock, blocks)
- if err != nil || blocks == 0 {
- return common.Big0, nil, nil, nil, err
- }
- oldestBlock := lastBlock + 1 - blocks
-
- var next atomic.Uint64
- next.Store(oldestBlock)
- results := make(chan *blockFees, blocks)
-
- percentileKey := make([]byte, 8*len(rewardPercentiles))
- for i, p := range rewardPercentiles {
- binary.LittleEndian.PutUint64(percentileKey[i*8:(i+1)*8], math.Float64bits(p))
- }
- for i := 0; i < maxBlockFetchers && i < int(blocks); i++ {
- go func() {
- for {
- // Retrieve the next block number to fetch with this goroutine
- blockNumber := next.Add(1) - 1
- if blockNumber > lastBlock {
- return
- }
-
- fees := &blockFees{blockNumber: blockNumber}
- if pendingBlock != nil && blockNumber >= pendingBlock.NumberU64() {
- fees.block, fees.receipts = pendingBlock, pendingReceipts
- fees.header = fees.block.Header()
- oracle.processBlock(fees, rewardPercentiles)
- results <- fees
- } else {
- cacheKey := cacheKey{number: blockNumber, percentiles: string(percentileKey)}
-
- if p, ok := oracle.historyCache.Get(cacheKey); ok {
- fees.results = p
- results <- fees
- } else {
- if len(rewardPercentiles) != 0 {
- fees.block, fees.err = oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNumber))
- if fees.block != nil && fees.err == nil {
- fees.receipts, fees.err = oracle.backend.GetReceipts(ctx, fees.block.Hash())
- fees.header = fees.block.Header()
- }
- } else {
- fees.header, fees.err = oracle.backend.HeaderByNumber(ctx, rpc.BlockNumber(blockNumber))
- }
- if fees.header != nil && fees.err == nil {
- oracle.processBlock(fees, rewardPercentiles)
- if fees.err == nil {
- oracle.historyCache.Add(cacheKey, fees.results)
- }
- }
- // send to results even if empty to guarantee that blocks items are sent in total
- results <- fees
- }
- }
- }
- }()
- }
- var (
- reward = make([][]*big.Int, blocks)
- baseFee = make([]*big.Int, blocks+1)
- gasUsedRatio = make([]float64, blocks)
- firstMissing = blocks
- )
- for ; blocks > 0; blocks-- {
- fees := <-results
- if fees.err != nil {
- return common.Big0, nil, nil, nil, fees.err
- }
- i := fees.blockNumber - oldestBlock
- if fees.results.baseFee != nil {
- reward[i], baseFee[i], baseFee[i+1], gasUsedRatio[i] = fees.results.reward, fees.results.baseFee, fees.results.nextBaseFee, fees.results.gasUsedRatio
- } else {
- // getting no block and no error means we are requesting into the future (might happen because of a reorg)
- if i < firstMissing {
- firstMissing = i
- }
- }
- }
- if firstMissing == 0 {
- return common.Big0, nil, nil, nil, nil
- }
- if len(rewardPercentiles) != 0 {
- reward = reward[:firstMissing]
- } else {
- reward = nil
- }
- baseFee, gasUsedRatio = baseFee[:firstMissing+1], gasUsedRatio[:firstMissing]
- return new(big.Int).SetUint64(oldestBlock), reward, baseFee, gasUsedRatio, nil
-}
diff --git a/eth/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go
deleted file mode 100644
index 1bcfb287a5..0000000000
--- a/eth/gasprice/feehistory_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2021 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 gasprice
-
-import (
- "context"
- "errors"
- "math/big"
- "testing"
-
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-func TestFeeHistory(t *testing.T) {
- var cases = []struct {
- pending bool
- maxHeader, maxBlock uint64
- count uint64
- last rpc.BlockNumber
- percent []float64
- expFirst uint64
- expCount int
- expErr error
- }{
- {false, 1000, 1000, 10, 30, nil, 21, 10, nil},
- {false, 1000, 1000, 10, 30, []float64{0, 10}, 21, 10, nil},
- {false, 1000, 1000, 10, 30, []float64{20, 10}, 0, 0, errInvalidPercentile},
- {false, 1000, 1000, 1000000000, 30, nil, 0, 31, nil},
- {false, 1000, 1000, 1000000000, rpc.LatestBlockNumber, nil, 0, 33, nil},
- {false, 1000, 1000, 10, 40, nil, 0, 0, errRequestBeyondHead},
- {true, 1000, 1000, 10, 40, nil, 0, 0, errRequestBeyondHead},
- {false, 20, 2, 100, rpc.LatestBlockNumber, nil, 13, 20, nil},
- {false, 20, 2, 100, rpc.LatestBlockNumber, []float64{0, 10}, 31, 2, nil},
- {false, 20, 2, 100, 32, []float64{0, 10}, 31, 2, nil},
- {false, 1000, 1000, 1, rpc.PendingBlockNumber, nil, 0, 0, nil},
- {false, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 1, nil},
- {true, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 2, nil},
- {true, 1000, 1000, 2, rpc.PendingBlockNumber, []float64{0, 10}, 32, 2, nil},
- {false, 1000, 1000, 2, rpc.FinalizedBlockNumber, []float64{0, 10}, 24, 2, nil},
- {false, 1000, 1000, 2, rpc.SafeBlockNumber, []float64{0, 10}, 24, 2, nil},
- }
- for i, c := range cases {
- config := Config{
- MaxHeaderHistory: c.maxHeader,
- MaxBlockHistory: c.maxBlock,
- }
- backend := newTestBackend(t, big.NewInt(16), c.pending)
- oracle := NewOracle(backend, config)
-
- first, reward, baseFee, ratio, err := oracle.FeeHistory(context.Background(), c.count, c.last, c.percent)
- backend.teardown()
- expReward := c.expCount
- if len(c.percent) == 0 {
- expReward = 0
- }
- expBaseFee := c.expCount
- if expBaseFee != 0 {
- expBaseFee++
- }
-
- if first.Uint64() != c.expFirst {
- t.Fatalf("Test case %d: first block mismatch, want %d, got %d", i, c.expFirst, first)
- }
- if len(reward) != expReward {
- t.Fatalf("Test case %d: reward array length mismatch, want %d, got %d", i, expReward, len(reward))
- }
- if len(baseFee) != expBaseFee {
- t.Fatalf("Test case %d: baseFee array length mismatch, want %d, got %d", i, expBaseFee, len(baseFee))
- }
- if len(ratio) != c.expCount {
- t.Fatalf("Test case %d: gasUsedRatio array length mismatch, want %d, got %d", i, c.expCount, len(ratio))
- }
- if err != c.expErr && !errors.Is(err, c.expErr) {
- t.Fatalf("Test case %d: error mismatch, want %v, got %v", i, c.expErr, err)
- }
- }
-}
diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go
deleted file mode 100644
index b719649811..0000000000
--- a/eth/gasprice/gasprice.go
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2015 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 gasprice
-
-import (
- "context"
- "math/big"
- "sync"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/lru"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
- "golang.org/x/exp/slices"
-)
-
-const sampleNumber = 3 // Number of transactions sampled in a block
-
-var (
- DefaultMaxPrice = big.NewInt(500 * params.GWei)
- DefaultIgnorePrice = big.NewInt(2 * params.Wei)
-)
-
-type Config struct {
- Blocks int
- Percentile int
- MaxHeaderHistory uint64
- MaxBlockHistory uint64
- Default *big.Int `toml:",omitempty"`
- MaxPrice *big.Int `toml:",omitempty"`
- IgnorePrice *big.Int `toml:",omitempty"`
-}
-
-// OracleBackend includes all necessary background APIs for oracle.
-type OracleBackend interface {
- HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
- BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
- GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error)
- PendingBlockAndReceipts() (*types.Block, types.Receipts)
- ChainConfig() *params.ChainConfig
- SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
-}
-
-// Oracle recommends gas prices based on the content of recent
-// blocks. Suitable for both light and full clients.
-type Oracle struct {
- backend OracleBackend
- lastHead common.Hash
- lastPrice *big.Int
- maxPrice *big.Int
- ignorePrice *big.Int
- cacheLock sync.RWMutex
- fetchLock sync.Mutex
-
- checkBlocks, percentile int
- maxHeaderHistory, maxBlockHistory uint64
-
- historyCache *lru.Cache[cacheKey, processedFees]
-}
-
-// NewOracle returns a new gasprice oracle which can recommend suitable
-// gasprice for newly created transaction.
-func NewOracle(backend OracleBackend, params Config) *Oracle {
- blocks := params.Blocks
- if blocks < 1 {
- blocks = 1
- log.Warn("Sanitizing invalid gasprice oracle sample blocks", "provided", params.Blocks, "updated", blocks)
- }
- percent := params.Percentile
- if percent < 0 {
- percent = 0
- log.Warn("Sanitizing invalid gasprice oracle sample percentile", "provided", params.Percentile, "updated", percent)
- } else if percent > 100 {
- percent = 100
- log.Warn("Sanitizing invalid gasprice oracle sample percentile", "provided", params.Percentile, "updated", percent)
- }
- maxPrice := params.MaxPrice
- if maxPrice == nil || maxPrice.Int64() <= 0 {
- maxPrice = DefaultMaxPrice
- log.Warn("Sanitizing invalid gasprice oracle price cap", "provided", params.MaxPrice, "updated", maxPrice)
- }
- ignorePrice := params.IgnorePrice
- if ignorePrice == nil || ignorePrice.Int64() <= 0 {
- ignorePrice = DefaultIgnorePrice
- log.Warn("Sanitizing invalid gasprice oracle ignore price", "provided", params.IgnorePrice, "updated", ignorePrice)
- } else if ignorePrice.Int64() > 0 {
- log.Info("Gasprice oracle is ignoring threshold set", "threshold", ignorePrice)
- }
- maxHeaderHistory := params.MaxHeaderHistory
- if maxHeaderHistory < 1 {
- maxHeaderHistory = 1
- log.Warn("Sanitizing invalid gasprice oracle max header history", "provided", params.MaxHeaderHistory, "updated", maxHeaderHistory)
- }
- maxBlockHistory := params.MaxBlockHistory
- if maxBlockHistory < 1 {
- maxBlockHistory = 1
- log.Warn("Sanitizing invalid gasprice oracle max block history", "provided", params.MaxBlockHistory, "updated", maxBlockHistory)
- }
-
- cache := lru.NewCache[cacheKey, processedFees](2048)
- headEvent := make(chan core.ChainHeadEvent, 1)
- backend.SubscribeChainHeadEvent(headEvent)
- go func() {
- var lastHead common.Hash
- for ev := range headEvent {
- if ev.Block.ParentHash() != lastHead {
- cache.Purge()
- }
- lastHead = ev.Block.Hash()
- }
- }()
-
- return &Oracle{
- backend: backend,
- lastPrice: params.Default,
- maxPrice: maxPrice,
- ignorePrice: ignorePrice,
- checkBlocks: blocks,
- percentile: percent,
- maxHeaderHistory: maxHeaderHistory,
- maxBlockHistory: maxBlockHistory,
- historyCache: cache,
- }
-}
-
-// SuggestTipCap returns a tip cap so that newly created transaction can have a
-// very high chance to be included in the following blocks.
-//
-// Note, for legacy transactions and the legacy eth_gasPrice RPC call, it will be
-// necessary to add the basefee to the returned number to fall back to the legacy
-// behavior.
-func (oracle *Oracle) SuggestTipCap(ctx context.Context) (*big.Int, error) {
- head, _ := oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
- headHash := head.Hash()
-
- // If the latest gasprice is still available, return it.
- oracle.cacheLock.RLock()
- lastHead, lastPrice := oracle.lastHead, oracle.lastPrice
- oracle.cacheLock.RUnlock()
- if headHash == lastHead {
- return new(big.Int).Set(lastPrice), nil
- }
- oracle.fetchLock.Lock()
- defer oracle.fetchLock.Unlock()
-
- // Try checking the cache again, maybe the last fetch fetched what we need
- oracle.cacheLock.RLock()
- lastHead, lastPrice = oracle.lastHead, oracle.lastPrice
- oracle.cacheLock.RUnlock()
- if headHash == lastHead {
- return new(big.Int).Set(lastPrice), nil
- }
- var (
- sent, exp int
- number = head.Number.Uint64()
- result = make(chan results, oracle.checkBlocks)
- quit = make(chan struct{})
- results []*big.Int
- )
- for sent < oracle.checkBlocks && number > 0 {
- go oracle.getBlockValues(ctx, number, sampleNumber, oracle.ignorePrice, result, quit)
- sent++
- exp++
- number--
- }
- for exp > 0 {
- res := <-result
- if res.err != nil {
- close(quit)
- return new(big.Int).Set(lastPrice), res.err
- }
- exp--
- // Nothing returned. There are two special cases here:
- // - The block is empty
- // - All the transactions included are sent by the miner itself.
- // In these cases, use the latest calculated price for sampling.
- if len(res.values) == 0 {
- res.values = []*big.Int{lastPrice}
- }
- // Besides, in order to collect enough data for sampling, if nothing
- // meaningful returned, try to query more blocks. But the maximum
- // is 2*checkBlocks.
- if len(res.values) == 1 && len(results)+1+exp < oracle.checkBlocks*2 && number > 0 {
- go oracle.getBlockValues(ctx, number, sampleNumber, oracle.ignorePrice, result, quit)
- sent++
- exp++
- number--
- }
- results = append(results, res.values...)
- }
- price := lastPrice
- if len(results) > 0 {
- slices.SortFunc(results, func(a, b *big.Int) int { return a.Cmp(b) })
- price = results[(len(results)-1)*oracle.percentile/100]
- }
- if price.Cmp(oracle.maxPrice) > 0 {
- price = new(big.Int).Set(oracle.maxPrice)
- }
- oracle.cacheLock.Lock()
- oracle.lastHead = headHash
- oracle.lastPrice = price
- oracle.cacheLock.Unlock()
-
- return new(big.Int).Set(price), nil
-}
-
-type results struct {
- values []*big.Int
- err error
-}
-
-// getBlockValues calculates the lowest transaction gas price in a given block
-// and sends it to the result channel. If the block is empty or all transactions
-// are sent by the miner itself(it doesn't make any sense to include this kind of
-// transaction prices for sampling), nil gasprice is returned.
-func (oracle *Oracle) getBlockValues(ctx context.Context, blockNum uint64, limit int, ignoreUnder *big.Int, result chan results, quit chan struct{}) {
- block, err := oracle.backend.BlockByNumber(ctx, rpc.BlockNumber(blockNum))
- if block == nil {
- select {
- case result <- results{nil, err}:
- case <-quit:
- }
- return
- }
- signer := types.MakeSigner(oracle.backend.ChainConfig(), block.Number(), block.Time())
-
- // Sort the transaction by effective tip in ascending sort.
- txs := block.Transactions()
- sortedTxs := make([]*types.Transaction, len(txs))
- copy(sortedTxs, txs)
- baseFee := block.BaseFee()
- slices.SortFunc(sortedTxs, func(a, b *types.Transaction) int {
- // It's okay to discard the error because a tx would never be
- // accepted into a block with an invalid effective tip.
- tip1, _ := a.EffectiveGasTip(baseFee)
- tip2, _ := b.EffectiveGasTip(baseFee)
- return tip1.Cmp(tip2)
- })
-
- var prices []*big.Int
- for _, tx := range sortedTxs {
- tip, _ := tx.EffectiveGasTip(baseFee)
- if ignoreUnder != nil && tip.Cmp(ignoreUnder) == -1 {
- continue
- }
- sender, err := types.Sender(signer, tx)
- if err == nil && sender != block.Coinbase() {
- prices = append(prices, tip)
- if len(prices) >= limit {
- break
- }
- }
- }
- select {
- case result <- results{prices, nil}:
- case <-quit:
- }
-}
diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go
deleted file mode 100644
index 4ee5a0d1b2..0000000000
--- a/eth/gasprice/gasprice_test.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2020 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 gasprice
-
-import (
- "context"
- "math"
- "math/big"
- "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/event"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-const testHead = 32
-
-type testBackend struct {
- chain *core.BlockChain
- pending bool // pending block available
-}
-
-func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
- if number > testHead {
- return nil, nil
- }
- if number == rpc.EarliestBlockNumber {
- number = 0
- }
- if number == rpc.FinalizedBlockNumber {
- return b.chain.CurrentFinalBlock(), nil
- }
- if number == rpc.SafeBlockNumber {
- return b.chain.CurrentSafeBlock(), nil
- }
- if number == rpc.LatestBlockNumber {
- number = testHead
- }
- if number == rpc.PendingBlockNumber {
- if b.pending {
- number = testHead + 1
- } else {
- return nil, nil
- }
- }
- return b.chain.GetHeaderByNumber(uint64(number)), nil
-}
-
-func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
- if number > testHead {
- return nil, nil
- }
- if number == rpc.EarliestBlockNumber {
- number = 0
- }
- if number == rpc.FinalizedBlockNumber {
- number = rpc.BlockNumber(b.chain.CurrentFinalBlock().Number.Uint64())
- }
- if number == rpc.SafeBlockNumber {
- number = rpc.BlockNumber(b.chain.CurrentSafeBlock().Number.Uint64())
- }
- if number == rpc.LatestBlockNumber {
- number = testHead
- }
- if number == rpc.PendingBlockNumber {
- if b.pending {
- number = testHead + 1
- } else {
- return nil, nil
- }
- }
- return b.chain.GetBlockByNumber(uint64(number)), nil
-}
-
-func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
- return b.chain.GetReceiptsByHash(hash), nil
-}
-
-func (b *testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
- if b.pending {
- block := b.chain.GetBlockByNumber(testHead + 1)
- return block, b.chain.GetReceiptsByHash(block.Hash())
- }
- return nil, nil
-}
-
-func (b *testBackend) ChainConfig() *params.ChainConfig {
- return b.chain.Config()
-}
-
-func (b *testBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription {
- return nil
-}
-
-func (b *testBackend) teardown() {
- b.chain.Stop()
-}
-
-// newTestBackend creates a test backend. OBS: don't forget to invoke tearDown
-// after use, otherwise the blockchain instance will mem-leak via goroutines.
-func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBackend {
- var (
- key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- addr = crypto.PubkeyToAddress(key.PublicKey)
- config = *params.TestChainConfig // needs copy because it is modified below
- gspec = &core.Genesis{
- Config: &config,
- Alloc: core.GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}},
- }
- signer = types.LatestSigner(gspec.Config)
- )
- config.LondonBlock = londonBlock
- config.ArrowGlacierBlock = londonBlock
- config.GrayGlacierBlock = londonBlock
- config.TerminalTotalDifficulty = common.Big0
- engine := ethash.NewFaker()
-
- // Generate testing blocks
- _, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, testHead+1, func(i int, b *core.BlockGen) {
- b.SetCoinbase(common.Address{1})
-
- var txdata types.TxData
- if londonBlock != nil && b.Number().Cmp(londonBlock) >= 0 {
- txdata = &types.DynamicFeeTx{
- ChainID: gspec.Config.ChainID,
- Nonce: b.TxNonce(addr),
- To: &common.Address{},
- Gas: 30000,
- GasFeeCap: big.NewInt(100 * params.GWei),
- GasTipCap: big.NewInt(int64(i+1) * params.GWei),
- Data: []byte{},
- }
- } else {
- txdata = &types.LegacyTx{
- Nonce: b.TxNonce(addr),
- To: &common.Address{},
- Gas: 21000,
- GasPrice: big.NewInt(int64(i+1) * params.GWei),
- Value: big.NewInt(100),
- Data: []byte{},
- }
- }
- b.AddTx(types.MustSignNewTx(key, signer, txdata))
- })
- // Construct testing chain
- chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec, nil, engine, vm.Config{}, nil, nil)
- if err != nil {
- t.Fatalf("Failed to create local chain, %v", err)
- }
- chain.InsertChain(blocks)
- chain.SetFinalized(chain.GetBlockByNumber(25).Header())
- chain.SetSafe(chain.GetBlockByNumber(25).Header())
- return &testBackend{chain: chain, pending: pending}
-}
-
-func (b *testBackend) CurrentHeader() *types.Header {
- return b.chain.CurrentHeader()
-}
-
-func (b *testBackend) GetBlockByNumber(number uint64) *types.Block {
- return b.chain.GetBlockByNumber(number)
-}
-
-func TestSuggestTipCap(t *testing.T) {
- config := Config{
- Blocks: 3,
- Percentile: 60,
- Default: big.NewInt(params.GWei),
- }
- var cases = []struct {
- fork *big.Int // London fork number
- expect *big.Int // Expected gasprice suggestion
- }{
- {nil, big.NewInt(params.GWei * int64(30))},
- {big.NewInt(0), big.NewInt(params.GWei * int64(30))}, // Fork point in genesis
- {big.NewInt(1), big.NewInt(params.GWei * int64(30))}, // Fork point in first block
- {big.NewInt(32), big.NewInt(params.GWei * int64(30))}, // Fork point in last block
- {big.NewInt(33), big.NewInt(params.GWei * int64(30))}, // Fork point in the future
- }
- for _, c := range cases {
- backend := newTestBackend(t, c.fork, false)
- oracle := NewOracle(backend, config)
-
- // The gas price sampled is: 32G, 31G, 30G, 29G, 28G, 27G
- got, err := oracle.SuggestTipCap(context.Background())
- backend.teardown()
- if err != nil {
- t.Fatalf("Failed to retrieve recommended gas price: %v", err)
- }
- if got.Cmp(c.expect) != 0 {
- t.Fatalf("Gas price mismatch, want %d, got %d", c.expect, got)
- }
- }
-}
diff --git a/eth/handler.go b/eth/handler.go
deleted file mode 100644
index a327af6113..0000000000
--- a/eth/handler.go
+++ /dev/null
@@ -1,692 +0,0 @@
-// Copyright 2015 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 eth
-
-import (
- "errors"
- "math"
- "math/big"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/beacon"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/forkid"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/txpool"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/fetcher"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/eth/protocols/snap"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/trie/triedb/pathdb"
-)
-
-const (
- // txChanSize is the size of channel listening to NewTxsEvent.
- // The number is referenced from the size of tx pool.
- txChanSize = 4096
-
- // txMaxBroadcastSize is the max size of a transaction that will be broadcasted.
- // All transactions with a higher size will be announced and need to be fetched
- // by the peer.
- txMaxBroadcastSize = 4096
-)
-
-var syncChallengeTimeout = 15 * time.Second // Time allowance for a node to reply to the sync progress challenge
-
-// txPool defines the methods needed from a transaction pool implementation to
-// support all the operations needed by the Ethereum chain protocols.
-type txPool interface {
- // Has returns an indicator whether txpool has a transaction
- // cached with the given hash.
- Has(hash common.Hash) bool
-
- // Get retrieves the transaction from local txpool with given
- // tx hash.
- Get(hash common.Hash) *types.Transaction
-
- // Add should add the given transactions to the pool.
- Add(txs []*types.Transaction, local bool, sync bool) []error
-
- // Pending should return pending transactions.
- // The slice should be modifiable by the caller.
- Pending(enforceTips bool) map[common.Address][]*txpool.LazyTransaction
-
- // SubscribeTransactions subscribes to new transaction events. The subscriber
- // can decide whether to receive notifications only for newly seen transactions
- // or also for reorged out ones.
- SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool) event.Subscription
-}
-
-// handlerConfig is the collection of initialization parameters to create a full
-// node network handler.
-type handlerConfig struct {
- Database ethdb.Database // Database for direct sync insertions
- Chain *core.BlockChain // Blockchain to serve data from
- TxPool txPool // Transaction pool to propagate from
- Merger *consensus.Merger // The manager for eth1/2 transition
- Network uint64 // Network identifier to advertise
- Sync downloader.SyncMode // Whether to snap or full sync
- BloomCache uint64 // Megabytes to alloc for snap sync bloom
- EventMux *event.TypeMux // Legacy event mux, deprecate for `feed`
- RequiredBlocks map[uint64]common.Hash // Hard coded map of required block hashes for sync challenges
-}
-
-type handler struct {
- networkID uint64
- forkFilter forkid.Filter // Fork ID filter, constant across the lifetime of the node
-
- snapSync atomic.Bool // Flag whether snap sync is enabled (gets disabled if we already have blocks)
- synced atomic.Bool // Flag whether we're considered synchronised (enables transaction processing)
-
- database ethdb.Database
- txpool txPool
- chain *core.BlockChain
- maxPeers int
-
- downloader *downloader.Downloader
- blockFetcher *fetcher.BlockFetcher
- txFetcher *fetcher.TxFetcher
- peers *peerSet
- merger *consensus.Merger
-
- eventMux *event.TypeMux
- txsCh chan core.NewTxsEvent
- txsSub event.Subscription
- minedBlockSub *event.TypeMuxSubscription
-
- requiredBlocks map[uint64]common.Hash
-
- // channels for fetcher, syncer, txsyncLoop
- quitSync chan struct{}
-
- chainSync *chainSyncer
- wg sync.WaitGroup
-
- handlerStartCh chan struct{}
- handlerDoneCh chan struct{}
-}
-
-// newHandler returns a handler for all Ethereum chain management protocol.
-func newHandler(config *handlerConfig) (*handler, error) {
- // Create the protocol manager with the base fields
- if config.EventMux == nil {
- config.EventMux = new(event.TypeMux) // Nicety initialization for tests
- }
- h := &handler{
- networkID: config.Network,
- forkFilter: forkid.NewFilter(config.Chain),
- eventMux: config.EventMux,
- database: config.Database,
- txpool: config.TxPool,
- chain: config.Chain,
- peers: newPeerSet(),
- merger: config.Merger,
- requiredBlocks: config.RequiredBlocks,
- quitSync: make(chan struct{}),
- handlerDoneCh: make(chan struct{}),
- handlerStartCh: make(chan struct{}),
- }
- if config.Sync == downloader.FullSync {
- // The database seems empty as the current block is the genesis. Yet the snap
- // block is ahead, so snap sync was enabled for this node at a certain point.
- // The scenarios where this can happen is
- // * if the user manually (or via a bad block) rolled back a snap sync node
- // below the sync point.
- // * the last snap sync is not finished while user specifies a full sync this
- // time. But we don't have any recent state for full sync.
- // In these cases however it's safe to reenable snap sync.
- fullBlock, snapBlock := h.chain.CurrentBlock(), h.chain.CurrentSnapBlock()
- if fullBlock.Number.Uint64() == 0 && snapBlock.Number.Uint64() > 0 {
- h.snapSync.Store(true)
- log.Warn("Switch sync mode from full sync to snap sync", "reason", "snap sync incomplete")
- } else if !h.chain.HasState(fullBlock.Root) {
- h.snapSync.Store(true)
- log.Warn("Switch sync mode from full sync to snap sync", "reason", "head state missing")
- }
- } else {
- head := h.chain.CurrentBlock()
- if head.Number.Uint64() > 0 && h.chain.HasState(head.Root) {
- // Print warning log if database is not empty to run snap sync.
- log.Warn("Switch sync mode from snap sync to full sync", "reason", "snap sync complete")
- } else {
- // If snap sync was requested and our database is empty, grant it
- h.snapSync.Store(true)
- log.Info("Enabled snap sync", "head", head.Number, "hash", head.Hash())
- }
- }
- // If snap sync is requested but snapshots are disabled, fail loudly
- if h.snapSync.Load() && config.Chain.Snapshots() == nil {
- return nil, errors.New("snap sync not supported with snapshots disabled")
- }
- // Construct the downloader (long sync)
- h.downloader = downloader.New(config.Database, h.eventMux, h.chain, nil, h.removePeer, h.enableSyncedFeatures)
- if ttd := h.chain.Config().TerminalTotalDifficulty; ttd != nil {
- if h.chain.Config().TerminalTotalDifficultyPassed {
- log.Info("Chain post-merge, sync via beacon client")
- } else {
- head := h.chain.CurrentBlock()
- if td := h.chain.GetTd(head.Hash(), head.Number.Uint64()); td.Cmp(ttd) >= 0 {
- log.Info("Chain post-TTD, sync via beacon client")
- } else {
- log.Warn("Chain pre-merge, sync via PoW (ensure beacon client is ready)")
- }
- }
- } else if h.chain.Config().TerminalTotalDifficultyPassed {
- log.Error("Chain configured post-merge, but without TTD. Are you debugging sync?")
- }
- // Construct the fetcher (short sync)
- validator := func(header *types.Header) error {
- // All the block fetcher activities should be disabled
- // after the transition. Print the warning log.
- if h.merger.PoSFinalized() {
- log.Warn("Unexpected validation activity", "hash", header.Hash(), "number", header.Number)
- return errors.New("unexpected behavior after transition")
- }
- // Reject all the PoS style headers in the first place. No matter
- // the chain has finished the transition or not, the PoS headers
- // should only come from the trusted consensus layer instead of
- // p2p network.
- if beacon, ok := h.chain.Engine().(*beacon.Beacon); ok {
- if beacon.IsPoSHeader(header) {
- return errors.New("unexpected post-merge header")
- }
- }
- return h.chain.Engine().VerifyHeader(h.chain, header)
- }
- heighter := func() uint64 {
- return h.chain.CurrentBlock().Number.Uint64()
- }
- inserter := func(blocks types.Blocks) (int, error) {
- // All the block fetcher activities should be disabled
- // after the transition. Print the warning log.
- if h.merger.PoSFinalized() {
- var ctx []interface{}
- ctx = append(ctx, "blocks", len(blocks))
- if len(blocks) > 0 {
- ctx = append(ctx, "firsthash", blocks[0].Hash())
- ctx = append(ctx, "firstnumber", blocks[0].Number())
- ctx = append(ctx, "lasthash", blocks[len(blocks)-1].Hash())
- ctx = append(ctx, "lastnumber", blocks[len(blocks)-1].Number())
- }
- log.Warn("Unexpected insertion activity", ctx...)
- return 0, errors.New("unexpected behavior after transition")
- }
- // If snap sync is running, deny importing weird blocks. This is a problematic
- // clause when starting up a new network, because snap-syncing miners might not
- // accept each others' blocks until a restart. Unfortunately we haven't figured
- // out a way yet where nodes can decide unilaterally whether the network is new
- // or not. This should be fixed if we figure out a solution.
- if !h.synced.Load() {
- log.Warn("Syncing, discarded propagated block", "number", blocks[0].Number(), "hash", blocks[0].Hash())
- return 0, nil
- }
- if h.merger.TDDReached() {
- // The blocks from the p2p network is regarded as untrusted
- // after the transition. In theory block gossip should be disabled
- // entirely whenever the transition is started. But in order to
- // handle the transition boundary reorg in the consensus-layer,
- // the legacy blocks are still accepted, but only for the terminal
- // pow blocks. Spec: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3675.md#halt-the-importing-of-pow-blocks
- for i, block := range blocks {
- ptd := h.chain.GetTd(block.ParentHash(), block.NumberU64()-1)
- if ptd == nil {
- return 0, nil
- }
- td := new(big.Int).Add(ptd, block.Difficulty())
- if !h.chain.Config().IsTerminalPoWBlock(ptd, td) {
- log.Info("Filtered out non-terminal pow block", "number", block.NumberU64(), "hash", block.Hash())
- return 0, nil
- }
- if err := h.chain.InsertBlockWithoutSetHead(block); err != nil {
- return i, err
- }
- }
- return 0, nil
- }
- return h.chain.InsertChain(blocks)
- }
- h.blockFetcher = fetcher.NewBlockFetcher(false, nil, h.chain.GetBlockByHash, validator, h.BroadcastBlock, heighter, nil, inserter, h.removePeer)
-
- fetchTx := func(peer string, hashes []common.Hash) error {
- p := h.peers.peer(peer)
- if p == nil {
- return errors.New("unknown peer")
- }
- return p.RequestTxs(hashes)
- }
- addTxs := func(txs []*types.Transaction) []error {
- return h.txpool.Add(txs, false, false)
- }
- h.txFetcher = fetcher.NewTxFetcher(h.txpool.Has, addTxs, fetchTx, h.removePeer)
- h.chainSync = newChainSyncer(h)
- return h, nil
-}
-
-// protoTracker tracks the number of active protocol handlers.
-func (h *handler) protoTracker() {
- defer h.wg.Done()
- var active int
- for {
- select {
- case <-h.handlerStartCh:
- active++
- case <-h.handlerDoneCh:
- active--
- case <-h.quitSync:
- // Wait for all active handlers to finish.
- for ; active > 0; active-- {
- <-h.handlerDoneCh
- }
- return
- }
- }
-}
-
-// incHandlers signals to increment the number of active handlers if not
-// quitting.
-func (h *handler) incHandlers() bool {
- select {
- case h.handlerStartCh <- struct{}{}:
- return true
- case <-h.quitSync:
- return false
- }
-}
-
-// decHandlers signals to decrement the number of active handlers.
-func (h *handler) decHandlers() {
- h.handlerDoneCh <- struct{}{}
-}
-
-// runEthPeer registers an eth peer into the joint eth/snap peerset, adds it to
-// various subsystems and starts handling messages.
-func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error {
- if !h.incHandlers() {
- return p2p.DiscQuitting
- }
- defer h.decHandlers()
-
- // If the peer has a `snap` extension, wait for it to connect so we can have
- // a uniform initialization/teardown mechanism
- snap, err := h.peers.waitSnapExtension(peer)
- if err != nil {
- peer.Log().Error("Snapshot extension barrier failed", "err", err)
- return err
- }
-
- // Execute the Ethereum handshake
- var (
- genesis = h.chain.Genesis()
- head = h.chain.CurrentHeader()
- hash = head.Hash()
- number = head.Number.Uint64()
- td = h.chain.GetTd(hash, number)
- )
- forkID := forkid.NewID(h.chain.Config(), genesis, number, head.Time)
- if err := peer.Handshake(h.networkID, td, hash, genesis.Hash(), forkID, h.forkFilter); err != nil {
- peer.Log().Debug("Ethereum handshake failed", "err", err)
- return err
- }
- reject := false // reserved peer slots
- if h.snapSync.Load() {
- if snap == nil {
- // If we are running snap-sync, we want to reserve roughly half the peer
- // slots for peers supporting the snap protocol.
- // The logic here is; we only allow up to 5 more non-snap peers than snap-peers.
- if all, snp := h.peers.len(), h.peers.snapLen(); all-snp > snp+5 {
- reject = true
- }
- }
- }
- // Ignore maxPeers if this is a trusted peer
- if !peer.Peer.Info().Network.Trusted {
- if reject || h.peers.len() >= h.maxPeers {
- return p2p.DiscTooManyPeers
- }
- }
- peer.Log().Debug("Ethereum peer connected", "name", peer.Name())
-
- // Register the peer locally
- if err := h.peers.registerPeer(peer, snap); err != nil {
- peer.Log().Error("Ethereum peer registration failed", "err", err)
- return err
- }
- defer h.unregisterPeer(peer.ID())
-
- p := h.peers.peer(peer.ID())
- if p == nil {
- return errors.New("peer dropped during handling")
- }
- // Register the peer in the downloader. If the downloader considers it banned, we disconnect
- if err := h.downloader.RegisterPeer(peer.ID(), peer.Version(), peer); err != nil {
- peer.Log().Error("Failed to register peer in eth syncer", "err", err)
- return err
- }
- if snap != nil {
- if err := h.downloader.SnapSyncer.Register(snap); err != nil {
- peer.Log().Error("Failed to register peer in snap syncer", "err", err)
- return err
- }
- }
- h.chainSync.handlePeerEvent()
-
- // Propagate existing transactions. new transactions appearing
- // after this will be sent via broadcasts.
- h.syncTransactions(peer)
-
- // Create a notification channel for pending requests if the peer goes down
- dead := make(chan struct{})
- defer close(dead)
-
- // If we have any explicit peer required block hashes, request them
- for number, hash := range h.requiredBlocks {
- resCh := make(chan *eth.Response)
-
- req, err := peer.RequestHeadersByNumber(number, 1, 0, false, resCh)
- if err != nil {
- return err
- }
- go func(number uint64, hash common.Hash, req *eth.Request) {
- // Ensure the request gets cancelled in case of error/drop
- defer req.Close()
-
- timeout := time.NewTimer(syncChallengeTimeout)
- defer timeout.Stop()
-
- select {
- case res := <-resCh:
- headers := ([]*types.Header)(*res.Res.(*eth.BlockHeadersRequest))
- if len(headers) == 0 {
- // Required blocks are allowed to be missing if the remote
- // node is not yet synced
- res.Done <- nil
- return
- }
- // Validate the header and either drop the peer or continue
- if len(headers) > 1 {
- res.Done <- errors.New("too many headers in required block response")
- return
- }
- if headers[0].Number.Uint64() != number || headers[0].Hash() != hash {
- peer.Log().Info("Required block mismatch, dropping peer", "number", number, "hash", headers[0].Hash(), "want", hash)
- res.Done <- errors.New("required block mismatch")
- return
- }
- peer.Log().Debug("Peer required block verified", "number", number, "hash", hash)
- res.Done <- nil
- case <-timeout.C:
- peer.Log().Warn("Required block challenge timed out, dropping", "addr", peer.RemoteAddr(), "type", peer.Name())
- h.removePeer(peer.ID())
- }
- }(number, hash, req)
- }
- // Handle incoming messages until the connection is torn down
- return handler(peer)
-}
-
-// runSnapExtension registers a `snap` peer into the joint eth/snap peerset and
-// starts handling inbound messages. As `snap` is only a satellite protocol to
-// `eth`, all subsystem registrations and lifecycle management will be done by
-// the main `eth` handler to prevent strange races.
-func (h *handler) runSnapExtension(peer *snap.Peer, handler snap.Handler) error {
- if !h.incHandlers() {
- return p2p.DiscQuitting
- }
- defer h.decHandlers()
-
- if err := h.peers.registerSnapExtension(peer); err != nil {
- if metrics.Enabled {
- if peer.Inbound() {
- snap.IngressRegistrationErrorMeter.Mark(1)
- } else {
- snap.EgressRegistrationErrorMeter.Mark(1)
- }
- }
- peer.Log().Debug("Snapshot extension registration failed", "err", err)
- return err
- }
- return handler(peer)
-}
-
-// removePeer requests disconnection of a peer.
-func (h *handler) removePeer(id string) {
- peer := h.peers.peer(id)
- if peer != nil {
- peer.Peer.Disconnect(p2p.DiscUselessPeer)
- }
-}
-
-// unregisterPeer removes a peer from the downloader, fetchers and main peer set.
-func (h *handler) unregisterPeer(id string) {
- // Create a custom logger to avoid printing the entire id
- var logger log.Logger
- if len(id) < 16 {
- // Tests use short IDs, don't choke on them
- logger = log.New("peer", id)
- } else {
- logger = log.New("peer", id[:8])
- }
- // Abort if the peer does not exist
- peer := h.peers.peer(id)
- if peer == nil {
- logger.Error("Ethereum peer removal failed", "err", errPeerNotRegistered)
- return
- }
- // Remove the `eth` peer if it exists
- logger.Debug("Removing Ethereum peer", "snap", peer.snapExt != nil)
-
- // Remove the `snap` extension if it exists
- if peer.snapExt != nil {
- h.downloader.SnapSyncer.Unregister(id)
- }
- h.downloader.UnregisterPeer(id)
- h.txFetcher.Drop(id)
-
- if err := h.peers.unregisterPeer(id); err != nil {
- logger.Error("Ethereum peer removal failed", "err", err)
- }
-}
-
-func (h *handler) Start(maxPeers int) {
- h.maxPeers = maxPeers
-
- // broadcast and announce transactions (only new ones, not resurrected ones)
- h.wg.Add(1)
- h.txsCh = make(chan core.NewTxsEvent, txChanSize)
- h.txsSub = h.txpool.SubscribeTransactions(h.txsCh, false)
- go h.txBroadcastLoop()
-
- // broadcast mined blocks
- h.wg.Add(1)
- h.minedBlockSub = h.eventMux.Subscribe(core.NewMinedBlockEvent{})
- go h.minedBroadcastLoop()
-
- // start sync handlers
- h.wg.Add(1)
- go h.chainSync.loop()
-
- // start peer handler tracker
- h.wg.Add(1)
- go h.protoTracker()
-}
-
-func (h *handler) Stop() {
- h.txsSub.Unsubscribe() // quits txBroadcastLoop
- h.minedBlockSub.Unsubscribe() // quits blockBroadcastLoop
-
- // Quit chainSync and txsync64.
- // After this is done, no new peers will be accepted.
- close(h.quitSync)
-
- // Disconnect existing sessions.
- // This also closes the gate for any new registrations on the peer set.
- // sessions which are already established but not added to h.peers yet
- // will exit when they try to register.
- h.peers.close()
- h.wg.Wait()
-
- log.Info("Ethereum protocol stopped")
-}
-
-// BroadcastBlock will either propagate a block to a subset of its peers, or
-// will only announce its availability (depending what's requested).
-func (h *handler) BroadcastBlock(block *types.Block, propagate bool) {
- // Disable the block propagation if the chain has already entered the PoS
- // stage. The block propagation is delegated to the consensus layer.
- if h.merger.PoSFinalized() {
- return
- }
- // Disable the block propagation if it's the post-merge block.
- if beacon, ok := h.chain.Engine().(*beacon.Beacon); ok {
- if beacon.IsPoSHeader(block.Header()) {
- return
- }
- }
- hash := block.Hash()
- peers := h.peers.peersWithoutBlock(hash)
-
- // If propagation is requested, send to a subset of the peer
- if propagate {
- // Calculate the TD of the block (it's not imported yet, so block.Td is not valid)
- var td *big.Int
- if parent := h.chain.GetBlock(block.ParentHash(), block.NumberU64()-1); parent != nil {
- td = new(big.Int).Add(block.Difficulty(), h.chain.GetTd(block.ParentHash(), block.NumberU64()-1))
- } else {
- log.Error("Propagating dangling block", "number", block.Number(), "hash", hash)
- return
- }
- // Send the block to a subset of our peers
- transfer := peers[:int(math.Sqrt(float64(len(peers))))]
- for _, peer := range transfer {
- peer.AsyncSendNewBlock(block, td)
- }
- log.Trace("Propagated block", "hash", hash, "recipients", len(transfer), "duration", common.PrettyDuration(time.Since(block.ReceivedAt)))
- return
- }
- // Otherwise if the block is indeed in out own chain, announce it
- if h.chain.HasBlock(hash, block.NumberU64()) {
- for _, peer := range peers {
- peer.AsyncSendNewBlockHash(block)
- }
- log.Trace("Announced block", "hash", hash, "recipients", len(peers), "duration", common.PrettyDuration(time.Since(block.ReceivedAt)))
- }
-}
-
-// BroadcastTransactions will propagate a batch of transactions
-// - To a square root of all peers for non-blob transactions
-// - And, separately, as announcements to all peers which are not known to
-// already have the given transaction.
-func (h *handler) BroadcastTransactions(txs types.Transactions) {
- var (
- blobTxs int // Number of blob transactions to announce only
- largeTxs int // Number of large transactions to announce only
-
- directCount int // Number of transactions sent directly to peers (duplicates included)
- directPeers int // Number of peers that were sent transactions directly
- annCount int // Number of transactions announced across all peers (duplicates included)
- annPeers int // Number of peers announced about transactions
-
- txset = make(map[*ethPeer][]common.Hash) // Set peer->hash to transfer directly
- annos = make(map[*ethPeer][]common.Hash) // Set peer->hash to announce
- )
- // Broadcast transactions to a batch of peers not knowing about it
- for _, tx := range txs {
- peers := h.peers.peersWithoutTransaction(tx.Hash())
-
- var numDirect int
- switch {
- case tx.Type() == types.BlobTxType:
- blobTxs++
- case tx.Size() > txMaxBroadcastSize:
- largeTxs++
- default:
- numDirect = int(math.Sqrt(float64(len(peers))))
- }
- // Send the tx unconditionally to a subset of our peers
- for _, peer := range peers[:numDirect] {
- txset[peer] = append(txset[peer], tx.Hash())
- }
- // For the remaining peers, send announcement only
- for _, peer := range peers[numDirect:] {
- annos[peer] = append(annos[peer], tx.Hash())
- }
- }
- for peer, hashes := range txset {
- directPeers++
- directCount += len(hashes)
- peer.AsyncSendTransactions(hashes)
- }
- for peer, hashes := range annos {
- annPeers++
- annCount += len(hashes)
- peer.AsyncSendPooledTransactionHashes(hashes)
- }
- log.Debug("Distributed transactions", "plaintxs", len(txs)-blobTxs-largeTxs, "blobtxs", blobTxs, "largetxs", largeTxs,
- "bcastpeers", directPeers, "bcastcount", directCount, "annpeers", annPeers, "anncount", annCount)
-}
-
-// minedBroadcastLoop sends mined blocks to connected peers.
-func (h *handler) minedBroadcastLoop() {
- defer h.wg.Done()
-
- for obj := range h.minedBlockSub.Chan() {
- if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok {
- h.BroadcastBlock(ev.Block, true) // First propagate block to peers
- h.BroadcastBlock(ev.Block, false) // Only then announce to the rest
- }
- }
-}
-
-// txBroadcastLoop announces new transactions to connected peers.
-func (h *handler) txBroadcastLoop() {
- defer h.wg.Done()
- for {
- select {
- case event := <-h.txsCh:
- h.BroadcastTransactions(event.Txs)
- case <-h.txsSub.Err():
- return
- }
- }
-}
-
-// enableSyncedFeatures enables the post-sync functionalities when the initial
-// sync is finished.
-func (h *handler) enableSyncedFeatures() {
- // Mark the local node as synced.
- h.synced.Store(true)
-
- // If we were running snap sync and it finished, disable doing another
- // round on next sync cycle
- if h.snapSync.Load() {
- log.Info("Snap sync complete, auto disabling")
- h.snapSync.Store(false)
- }
- if h.chain.TrieDB().Scheme() == rawdb.PathScheme {
- h.chain.TrieDB().SetBufferSize(pathdb.DefaultBufferSize)
- }
-}
diff --git a/eth/handler_eth.go b/eth/handler_eth.go
deleted file mode 100644
index 2a839f615f..0000000000
--- a/eth/handler_eth.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "errors"
- "fmt"
- "math/big"
- "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/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/p2p/enode"
-)
-
-// ethHandler implements the eth.Backend interface to handle the various network
-// packets that are sent as replies or broadcasts.
-type ethHandler handler
-
-func (h *ethHandler) Chain() *core.BlockChain { return h.chain }
-func (h *ethHandler) TxPool() eth.TxPool { return h.txpool }
-
-// RunPeer is invoked when a peer joins on the `eth` protocol.
-func (h *ethHandler) RunPeer(peer *eth.Peer, hand eth.Handler) error {
- return (*handler)(h).runEthPeer(peer, hand)
-}
-
-// PeerInfo retrieves all known `eth` information about a peer.
-func (h *ethHandler) PeerInfo(id enode.ID) interface{} {
- if p := h.peers.peer(id.String()); p != nil {
- return p.info()
- }
- return nil
-}
-
-// AcceptTxs retrieves whether transaction processing is enabled on the node
-// or if inbound transactions should simply be dropped.
-func (h *ethHandler) AcceptTxs() bool {
- return h.synced.Load()
-}
-
-// Handle is invoked from a peer's message handler when it receives a new remote
-// message that the handler couldn't consume and serve itself.
-func (h *ethHandler) Handle(peer *eth.Peer, packet eth.Packet) error {
- // Consume any broadcasts and announces, forwarding the rest to the downloader
- switch packet := packet.(type) {
- case *eth.NewBlockHashesPacket:
- hashes, numbers := packet.Unpack()
- return h.handleBlockAnnounces(peer, hashes, numbers)
-
- case *eth.NewBlockPacket:
- return h.handleBlockBroadcast(peer, packet.Block, packet.TD)
-
- case *eth.NewPooledTransactionHashesPacket67:
- return h.txFetcher.Notify(peer.ID(), nil, nil, *packet)
-
- case *eth.NewPooledTransactionHashesPacket68:
- return h.txFetcher.Notify(peer.ID(), packet.Types, packet.Sizes, packet.Hashes)
-
- case *eth.TransactionsPacket:
- for _, tx := range *packet {
- if tx.Type() == types.BlobTxType {
- return errors.New("disallowed broadcast blob transaction")
- }
- }
- return h.txFetcher.Enqueue(peer.ID(), *packet, false)
-
- case *eth.PooledTransactionsResponse:
- return h.txFetcher.Enqueue(peer.ID(), *packet, true)
-
- default:
- return fmt.Errorf("unexpected eth packet type: %T", packet)
- }
-}
-
-// handleBlockAnnounces is invoked from a peer's message handler when it transmits a
-// batch of block announcements for the local node to process.
-func (h *ethHandler) handleBlockAnnounces(peer *eth.Peer, hashes []common.Hash, numbers []uint64) error {
- // Drop all incoming block announces from the p2p network if
- // the chain already entered the pos stage and disconnect the
- // remote peer.
- if h.merger.PoSFinalized() {
- return errors.New("disallowed block announcement")
- }
- // Schedule all the unknown hashes for retrieval
- var (
- unknownHashes = make([]common.Hash, 0, len(hashes))
- unknownNumbers = make([]uint64, 0, len(numbers))
- )
- for i := 0; i < len(hashes); i++ {
- if !h.chain.HasBlock(hashes[i], numbers[i]) {
- unknownHashes = append(unknownHashes, hashes[i])
- unknownNumbers = append(unknownNumbers, numbers[i])
- }
- }
- for i := 0; i < len(unknownHashes); i++ {
- h.blockFetcher.Notify(peer.ID(), unknownHashes[i], unknownNumbers[i], time.Now(), peer.RequestOneHeader, peer.RequestBodies)
- }
- return nil
-}
-
-// handleBlockBroadcast is invoked from a peer's message handler when it transmits a
-// block broadcast for the local node to process.
-func (h *ethHandler) handleBlockBroadcast(peer *eth.Peer, block *types.Block, td *big.Int) error {
- // Drop all incoming block announces from the p2p network if
- // the chain already entered the pos stage and disconnect the
- // remote peer.
- if h.merger.PoSFinalized() {
- return errors.New("disallowed block broadcast")
- }
- // Schedule the block for import
- h.blockFetcher.Enqueue(peer.ID(), block)
-
- // Assuming the block is importable by the peer, but possibly not yet done so,
- // calculate the head hash and TD that the peer truly must have.
- var (
- trueHead = block.ParentHash()
- trueTD = new(big.Int).Sub(td, block.Difficulty())
- )
- // Update the peer's total difficulty if better than the previous
- if _, td := peer.Head(); trueTD.Cmp(td) > 0 {
- peer.SetHead(trueHead, trueTD)
- h.chainSync.handlePeerEvent()
- }
- return nil
-}
diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go
deleted file mode 100644
index bb342acc18..0000000000
--- a/eth/handler_eth_test.go
+++ /dev/null
@@ -1,608 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "fmt"
- "math/big"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/forkid"
- "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/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
- "github.com/ethereum/go-ethereum/params"
-)
-
-// testEthHandler is a mock event handler to listen for inbound network requests
-// on the `eth` protocol and convert them into a more easily testable form.
-type testEthHandler struct {
- blockBroadcasts event.Feed
- txAnnounces event.Feed
- txBroadcasts event.Feed
-}
-
-func (h *testEthHandler) Chain() *core.BlockChain { panic("no backing chain") }
-func (h *testEthHandler) TxPool() eth.TxPool { panic("no backing tx pool") }
-func (h *testEthHandler) AcceptTxs() bool { return true }
-func (h *testEthHandler) RunPeer(*eth.Peer, eth.Handler) error { panic("not used in tests") }
-func (h *testEthHandler) PeerInfo(enode.ID) interface{} { panic("not used in tests") }
-
-func (h *testEthHandler) Handle(peer *eth.Peer, packet eth.Packet) error {
- switch packet := packet.(type) {
- case *eth.NewBlockPacket:
- h.blockBroadcasts.Send(packet.Block)
- return nil
-
- case *eth.NewPooledTransactionHashesPacket67:
- h.txAnnounces.Send(([]common.Hash)(*packet))
- return nil
-
- case *eth.NewPooledTransactionHashesPacket68:
- h.txAnnounces.Send(packet.Hashes)
- return nil
-
- case *eth.TransactionsPacket:
- h.txBroadcasts.Send(([]*types.Transaction)(*packet))
- return nil
-
- case *eth.PooledTransactionsResponse:
- h.txBroadcasts.Send(([]*types.Transaction)(*packet))
- return nil
-
- default:
- panic(fmt.Sprintf("unexpected eth packet type in tests: %T", packet))
- }
-}
-
-// Tests that peers are correctly accepted (or rejected) based on the advertised
-// fork IDs in the protocol handshake.
-func TestForkIDSplit67(t *testing.T) { testForkIDSplit(t, eth.ETH67) }
-func TestForkIDSplit68(t *testing.T) { testForkIDSplit(t, eth.ETH68) }
-
-func testForkIDSplit(t *testing.T, protocol uint) {
- t.Parallel()
-
- var (
- engine = ethash.NewFaker()
-
- configNoFork = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(1)}
- configProFork = ¶ms.ChainConfig{
- HomesteadBlock: big.NewInt(1),
- EIP150Block: big.NewInt(2),
- EIP155Block: big.NewInt(2),
- EIP158Block: big.NewInt(2),
- ByzantiumBlock: big.NewInt(3),
- }
- dbNoFork = rawdb.NewMemoryDatabase()
- dbProFork = rawdb.NewMemoryDatabase()
-
- gspecNoFork = &core.Genesis{Config: configNoFork}
- gspecProFork = &core.Genesis{Config: configProFork}
-
- chainNoFork, _ = core.NewBlockChain(dbNoFork, nil, gspecNoFork, nil, engine, vm.Config{}, nil, nil)
- chainProFork, _ = core.NewBlockChain(dbProFork, nil, gspecProFork, nil, engine, vm.Config{}, nil, nil)
-
- _, blocksNoFork, _ = core.GenerateChainWithGenesis(gspecNoFork, engine, 2, nil)
- _, blocksProFork, _ = core.GenerateChainWithGenesis(gspecProFork, engine, 2, nil)
-
- ethNoFork, _ = newHandler(&handlerConfig{
- Database: dbNoFork,
- Chain: chainNoFork,
- TxPool: newTestTxPool(),
- Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()),
- Network: 1,
- Sync: downloader.FullSync,
- BloomCache: 1,
- })
- ethProFork, _ = newHandler(&handlerConfig{
- Database: dbProFork,
- Chain: chainProFork,
- TxPool: newTestTxPool(),
- Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()),
- Network: 1,
- Sync: downloader.FullSync,
- BloomCache: 1,
- })
- )
- ethNoFork.Start(1000)
- ethProFork.Start(1000)
-
- // Clean up everything after ourselves
- defer chainNoFork.Stop()
- defer chainProFork.Stop()
-
- defer ethNoFork.Stop()
- defer ethProFork.Stop()
-
- // Both nodes should allow the other to connect (same genesis, next fork is the same)
- p2pNoFork, p2pProFork := p2p.MsgPipe()
- defer p2pNoFork.Close()
- defer p2pProFork.Close()
-
- peerNoFork := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pNoFork), p2pNoFork, nil)
- peerProFork := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pProFork), p2pProFork, nil)
- defer peerNoFork.Close()
- defer peerProFork.Close()
-
- errc := make(chan error, 2)
- go func(errc chan error) {
- errc <- ethNoFork.runEthPeer(peerProFork, func(peer *eth.Peer) error { return nil })
- }(errc)
- go func(errc chan error) {
- errc <- ethProFork.runEthPeer(peerNoFork, func(peer *eth.Peer) error { return nil })
- }(errc)
-
- for i := 0; i < 2; i++ {
- select {
- case err := <-errc:
- if err != nil {
- t.Fatalf("frontier nofork <-> profork failed: %v", err)
- }
- case <-time.After(250 * time.Millisecond):
- t.Fatalf("frontier nofork <-> profork handler timeout")
- }
- }
- // Progress into Homestead. Fork's match, so we don't care what the future holds
- chainNoFork.InsertChain(blocksNoFork[:1])
- chainProFork.InsertChain(blocksProFork[:1])
-
- p2pNoFork, p2pProFork = p2p.MsgPipe()
- defer p2pNoFork.Close()
- defer p2pProFork.Close()
-
- peerNoFork = eth.NewPeer(protocol, p2p.NewPeer(enode.ID{1}, "", nil), p2pNoFork, nil)
- peerProFork = eth.NewPeer(protocol, p2p.NewPeer(enode.ID{2}, "", nil), p2pProFork, nil)
- defer peerNoFork.Close()
- defer peerProFork.Close()
-
- errc = make(chan error, 2)
- go func(errc chan error) {
- errc <- ethNoFork.runEthPeer(peerProFork, func(peer *eth.Peer) error { return nil })
- }(errc)
- go func(errc chan error) {
- errc <- ethProFork.runEthPeer(peerNoFork, func(peer *eth.Peer) error { return nil })
- }(errc)
-
- for i := 0; i < 2; i++ {
- select {
- case err := <-errc:
- if err != nil {
- t.Fatalf("homestead nofork <-> profork failed: %v", err)
- }
- case <-time.After(250 * time.Millisecond):
- t.Fatalf("homestead nofork <-> profork handler timeout")
- }
- }
- // Progress into Spurious. Forks mismatch, signalling differing chains, reject
- chainNoFork.InsertChain(blocksNoFork[1:2])
- chainProFork.InsertChain(blocksProFork[1:2])
-
- p2pNoFork, p2pProFork = p2p.MsgPipe()
- defer p2pNoFork.Close()
- defer p2pProFork.Close()
-
- peerNoFork = eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pNoFork), p2pNoFork, nil)
- peerProFork = eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pProFork), p2pProFork, nil)
- defer peerNoFork.Close()
- defer peerProFork.Close()
-
- errc = make(chan error, 2)
- go func(errc chan error) {
- errc <- ethNoFork.runEthPeer(peerProFork, func(peer *eth.Peer) error { return nil })
- }(errc)
- go func(errc chan error) {
- errc <- ethProFork.runEthPeer(peerNoFork, func(peer *eth.Peer) error { return nil })
- }(errc)
-
- var successes int
- for i := 0; i < 2; i++ {
- select {
- case err := <-errc:
- if err == nil {
- successes++
- if successes == 2 { // Only one side disconnects
- t.Fatalf("fork ID rejection didn't happen")
- }
- }
- case <-time.After(250 * time.Millisecond):
- t.Fatalf("split peers not rejected")
- }
- }
-}
-
-// Tests that received transactions are added to the local pool.
-func TestRecvTransactions67(t *testing.T) { testRecvTransactions(t, eth.ETH67) }
-func TestRecvTransactions68(t *testing.T) { testRecvTransactions(t, eth.ETH68) }
-
-func testRecvTransactions(t *testing.T, protocol uint) {
- t.Parallel()
-
- // Create a message handler, configure it to accept transactions and watch them
- handler := newTestHandler()
- defer handler.close()
-
- handler.handler.synced.Store(true) // mark synced to accept transactions
-
- txs := make(chan core.NewTxsEvent)
- sub := handler.txpool.SubscribeTransactions(txs, false)
- defer sub.Unsubscribe()
-
- // Create a source peer to send messages through and a sink handler to receive them
- p2pSrc, p2pSink := p2p.MsgPipe()
- defer p2pSrc.Close()
- defer p2pSink.Close()
-
- src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, handler.txpool)
- sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, handler.txpool)
- defer src.Close()
- defer sink.Close()
-
- go handler.handler.runEthPeer(sink, func(peer *eth.Peer) error {
- return eth.Handle((*ethHandler)(handler.handler), peer)
- })
- // Run the handshake locally to avoid spinning up a source handler
- var (
- genesis = handler.chain.Genesis()
- head = handler.chain.CurrentBlock()
- td = handler.chain.GetTd(head.Hash(), head.Number.Uint64())
- )
- if err := src.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil {
- t.Fatalf("failed to run protocol handshake")
- }
- // Send the transaction to the sink and verify that it's added to the tx pool
- tx := types.NewTransaction(0, common.Address{}, big.NewInt(0), 100000, big.NewInt(0), nil)
- tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
-
- if err := src.SendTransactions([]*types.Transaction{tx}); err != nil {
- t.Fatalf("failed to send transaction: %v", err)
- }
- select {
- case event := <-txs:
- if len(event.Txs) != 1 {
- t.Errorf("wrong number of added transactions: got %d, want 1", len(event.Txs))
- } else if event.Txs[0].Hash() != tx.Hash() {
- t.Errorf("added wrong tx hash: got %v, want %v", event.Txs[0].Hash(), tx.Hash())
- }
- case <-time.After(2 * time.Second):
- t.Errorf("no NewTxsEvent received within 2 seconds")
- }
-}
-
-// This test checks that pending transactions are sent.
-func TestSendTransactions67(t *testing.T) { testSendTransactions(t, eth.ETH67) }
-func TestSendTransactions68(t *testing.T) { testSendTransactions(t, eth.ETH68) }
-
-func testSendTransactions(t *testing.T, protocol uint) {
- t.Parallel()
-
- // Create a message handler and fill the pool with big transactions
- handler := newTestHandler()
- defer handler.close()
-
- insert := make([]*types.Transaction, 100)
- for nonce := range insert {
- tx := types.NewTransaction(uint64(nonce), common.Address{}, big.NewInt(0), 100000, big.NewInt(0), make([]byte, 10240))
- tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
- insert[nonce] = tx
- }
- go handler.txpool.Add(insert, false, false) // Need goroutine to not block on feed
- time.Sleep(250 * time.Millisecond) // Wait until tx events get out of the system (can't use events, tx broadcaster races with peer join)
-
- // Create a source handler to send messages through and a sink peer to receive them
- p2pSrc, p2pSink := p2p.MsgPipe()
- defer p2pSrc.Close()
- defer p2pSink.Close()
-
- src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, handler.txpool)
- sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, handler.txpool)
- defer src.Close()
- defer sink.Close()
-
- go handler.handler.runEthPeer(src, func(peer *eth.Peer) error {
- return eth.Handle((*ethHandler)(handler.handler), peer)
- })
- // Run the handshake locally to avoid spinning up a source handler
- var (
- genesis = handler.chain.Genesis()
- head = handler.chain.CurrentBlock()
- td = handler.chain.GetTd(head.Hash(), head.Number.Uint64())
- )
- if err := sink.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain)); err != nil {
- t.Fatalf("failed to run protocol handshake")
- }
- // After the handshake completes, the source handler should stream the sink
- // the transactions, subscribe to all inbound network events
- backend := new(testEthHandler)
-
- anns := make(chan []common.Hash)
- annSub := backend.txAnnounces.Subscribe(anns)
- defer annSub.Unsubscribe()
-
- bcasts := make(chan []*types.Transaction)
- bcastSub := backend.txBroadcasts.Subscribe(bcasts)
- defer bcastSub.Unsubscribe()
-
- go eth.Handle(backend, sink)
-
- // Make sure we get all the transactions on the correct channels
- seen := make(map[common.Hash]struct{})
- for len(seen) < len(insert) {
- switch protocol {
- case 67, 68:
- select {
- case hashes := <-anns:
- for _, hash := range hashes {
- if _, ok := seen[hash]; ok {
- t.Errorf("duplicate transaction announced: %x", hash)
- }
- seen[hash] = struct{}{}
- }
- case <-bcasts:
- t.Errorf("initial tx broadcast received on post eth/66")
- }
-
- default:
- panic("unsupported protocol, please extend test")
- }
- }
- for _, tx := range insert {
- if _, ok := seen[tx.Hash()]; !ok {
- t.Errorf("missing transaction: %x", tx.Hash())
- }
- }
-}
-
-// Tests that transactions get propagated to all attached peers, either via direct
-// broadcasts or via announcements/retrievals.
-func TestTransactionPropagation67(t *testing.T) { testTransactionPropagation(t, eth.ETH67) }
-func TestTransactionPropagation68(t *testing.T) { testTransactionPropagation(t, eth.ETH68) }
-
-func testTransactionPropagation(t *testing.T, protocol uint) {
- t.Parallel()
-
- // Create a source handler to send transactions from and a number of sinks
- // to receive them. We need multiple sinks since a one-to-one peering would
- // broadcast all transactions without announcement.
- source := newTestHandler()
- source.handler.snapSync.Store(false) // Avoid requiring snap, otherwise some will be dropped below
- defer source.close()
-
- sinks := make([]*testHandler, 10)
- for i := 0; i < len(sinks); i++ {
- sinks[i] = newTestHandler()
- defer sinks[i].close()
-
- sinks[i].handler.synced.Store(true) // mark synced to accept transactions
- }
- // Interconnect all the sink handlers with the source handler
- for i, sink := range sinks {
- sink := sink // Closure for gorotuine below
-
- sourcePipe, sinkPipe := p2p.MsgPipe()
- defer sourcePipe.Close()
- defer sinkPipe.Close()
-
- sourcePeer := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{byte(i + 1)}, "", nil, sourcePipe), sourcePipe, source.txpool)
- sinkPeer := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{0}, "", nil, sinkPipe), sinkPipe, sink.txpool)
- defer sourcePeer.Close()
- defer sinkPeer.Close()
-
- go source.handler.runEthPeer(sourcePeer, func(peer *eth.Peer) error {
- return eth.Handle((*ethHandler)(source.handler), peer)
- })
- go sink.handler.runEthPeer(sinkPeer, func(peer *eth.Peer) error {
- return eth.Handle((*ethHandler)(sink.handler), peer)
- })
- }
- // Subscribe to all the transaction pools
- txChs := make([]chan core.NewTxsEvent, len(sinks))
- for i := 0; i < len(sinks); i++ {
- txChs[i] = make(chan core.NewTxsEvent, 1024)
-
- sub := sinks[i].txpool.SubscribeTransactions(txChs[i], false)
- defer sub.Unsubscribe()
- }
- // Fill the source pool with transactions and wait for them at the sinks
- txs := make([]*types.Transaction, 1024)
- for nonce := range txs {
- tx := types.NewTransaction(uint64(nonce), common.Address{}, big.NewInt(0), 100000, big.NewInt(0), nil)
- tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey)
- txs[nonce] = tx
- }
- source.txpool.Add(txs, false, false)
-
- // Iterate through all the sinks and ensure they all got the transactions
- for i := range sinks {
- for arrived, timeout := 0, false; arrived < len(txs) && !timeout; {
- select {
- case event := <-txChs[i]:
- arrived += len(event.Txs)
- case <-time.After(2 * time.Second):
- t.Errorf("sink %d: transaction propagation timed out: have %d, want %d", i, arrived, len(txs))
- timeout = true
- }
- }
- }
-}
-
-// Tests that blocks are broadcast to a sqrt number of peers only.
-func TestBroadcastBlock1Peer(t *testing.T) { testBroadcastBlock(t, 1, 1) }
-func TestBroadcastBlock2Peers(t *testing.T) { testBroadcastBlock(t, 2, 1) }
-func TestBroadcastBlock3Peers(t *testing.T) { testBroadcastBlock(t, 3, 1) }
-func TestBroadcastBlock4Peers(t *testing.T) { testBroadcastBlock(t, 4, 2) }
-func TestBroadcastBlock5Peers(t *testing.T) { testBroadcastBlock(t, 5, 2) }
-func TestBroadcastBlock8Peers(t *testing.T) { testBroadcastBlock(t, 9, 3) }
-func TestBroadcastBlock12Peers(t *testing.T) { testBroadcastBlock(t, 12, 3) }
-func TestBroadcastBlock16Peers(t *testing.T) { testBroadcastBlock(t, 16, 4) }
-func TestBroadcastBloc26Peers(t *testing.T) { testBroadcastBlock(t, 26, 5) }
-func TestBroadcastBlock100Peers(t *testing.T) { testBroadcastBlock(t, 100, 10) }
-
-func testBroadcastBlock(t *testing.T, peers, bcasts int) {
- t.Parallel()
-
- // Create a source handler to broadcast blocks from and a number of sinks
- // to receive them.
- source := newTestHandlerWithBlocks(1)
- defer source.close()
-
- sinks := make([]*testEthHandler, peers)
- for i := 0; i < len(sinks); i++ {
- sinks[i] = new(testEthHandler)
- }
- // Interconnect all the sink handlers with the source handler
- var (
- genesis = source.chain.Genesis()
- td = source.chain.GetTd(genesis.Hash(), genesis.NumberU64())
- )
- for i, sink := range sinks {
- sink := sink // Closure for gorotuine below
-
- sourcePipe, sinkPipe := p2p.MsgPipe()
- defer sourcePipe.Close()
- defer sinkPipe.Close()
-
- sourcePeer := eth.NewPeer(eth.ETH67, p2p.NewPeerPipe(enode.ID{byte(i)}, "", nil, sourcePipe), sourcePipe, nil)
- sinkPeer := eth.NewPeer(eth.ETH67, p2p.NewPeerPipe(enode.ID{0}, "", nil, sinkPipe), sinkPipe, nil)
- defer sourcePeer.Close()
- defer sinkPeer.Close()
-
- go source.handler.runEthPeer(sourcePeer, func(peer *eth.Peer) error {
- return eth.Handle((*ethHandler)(source.handler), peer)
- })
- if err := sinkPeer.Handshake(1, td, genesis.Hash(), genesis.Hash(), forkid.NewIDWithChain(source.chain), forkid.NewFilter(source.chain)); err != nil {
- t.Fatalf("failed to run protocol handshake")
- }
- go eth.Handle(sink, sinkPeer)
- }
- // Subscribe to all the transaction pools
- blockChs := make([]chan *types.Block, len(sinks))
- for i := 0; i < len(sinks); i++ {
- blockChs[i] = make(chan *types.Block, 1)
- defer close(blockChs[i])
-
- sub := sinks[i].blockBroadcasts.Subscribe(blockChs[i])
- defer sub.Unsubscribe()
- }
- // Initiate a block propagation across the peers
- time.Sleep(100 * time.Millisecond)
- header := source.chain.CurrentBlock()
- source.handler.BroadcastBlock(source.chain.GetBlock(header.Hash(), header.Number.Uint64()), true)
-
- // Iterate through all the sinks and ensure the correct number got the block
- done := make(chan struct{}, peers)
- for _, ch := range blockChs {
- ch := ch
- go func() {
- <-ch
- done <- struct{}{}
- }()
- }
- var received int
- for {
- select {
- case <-done:
- received++
-
- case <-time.After(100 * time.Millisecond):
- if received != bcasts {
- t.Errorf("broadcast count mismatch: have %d, want %d", received, bcasts)
- }
- return
- }
- }
-}
-
-// Tests that a propagated malformed block (uncles or transactions don't match
-// with the hashes in the header) gets discarded and not broadcast forward.
-func TestBroadcastMalformedBlock67(t *testing.T) { testBroadcastMalformedBlock(t, eth.ETH67) }
-func TestBroadcastMalformedBlock68(t *testing.T) { testBroadcastMalformedBlock(t, eth.ETH68) }
-
-func testBroadcastMalformedBlock(t *testing.T, protocol uint) {
- t.Parallel()
-
- // Create a source handler to broadcast blocks from and a number of sinks
- // to receive them.
- source := newTestHandlerWithBlocks(1)
- defer source.close()
-
- // Create a source handler to send messages through and a sink peer to receive them
- p2pSrc, p2pSink := p2p.MsgPipe()
- defer p2pSrc.Close()
- defer p2pSink.Close()
-
- src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, source.txpool)
- sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, source.txpool)
- defer src.Close()
- defer sink.Close()
-
- go source.handler.runEthPeer(src, func(peer *eth.Peer) error {
- return eth.Handle((*ethHandler)(source.handler), peer)
- })
- // Run the handshake locally to avoid spinning up a sink handler
- var (
- genesis = source.chain.Genesis()
- td = source.chain.GetTd(genesis.Hash(), genesis.NumberU64())
- )
- if err := sink.Handshake(1, td, genesis.Hash(), genesis.Hash(), forkid.NewIDWithChain(source.chain), forkid.NewFilter(source.chain)); err != nil {
- t.Fatalf("failed to run protocol handshake")
- }
- // After the handshake completes, the source handler should stream the sink
- // the blocks, subscribe to inbound network events
- backend := new(testEthHandler)
-
- blocks := make(chan *types.Block, 1)
- sub := backend.blockBroadcasts.Subscribe(blocks)
- defer sub.Unsubscribe()
-
- go eth.Handle(backend, sink)
-
- // Create various combinations of malformed blocks
- head := source.chain.CurrentBlock()
- block := source.chain.GetBlock(head.Hash(), head.Number.Uint64())
-
- malformedUncles := head
- malformedUncles.UncleHash[0]++
- malformedTransactions := head
- malformedTransactions.TxHash[0]++
- malformedEverything := head
- malformedEverything.UncleHash[0]++
- malformedEverything.TxHash[0]++
-
- // Try to broadcast all malformations and ensure they all get discarded
- for _, header := range []*types.Header{malformedUncles, malformedTransactions, malformedEverything} {
- block := types.NewBlockWithHeader(header).WithBody(block.Transactions(), block.Uncles())
- if err := src.SendNewBlock(block, big.NewInt(131136)); err != nil {
- t.Fatalf("failed to broadcast block: %v", err)
- }
- select {
- case <-blocks:
- t.Fatalf("malformed block forwarded")
- case <-time.After(100 * time.Millisecond):
- }
- }
-}
diff --git a/eth/handler_snap.go b/eth/handler_snap.go
deleted file mode 100644
index 767416ffd6..0000000000
--- a/eth/handler_snap.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/eth/protocols/snap"
- "github.com/ethereum/go-ethereum/p2p/enode"
-)
-
-// snapHandler implements the snap.Backend interface to handle the various network
-// packets that are sent as replies or broadcasts.
-type snapHandler handler
-
-func (h *snapHandler) Chain() *core.BlockChain { return h.chain }
-
-// RunPeer is invoked when a peer joins on the `snap` protocol.
-func (h *snapHandler) RunPeer(peer *snap.Peer, hand snap.Handler) error {
- return (*handler)(h).runSnapExtension(peer, hand)
-}
-
-// PeerInfo retrieves all known `snap` information about a peer.
-func (h *snapHandler) PeerInfo(id enode.ID) interface{} {
- if p := h.peers.peer(id.String()); p != nil {
- if p.snapExt != nil {
- return p.snapExt.info()
- }
- }
- return nil
-}
-
-// Handle is invoked from a peer's message handler when it receives a new remote
-// message that the handler couldn't consume and serve itself.
-func (h *snapHandler) Handle(peer *snap.Peer, packet snap.Packet) error {
- return h.downloader.DeliverSnapPacket(peer, packet)
-}
diff --git a/eth/handler_test.go b/eth/handler_test.go
deleted file mode 100644
index 6d6132ee4c..0000000000
--- a/eth/handler_test.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2015 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 eth
-
-import (
- "math/big"
- "sort"
- "sync"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "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/txpool"
- "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/eth/downloader"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
-)
-
-var (
- // testKey is a private key to use for funding a tester account.
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
-
- // testAddr is the Ethereum address of the tester account.
- testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
-)
-
-// testTxPool is a mock transaction pool that blindly accepts all transactions.
-// Its goal is to get around setting up a valid statedb for the balance and nonce
-// checks.
-type testTxPool struct {
- pool map[common.Hash]*types.Transaction // Hash map of collected transactions
-
- txFeed event.Feed // Notification feed to allow waiting for inclusion
- lock sync.RWMutex // Protects the transaction pool
-}
-
-// newTestTxPool creates a mock transaction pool.
-func newTestTxPool() *testTxPool {
- return &testTxPool{
- pool: make(map[common.Hash]*types.Transaction),
- }
-}
-
-// Has returns an indicator whether txpool has a transaction
-// cached with the given hash.
-func (p *testTxPool) Has(hash common.Hash) bool {
- p.lock.Lock()
- defer p.lock.Unlock()
-
- return p.pool[hash] != nil
-}
-
-// Get retrieves the transaction from local txpool with given
-// tx hash.
-func (p *testTxPool) Get(hash common.Hash) *types.Transaction {
- p.lock.Lock()
- defer p.lock.Unlock()
- return p.pool[hash]
-}
-
-// Add appends a batch of transactions to the pool, and notifies any
-// listeners if the addition channel is non nil
-func (p *testTxPool) Add(txs []*types.Transaction, local bool, sync bool) []error {
- p.lock.Lock()
- defer p.lock.Unlock()
-
- for _, tx := range txs {
- p.pool[tx.Hash()] = tx
- }
- p.txFeed.Send(core.NewTxsEvent{Txs: txs})
- return make([]error, len(txs))
-}
-
-// Pending returns all the transactions known to the pool
-func (p *testTxPool) Pending(enforceTips bool) map[common.Address][]*txpool.LazyTransaction {
- p.lock.RLock()
- defer p.lock.RUnlock()
-
- batches := make(map[common.Address][]*types.Transaction)
- for _, tx := range p.pool {
- from, _ := types.Sender(types.HomesteadSigner{}, tx)
- batches[from] = append(batches[from], tx)
- }
- for _, batch := range batches {
- sort.Sort(types.TxByNonce(batch))
- }
- pending := make(map[common.Address][]*txpool.LazyTransaction)
- for addr, batch := range batches {
- for _, tx := range batch {
- pending[addr] = append(pending[addr], &txpool.LazyTransaction{
- Hash: tx.Hash(),
- Tx: tx,
- Time: tx.Time(),
- GasFeeCap: tx.GasFeeCap(),
- GasTipCap: tx.GasTipCap(),
- Gas: tx.Gas(),
- BlobGas: tx.BlobGas(),
- })
- }
- }
- return pending
-}
-
-// SubscribeTransactions should return an event subscription of NewTxsEvent and
-// send events to the given channel.
-func (p *testTxPool) SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool) event.Subscription {
- return p.txFeed.Subscribe(ch)
-}
-
-// testHandler is a live implementation of the Ethereum protocol handler, just
-// preinitialized with some sane testing defaults and the transaction pool mocked
-// out.
-type testHandler struct {
- db ethdb.Database
- chain *core.BlockChain
- txpool *testTxPool
- handler *handler
-}
-
-// newTestHandler creates a new handler for testing purposes with no blocks.
-func newTestHandler() *testHandler {
- return newTestHandlerWithBlocks(0)
-}
-
-// newTestHandlerWithBlocks creates a new handler for testing purposes, with a
-// given number of initial blocks.
-func newTestHandlerWithBlocks(blocks int) *testHandler {
- // Create a database pre-initialize with a genesis block
- db := rawdb.NewMemoryDatabase()
- gspec := &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(1000000)}},
- }
- chain, _ := core.NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
-
- _, bs, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), blocks, nil)
- if _, err := chain.InsertChain(bs); err != nil {
- panic(err)
- }
- txpool := newTestTxPool()
-
- handler, _ := newHandler(&handlerConfig{
- Database: db,
- Chain: chain,
- TxPool: txpool,
- Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()),
- Network: 1,
- Sync: downloader.SnapSync,
- BloomCache: 1,
- })
- handler.Start(1000)
-
- return &testHandler{
- db: db,
- chain: chain,
- txpool: txpool,
- handler: handler,
- }
-}
-
-// close tears down the handler and all its internal constructs.
-func (b *testHandler) close() {
- b.handler.Stop()
- b.chain.Stop()
-}
diff --git a/eth/peer.go b/eth/peer.go
deleted file mode 100644
index 7618777716..0000000000
--- a/eth/peer.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2015 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 eth
-
-import (
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/eth/protocols/snap"
-)
-
-// ethPeerInfo represents a short summary of the `eth` sub-protocol metadata known
-// about a connected peer.
-type ethPeerInfo struct {
- Version uint `json:"version"` // Ethereum protocol version negotiated
-}
-
-// ethPeer is a wrapper around eth.Peer to maintain a few extra metadata.
-type ethPeer struct {
- *eth.Peer
- snapExt *snapPeer // Satellite `snap` connection
-}
-
-// info gathers and returns some `eth` protocol metadata known about a peer.
-func (p *ethPeer) info() *ethPeerInfo {
- return ðPeerInfo{
- Version: p.Version(),
- }
-}
-
-// snapPeerInfo represents a short summary of the `snap` sub-protocol metadata known
-// about a connected peer.
-type snapPeerInfo struct {
- Version uint `json:"version"` // Snapshot protocol version negotiated
-}
-
-// snapPeer is a wrapper around snap.Peer to maintain a few extra metadata.
-type snapPeer struct {
- *snap.Peer
-}
-
-// info gathers and returns some `snap` protocol metadata known about a peer.
-func (p *snapPeer) info() *snapPeerInfo {
- return &snapPeerInfo{
- Version: p.Version(),
- }
-}
diff --git a/eth/peerset.go b/eth/peerset.go
deleted file mode 100644
index b27d3964a1..0000000000
--- a/eth/peerset.go
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "errors"
- "fmt"
- "math/big"
- "sync"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/eth/protocols/snap"
- "github.com/ethereum/go-ethereum/p2p"
-)
-
-var (
- // errPeerSetClosed is returned if a peer is attempted to be added or removed
- // from the peer set after it has been terminated.
- errPeerSetClosed = errors.New("peerset closed")
-
- // errPeerAlreadyRegistered is returned if a peer is attempted to be added
- // to the peer set, but one with the same id already exists.
- errPeerAlreadyRegistered = errors.New("peer already registered")
-
- // errPeerNotRegistered is returned if a peer is attempted to be removed from
- // a peer set, but no peer with the given id exists.
- errPeerNotRegistered = errors.New("peer not registered")
-
- // errSnapWithoutEth is returned if a peer attempts to connect only on the
- // snap protocol without advertising the eth main protocol.
- errSnapWithoutEth = errors.New("peer connected on snap without compatible eth support")
-)
-
-// peerSet represents the collection of active peers currently participating in
-// the `eth` protocol, with or without the `snap` extension.
-type peerSet struct {
- peers map[string]*ethPeer // Peers connected on the `eth` protocol
- snapPeers int // Number of `snap` compatible peers for connection prioritization
-
- snapWait map[string]chan *snap.Peer // Peers connected on `eth` waiting for their snap extension
- snapPend map[string]*snap.Peer // Peers connected on the `snap` protocol, but not yet on `eth`
-
- lock sync.RWMutex
- closed bool
-}
-
-// newPeerSet creates a new peer set to track the active participants.
-func newPeerSet() *peerSet {
- return &peerSet{
- peers: make(map[string]*ethPeer),
- snapWait: make(map[string]chan *snap.Peer),
- snapPend: make(map[string]*snap.Peer),
- }
-}
-
-// registerSnapExtension unblocks an already connected `eth` peer waiting for its
-// `snap` extension, or if no such peer exists, tracks the extension for the time
-// being until the `eth` main protocol starts looking for it.
-func (ps *peerSet) registerSnapExtension(peer *snap.Peer) error {
- // Reject the peer if it advertises `snap` without `eth` as `snap` is only a
- // satellite protocol meaningful with the chain selection of `eth`
- if !peer.RunningCap(eth.ProtocolName, eth.ProtocolVersions) {
- return fmt.Errorf("%w: have %v", errSnapWithoutEth, peer.Caps())
- }
- // Ensure nobody can double connect
- ps.lock.Lock()
- defer ps.lock.Unlock()
-
- id := peer.ID()
- if _, ok := ps.peers[id]; ok {
- return errPeerAlreadyRegistered // avoid connections with the same id as existing ones
- }
- if _, ok := ps.snapPend[id]; ok {
- return errPeerAlreadyRegistered // avoid connections with the same id as pending ones
- }
- // Inject the peer into an `eth` counterpart is available, otherwise save for later
- if wait, ok := ps.snapWait[id]; ok {
- delete(ps.snapWait, id)
- wait <- peer
- return nil
- }
- ps.snapPend[id] = peer
- return nil
-}
-
-// waitExtensions blocks until all satellite protocols are connected and tracked
-// by the peerset.
-func (ps *peerSet) waitSnapExtension(peer *eth.Peer) (*snap.Peer, error) {
- // If the peer does not support a compatible `snap`, don't wait
- if !peer.RunningCap(snap.ProtocolName, snap.ProtocolVersions) {
- return nil, nil
- }
- // Ensure nobody can double connect
- ps.lock.Lock()
-
- id := peer.ID()
- if _, ok := ps.peers[id]; ok {
- ps.lock.Unlock()
- return nil, errPeerAlreadyRegistered // avoid connections with the same id as existing ones
- }
- if _, ok := ps.snapWait[id]; ok {
- ps.lock.Unlock()
- return nil, errPeerAlreadyRegistered // avoid connections with the same id as pending ones
- }
- // If `snap` already connected, retrieve the peer from the pending set
- if snap, ok := ps.snapPend[id]; ok {
- delete(ps.snapPend, id)
-
- ps.lock.Unlock()
- return snap, nil
- }
- // Otherwise wait for `snap` to connect concurrently
- wait := make(chan *snap.Peer)
- ps.snapWait[id] = wait
- ps.lock.Unlock()
-
- return <-wait, nil
-}
-
-// registerPeer injects a new `eth` peer into the working set, or returns an error
-// if the peer is already known.
-func (ps *peerSet) registerPeer(peer *eth.Peer, ext *snap.Peer) error {
- // Start tracking the new peer
- ps.lock.Lock()
- defer ps.lock.Unlock()
-
- if ps.closed {
- return errPeerSetClosed
- }
- id := peer.ID()
- if _, ok := ps.peers[id]; ok {
- return errPeerAlreadyRegistered
- }
- eth := ðPeer{
- Peer: peer,
- }
- if ext != nil {
- eth.snapExt = &snapPeer{ext}
- ps.snapPeers++
- }
- ps.peers[id] = eth
- return nil
-}
-
-// unregisterPeer removes a remote peer from the active set, disabling any further
-// actions to/from that particular entity.
-func (ps *peerSet) unregisterPeer(id string) error {
- ps.lock.Lock()
- defer ps.lock.Unlock()
-
- peer, ok := ps.peers[id]
- if !ok {
- return errPeerNotRegistered
- }
- delete(ps.peers, id)
- if peer.snapExt != nil {
- ps.snapPeers--
- }
- return nil
-}
-
-// peer retrieves the registered peer with the given id.
-func (ps *peerSet) peer(id string) *ethPeer {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- return ps.peers[id]
-}
-
-// peersWithoutBlock retrieves a list of peers that do not have a given block in
-// their set of known hashes so it might be propagated to them.
-func (ps *peerSet) peersWithoutBlock(hash common.Hash) []*ethPeer {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- list := make([]*ethPeer, 0, len(ps.peers))
- for _, p := range ps.peers {
- if !p.KnownBlock(hash) {
- list = append(list, p)
- }
- }
- return list
-}
-
-// peersWithoutTransaction retrieves a list of peers that do not have a given
-// transaction in their set of known hashes.
-func (ps *peerSet) peersWithoutTransaction(hash common.Hash) []*ethPeer {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- list := make([]*ethPeer, 0, len(ps.peers))
- for _, p := range ps.peers {
- if !p.KnownTransaction(hash) {
- list = append(list, p)
- }
- }
- return list
-}
-
-// len returns if the current number of `eth` peers in the set. Since the `snap`
-// peers are tied to the existence of an `eth` connection, that will always be a
-// subset of `eth`.
-func (ps *peerSet) len() int {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- return len(ps.peers)
-}
-
-// snapLen returns if the current number of `snap` peers in the set.
-func (ps *peerSet) snapLen() int {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- return ps.snapPeers
-}
-
-// peerWithHighestTD retrieves the known peer with the currently highest total
-// difficulty, but below the given PoS switchover threshold.
-func (ps *peerSet) peerWithHighestTD() *eth.Peer {
- ps.lock.RLock()
- defer ps.lock.RUnlock()
-
- var (
- bestPeer *eth.Peer
- bestTd *big.Int
- )
- for _, p := range ps.peers {
- if _, td := p.Head(); bestPeer == nil || td.Cmp(bestTd) > 0 {
- bestPeer, bestTd = p.Peer, td
- }
- }
- return bestPeer
-}
-
-// close disconnects all peers.
-func (ps *peerSet) close() {
- ps.lock.Lock()
- defer ps.lock.Unlock()
-
- for _, p := range ps.peers {
- p.Disconnect(p2p.DiscQuitting)
- }
- ps.closed = true
-}
diff --git a/eth/protocols/eth/broadcast.go b/eth/protocols/eth/broadcast.go
deleted file mode 100644
index 3045303f22..0000000000
--- a/eth/protocols/eth/broadcast.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
-)
-
-const (
- // This is the target size for the packs of transactions or announcements. A
- // pack can get larger than this if a single transactions exceeds this size.
- maxTxPacketSize = 100 * 1024
-)
-
-// blockPropagation is a block propagation event, waiting for its turn in the
-// broadcast queue.
-type blockPropagation struct {
- block *types.Block
- td *big.Int
-}
-
-// broadcastBlocks is a write loop that multiplexes blocks and block announcements
-// to the remote peer. The goal is to have an async writer that does not lock up
-// node internals and at the same time rate limits queued data.
-func (p *Peer) broadcastBlocks() {
- for {
- select {
- case prop := <-p.queuedBlocks:
- if err := p.SendNewBlock(prop.block, prop.td); err != nil {
- return
- }
- p.Log().Trace("Propagated block", "number", prop.block.Number(), "hash", prop.block.Hash(), "td", prop.td)
-
- case block := <-p.queuedBlockAnns:
- if err := p.SendNewBlockHashes([]common.Hash{block.Hash()}, []uint64{block.NumberU64()}); err != nil {
- return
- }
- p.Log().Trace("Announced block", "number", block.Number(), "hash", block.Hash())
-
- case <-p.term:
- return
- }
- }
-}
-
-// broadcastTransactions is a write loop that schedules transaction broadcasts
-// to the remote peer. The goal is to have an async writer that does not lock up
-// node internals and at the same time rate limits queued data.
-func (p *Peer) broadcastTransactions() {
- var (
- queue []common.Hash // Queue of hashes to broadcast as full transactions
- done chan struct{} // Non-nil if background broadcaster is running
- fail = make(chan error, 1) // Channel used to receive network error
- failed bool // Flag whether a send failed, discard everything onward
- )
- for {
- // If there's no in-flight broadcast running, check if a new one is needed
- if done == nil && len(queue) > 0 {
- // Pile transaction until we reach our allowed network limit
- var (
- hashesCount uint64
- txs []*types.Transaction
- size common.StorageSize
- )
- for i := 0; i < len(queue) && size < maxTxPacketSize; i++ {
- if tx := p.txpool.Get(queue[i]); tx != nil {
- txs = append(txs, tx)
- size += common.StorageSize(tx.Size())
- }
- hashesCount++
- }
- queue = queue[:copy(queue, queue[hashesCount:])]
-
- // If there's anything available to transfer, fire up an async writer
- if len(txs) > 0 {
- done = make(chan struct{})
- go func() {
- if err := p.SendTransactions(txs); err != nil {
- fail <- err
- return
- }
- close(done)
- p.Log().Trace("Sent transactions", "count", len(txs))
- }()
- }
- }
- // Transfer goroutine may or may not have been started, listen for events
- select {
- case hashes := <-p.txBroadcast:
- // If the connection failed, discard all transaction events
- if failed {
- continue
- }
- // New batch of transactions to be broadcast, queue them (with cap)
- queue = append(queue, hashes...)
- if len(queue) > maxQueuedTxs {
- // Fancy copy and resize to ensure buffer doesn't grow indefinitely
- queue = queue[:copy(queue, queue[len(queue)-maxQueuedTxs:])]
- }
-
- case <-done:
- done = nil
-
- case <-fail:
- failed = true
-
- case <-p.term:
- return
- }
- }
-}
-
-// announceTransactions is a write loop that schedules transaction broadcasts
-// to the remote peer. The goal is to have an async writer that does not lock up
-// node internals and at the same time rate limits queued data.
-func (p *Peer) announceTransactions() {
- var (
- queue []common.Hash // Queue of hashes to announce as transaction stubs
- done chan struct{} // Non-nil if background announcer is running
- fail = make(chan error, 1) // Channel used to receive network error
- failed bool // Flag whether a send failed, discard everything onward
- )
- for {
- // If there's no in-flight announce running, check if a new one is needed
- if done == nil && len(queue) > 0 {
- // Pile transaction hashes until we reach our allowed network limit
- var (
- count int
- pending []common.Hash
- pendingTypes []byte
- pendingSizes []uint32
- size common.StorageSize
- )
- for count = 0; count < len(queue) && size < maxTxPacketSize; count++ {
- if tx := p.txpool.Get(queue[count]); tx != nil {
- pending = append(pending, queue[count])
- pendingTypes = append(pendingTypes, tx.Type())
- pendingSizes = append(pendingSizes, uint32(tx.Size()))
- size += common.HashLength
- }
- }
- // Shift and trim queue
- queue = queue[:copy(queue, queue[count:])]
-
- // If there's anything available to transfer, fire up an async writer
- if len(pending) > 0 {
- done = make(chan struct{})
- go func() {
- if p.version >= ETH68 {
- if err := p.sendPooledTransactionHashes68(pending, pendingTypes, pendingSizes); err != nil {
- fail <- err
- return
- }
- } else {
- if err := p.sendPooledTransactionHashes66(pending); err != nil {
- fail <- err
- return
- }
- }
- close(done)
- p.Log().Trace("Sent transaction announcements", "count", len(pending))
- }()
- }
- }
- // Transfer goroutine may or may not have been started, listen for events
- select {
- case hashes := <-p.txAnnounce:
- // If the connection failed, discard all transaction events
- if failed {
- continue
- }
- // New batch of transactions to be broadcast, queue them (with cap)
- queue = append(queue, hashes...)
- if len(queue) > maxQueuedTxAnns {
- // Fancy copy and resize to ensure buffer doesn't grow indefinitely
- queue = queue[:copy(queue, queue[len(queue)-maxQueuedTxAnns:])]
- }
-
- case <-done:
- done = nil
-
- case <-fail:
- failed = true
-
- case <-p.term:
- return
- }
- }
-}
diff --git a/eth/protocols/eth/discovery.go b/eth/protocols/eth/discovery.go
deleted file mode 100644
index a7bdd47daf..0000000000
--- a/eth/protocols/eth/discovery.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/forkid"
- "github.com/ethereum/go-ethereum/p2p/enode"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// enrEntry is the ENR entry which advertises `eth` protocol on the discovery.
-type enrEntry struct {
- ForkID forkid.ID // Fork identifier per EIP-2124
-
- // Ignore additional fields (for forward compatibility).
- Rest []rlp.RawValue `rlp:"tail"`
-}
-
-// ENRKey implements enr.Entry.
-func (e enrEntry) ENRKey() string {
- return "eth"
-}
-
-// StartENRUpdater starts the `eth` ENR updater loop, which listens for chain
-// head events and updates the requested node record whenever a fork is passed.
-func StartENRUpdater(chain *core.BlockChain, ln *enode.LocalNode) {
- var newHead = make(chan core.ChainHeadEvent, 10)
- sub := chain.SubscribeChainHeadEvent(newHead)
-
- go func() {
- defer sub.Unsubscribe()
- for {
- select {
- case <-newHead:
- ln.Set(currentENREntry(chain))
- case <-sub.Err():
- // Would be nice to sync with Stop, but there is no
- // good way to do that.
- return
- }
- }
- }()
-}
-
-// currentENREntry constructs an `eth` ENR entry based on the current state of the chain.
-func currentENREntry(chain *core.BlockChain) *enrEntry {
- head := chain.CurrentHeader()
- return &enrEntry{
- ForkID: forkid.NewID(chain.Config(), chain.Genesis(), head.Number.Uint64(), head.Time),
- }
-}
diff --git a/eth/protocols/eth/dispatcher.go b/eth/protocols/eth/dispatcher.go
deleted file mode 100644
index ae98820cd6..0000000000
--- a/eth/protocols/eth/dispatcher.go
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2021 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 eth
-
-import (
- "errors"
- "fmt"
- "time"
-
- "github.com/ethereum/go-ethereum/p2p"
-)
-
-var (
- // errDisconnected is returned if a request is attempted to be made to a peer
- // that was already closed.
- errDisconnected = errors.New("disconnected")
-
- // errDanglingResponse is returned if a response arrives with a request id
- // which does not match to any existing pending requests.
- errDanglingResponse = errors.New("response to non-existent request")
-
- // errMismatchingResponseType is returned if the remote peer sent a different
- // packet type as a response to a request than what the local node expected.
- errMismatchingResponseType = errors.New("mismatching response type")
-)
-
-// Request is a pending request to allow tracking it and delivering a response
-// back to the requester on their chosen channel.
-type Request struct {
- peer *Peer // Peer to which this request belongs for untracking
- id uint64 // Request ID to match up replies to
-
- sink chan *Response // Channel to deliver the response on
- cancel chan struct{} // Channel to cancel requests ahead of time
-
- code uint64 // Message code of the request packet
- want uint64 // Message code of the response packet
- data interface{} // Data content of the request packet
-
- Peer string // Demultiplexer if cross-peer requests are batched together
- Sent time.Time // Timestamp when the request was sent
-}
-
-// Close aborts an in-flight request. Although there's no way to notify the
-// remote peer about the cancellation, this method notifies the dispatcher to
-// discard any late responses.
-func (r *Request) Close() error {
- if r.peer == nil { // Tests mock out the dispatcher, skip internal cancellation
- return nil
- }
- cancelOp := &cancel{
- id: r.id,
- fail: make(chan error),
- }
- select {
- case r.peer.reqCancel <- cancelOp:
- if err := <-cancelOp.fail; err != nil {
- return err
- }
- close(r.cancel)
- return nil
- case <-r.peer.term:
- return errDisconnected
- }
-}
-
-// request is a wrapper around a client Request that has an error channel to
-// signal on if sending the request already failed on a network level.
-type request struct {
- req *Request
- fail chan error
-}
-
-// cancel is a maintenance type on the dispatcher to stop tracking a pending
-// request.
-type cancel struct {
- id uint64 // Request ID to stop tracking
- fail chan error
-}
-
-// Response is a reply packet to a previously created request. It is delivered
-// on the channel assigned by the requester subsystem and contains the original
-// request embedded to allow uniquely matching it caller side.
-type Response struct {
- id uint64 // Request ID to match up this reply to
- recv time.Time // Timestamp when the request was received
- code uint64 // Response packet type to cross validate with request
-
- Req *Request // Original request to cross-reference with
- Res interface{} // Remote response for the request query
- Meta interface{} // Metadata generated locally on the receiver thread
- Time time.Duration // Time it took for the request to be served
- Done chan error // Channel to signal message handling to the reader
-}
-
-// response is a wrapper around a remote Response that has an error channel to
-// signal on if processing the response failed.
-type response struct {
- res *Response
- fail chan error
-}
-
-// dispatchRequest schedules the request to the dispatcher for tracking and
-// network serialization, blocking until it's successfully sent.
-//
-// The returned Request must either be closed before discarding it, or the reply
-// must be waited for and the Response's Done channel signalled.
-func (p *Peer) dispatchRequest(req *Request) error {
- reqOp := &request{
- req: req,
- fail: make(chan error),
- }
- req.cancel = make(chan struct{})
- req.peer = p
- req.Peer = p.id
-
- select {
- case p.reqDispatch <- reqOp:
- return <-reqOp.fail
- case <-p.term:
- return errDisconnected
- }
-}
-
-// dispatchRequest fulfils a pending request and delivers it to the requested
-// sink.
-func (p *Peer) dispatchResponse(res *Response, metadata func() interface{}) error {
- resOp := &response{
- res: res,
- fail: make(chan error),
- }
- res.recv = time.Now()
- res.Done = make(chan error)
-
- select {
- case p.resDispatch <- resOp:
- // Ensure the response is accepted by the dispatcher
- if err := <-resOp.fail; err != nil {
- return nil
- }
- // Request was accepted, run any postprocessing step to generate metadata
- // on the receiver thread, not the sink thread
- if metadata != nil {
- res.Meta = metadata()
- }
- // Deliver the filled out response and wait until it's handled. This
- // path is a bit funky as Go's select has no order, so if a response
- // arrives to an already cancelled request, there's a 50-50% changes
- // of picking on channel or the other. To avoid such cases delivering
- // the packet upstream, check for cancellation first and only after
- // block on delivery.
- select {
- case <-res.Req.cancel:
- return nil // Request cancelled, silently discard response
- default:
- // Request not yet cancelled, attempt to deliver it, but do watch
- // for fresh cancellations too
- select {
- case res.Req.sink <- res:
- return <-res.Done // Response delivered, return any errors
- case <-res.Req.cancel:
- return nil // Request cancelled, silently discard response
- }
- }
-
- case <-p.term:
- return errDisconnected
- }
-}
-
-// dispatcher is a loop that accepts requests from higher layer packages, pushes
-// it to the network and tracks and dispatches the responses back to the original
-// requester.
-func (p *Peer) dispatcher() {
- pending := make(map[uint64]*Request)
-
- for {
- select {
- case reqOp := <-p.reqDispatch:
- req := reqOp.req
- req.Sent = time.Now()
-
- requestTracker.Track(p.id, p.version, req.code, req.want, req.id)
- err := p2p.Send(p.rw, req.code, req.data)
- reqOp.fail <- err
-
- if err == nil {
- pending[req.id] = req
- }
-
- case cancelOp := <-p.reqCancel:
- // Retrieve the pending request to cancel and short circuit if it
- // has already been serviced and is not available anymore
- req := pending[cancelOp.id]
- if req == nil {
- cancelOp.fail <- nil
- continue
- }
- // Stop tracking the request
- delete(pending, cancelOp.id)
- cancelOp.fail <- nil
-
- case resOp := <-p.resDispatch:
- res := resOp.res
- res.Req = pending[res.id]
-
- // Independent if the request exists or not, track this packet
- requestTracker.Fulfil(p.id, p.version, res.code, res.id)
-
- switch {
- case res.Req == nil:
- // Response arrived with an untracked ID. Since even cancelled
- // requests are tracked until fulfillment, a dangling response
- // means the remote peer implements the protocol badly.
- resOp.fail <- errDanglingResponse
-
- case res.Req.want != res.code:
- // Response arrived, but it's a different packet type than the
- // one expected by the requester. Either the local code is bad,
- // or the remote peer send junk. In neither cases can we handle
- // the packet.
- resOp.fail <- fmt.Errorf("%w: have %d, want %d", errMismatchingResponseType, res.code, res.Req.want)
-
- default:
- // All dispatcher checks passed and the response was initialized
- // with the matching request. Signal to the delivery routine that
- // it can wait for a handler response and dispatch the data.
- res.Time = res.recv.Sub(res.Req.Sent)
- resOp.fail <- nil
-
- // Stop tracking the request, the response dispatcher will deliver
- delete(pending, res.id)
- }
-
- case <-p.term:
- return
- }
- }
-}
diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go
deleted file mode 100644
index 42d0412a12..0000000000
--- a/eth/protocols/eth/handler.go
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "fmt"
- "math/big"
- "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/metrics"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
- "github.com/ethereum/go-ethereum/p2p/enr"
- "github.com/ethereum/go-ethereum/params"
-)
-
-const (
- // softResponseLimit is the target maximum size of replies to data retrievals.
- softResponseLimit = 2 * 1024 * 1024
-
- // maxHeadersServe is the maximum number of block headers to serve. This number
- // is there to limit the number of disk lookups.
- maxHeadersServe = 1024
-
- // maxBodiesServe is the maximum number of block bodies to serve. This number
- // is mostly there to limit the number of disk lookups. With 24KB block sizes
- // nowadays, the practical limit will always be softResponseLimit.
- maxBodiesServe = 1024
-
- // maxReceiptsServe is the maximum number of block receipts to serve. This
- // number is mostly there to limit the number of disk lookups. With block
- // containing 200+ transactions nowadays, the practical limit will always
- // be softResponseLimit.
- maxReceiptsServe = 1024
-)
-
-// Handler is a callback to invoke from an outside runner after the boilerplate
-// exchanges have passed.
-type Handler func(peer *Peer) error
-
-// Backend defines the data retrieval methods to serve remote requests and the
-// callback methods to invoke on remote deliveries.
-type Backend interface {
- // Chain retrieves the blockchain object to serve data.
- Chain() *core.BlockChain
-
- // TxPool retrieves the transaction pool object to serve data.
- TxPool() TxPool
-
- // AcceptTxs retrieves whether transaction processing is enabled on the node
- // or if inbound transactions should simply be dropped.
- AcceptTxs() bool
-
- // RunPeer is invoked when a peer joins on the `eth` protocol. The handler
- // should do any peer maintenance work, handshakes and validations. If all
- // is passed, control should be given back to the `handler` to process the
- // inbound messages going forward.
- RunPeer(peer *Peer, handler Handler) error
-
- // PeerInfo retrieves all known `eth` information about a peer.
- PeerInfo(id enode.ID) interface{}
-
- // Handle is a callback to be invoked when a data packet is received from
- // the remote peer. Only packets not consumed by the protocol handler will
- // be forwarded to the backend.
- Handle(peer *Peer, packet Packet) error
-}
-
-// TxPool defines the methods needed by the protocol handler to serve transactions.
-type TxPool interface {
- // Get retrieves the transaction from the local txpool with the given hash.
- Get(hash common.Hash) *types.Transaction
-}
-
-// MakeProtocols constructs the P2P protocol definitions for `eth`.
-func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2p.Protocol {
- protocols := make([]p2p.Protocol, 0, len(ProtocolVersions))
- for _, version := range ProtocolVersions {
- // Blob transactions require eth/68 announcements, disable everything else
- if version <= ETH67 && backend.Chain().Config().CancunTime != nil {
- continue
- }
- version := version // Closure
-
- protocols = append(protocols, p2p.Protocol{
- Name: ProtocolName,
- Version: version,
- Length: protocolLengths[version],
- Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
- peer := NewPeer(version, p, rw, backend.TxPool())
- defer peer.Close()
-
- return backend.RunPeer(peer, func(peer *Peer) error {
- return Handle(backend, peer)
- })
- },
- NodeInfo: func() interface{} {
- return nodeInfo(backend.Chain(), network)
- },
- PeerInfo: func(id enode.ID) interface{} {
- return backend.PeerInfo(id)
- },
- Attributes: []enr.Entry{currentENREntry(backend.Chain())},
- DialCandidates: dnsdisc,
- })
- }
- return protocols
-}
-
-// NodeInfo represents a short summary of the `eth` sub-protocol metadata
-// known about the host peer.
-type NodeInfo struct {
- Network uint64 `json:"network"` // Ethereum network ID (1=Mainnet, Goerli=5)
- Difficulty *big.Int `json:"difficulty"` // Total difficulty of the host's blockchain
- Genesis common.Hash `json:"genesis"` // SHA3 hash of the host's genesis block
- Config *params.ChainConfig `json:"config"` // Chain configuration for the fork rules
- Head common.Hash `json:"head"` // Hex hash of the host's best owned block
-}
-
-// nodeInfo retrieves some `eth` protocol metadata about the running host node.
-func nodeInfo(chain *core.BlockChain, network uint64) *NodeInfo {
- head := chain.CurrentBlock()
- hash := head.Hash()
-
- return &NodeInfo{
- Network: network,
- Difficulty: chain.GetTd(hash, head.Number.Uint64()),
- Genesis: chain.Genesis().Hash(),
- Config: chain.Config(),
- Head: hash,
- }
-}
-
-// Handle is invoked whenever an `eth` connection is made that successfully passes
-// the protocol handshake. This method will keep processing messages until the
-// connection is torn down.
-func Handle(backend Backend, peer *Peer) error {
- for {
- if err := handleMessage(backend, peer); err != nil {
- peer.Log().Debug("Message handling failed in `eth`", "err", err)
- return err
- }
- }
-}
-
-type msgHandler func(backend Backend, msg Decoder, peer *Peer) error
-type Decoder interface {
- Decode(val interface{}) error
- Time() time.Time
-}
-
-var eth67 = map[uint64]msgHandler{
- NewBlockHashesMsg: handleNewBlockhashes,
- NewBlockMsg: handleNewBlock,
- TransactionsMsg: handleTransactions,
- NewPooledTransactionHashesMsg: handleNewPooledTransactionHashes67,
- GetBlockHeadersMsg: handleGetBlockHeaders,
- BlockHeadersMsg: handleBlockHeaders,
- GetBlockBodiesMsg: handleGetBlockBodies,
- BlockBodiesMsg: handleBlockBodies,
- GetReceiptsMsg: handleGetReceipts,
- ReceiptsMsg: handleReceipts,
- GetPooledTransactionsMsg: handleGetPooledTransactions,
- PooledTransactionsMsg: handlePooledTransactions,
-}
-
-var eth68 = map[uint64]msgHandler{
- NewBlockHashesMsg: handleNewBlockhashes,
- NewBlockMsg: handleNewBlock,
- TransactionsMsg: handleTransactions,
- NewPooledTransactionHashesMsg: handleNewPooledTransactionHashes68,
- GetBlockHeadersMsg: handleGetBlockHeaders,
- BlockHeadersMsg: handleBlockHeaders,
- GetBlockBodiesMsg: handleGetBlockBodies,
- BlockBodiesMsg: handleBlockBodies,
- GetReceiptsMsg: handleGetReceipts,
- ReceiptsMsg: handleReceipts,
- GetPooledTransactionsMsg: handleGetPooledTransactions,
- PooledTransactionsMsg: handlePooledTransactions,
-}
-
-// handleMessage is invoked whenever an inbound message is received from a remote
-// peer. The remote connection is torn down upon returning any error.
-func handleMessage(backend Backend, peer *Peer) error {
- // Read the next message from the remote peer, and ensure it's fully consumed
- msg, err := peer.rw.ReadMsg()
- if err != nil {
- return err
- }
- if msg.Size > maxMessageSize {
- return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize)
- }
- defer msg.Discard()
-
- var handlers = eth67
- if peer.Version() >= ETH68 {
- handlers = eth68
- }
- // Track the amount of time it takes to serve the request and run the handler
- if metrics.Enabled {
- h := fmt.Sprintf("%s/%s/%d/%#02x", p2p.HandleHistName, ProtocolName, peer.Version(), msg.Code)
- defer func(start time.Time) {
- sampler := func() metrics.Sample {
- return metrics.ResettingSample(
- metrics.NewExpDecaySample(1028, 0.015),
- )
- }
- metrics.GetOrRegisterHistogramLazy(h, nil, sampler).Update(time.Since(start).Microseconds())
- }(time.Now())
- }
- if handler := handlers[msg.Code]; handler != nil {
- return handler(backend, msg, peer)
- }
- return fmt.Errorf("%w: %v", errInvalidMsgCode, msg.Code)
-}
diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go
deleted file mode 100644
index 41e18bfb3e..0000000000
--- a/eth/protocols/eth/handler_test.go
+++ /dev/null
@@ -1,504 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "math"
- "math/big"
- "math/rand"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/beacon"
- "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/txpool"
- "github.com/ethereum/go-ethereum/core/txpool/legacypool"
- "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/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
- "github.com/ethereum/go-ethereum/params"
-)
-
-var (
- // testKey is a private key to use for funding a tester account.
- testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
-
- // testAddr is the Ethereum address of the tester account.
- testAddr = crypto.PubkeyToAddress(testKey.PublicKey)
-)
-
-func u64(val uint64) *uint64 { return &val }
-
-// testBackend is a mock implementation of the live Ethereum message handler. Its
-// purpose is to allow testing the request/reply workflows and wire serialization
-// in the `eth` protocol without actually doing any data processing.
-type testBackend struct {
- db ethdb.Database
- chain *core.BlockChain
- txpool *txpool.TxPool
-}
-
-// newTestBackend creates an empty chain and wraps it into a mock backend.
-func newTestBackend(blocks int) *testBackend {
- return newTestBackendWithGenerator(blocks, false, nil)
-}
-
-// newTestBackend creates a chain with a number of explicitly defined blocks and
-// wraps it into a mock backend.
-func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int, *core.BlockGen)) *testBackend {
- var (
- // Create a database pre-initialize with a genesis block
- db = rawdb.NewMemoryDatabase()
- config = params.TestChainConfig
- engine consensus.Engine = ethash.NewFaker()
- )
-
- if shanghai {
- config = ¶ms.ChainConfig{
- ChainID: big.NewInt(1),
- HomesteadBlock: big.NewInt(0),
- DAOForkBlock: nil,
- DAOForkSupport: true,
- EIP150Block: big.NewInt(0),
- EIP155Block: big.NewInt(0),
- EIP158Block: big.NewInt(0),
- ByzantiumBlock: big.NewInt(0),
- ConstantinopleBlock: big.NewInt(0),
- PetersburgBlock: big.NewInt(0),
- IstanbulBlock: big.NewInt(0),
- MuirGlacierBlock: big.NewInt(0),
- BerlinBlock: big.NewInt(0),
- LondonBlock: big.NewInt(0),
- ArrowGlacierBlock: big.NewInt(0),
- GrayGlacierBlock: big.NewInt(0),
- MergeNetsplitBlock: big.NewInt(0),
- ShanghaiTime: u64(0),
- TerminalTotalDifficulty: big.NewInt(0),
- TerminalTotalDifficultyPassed: true,
- Ethash: new(params.EthashConfig),
- }
- engine = beacon.NewFaker()
- }
-
- gspec := &core.Genesis{
- Config: config,
- Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(100_000_000_000_000_000)}},
- }
- chain, _ := core.NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil, nil)
-
- _, bs, _ := core.GenerateChainWithGenesis(gspec, engine, blocks, generator)
- if _, err := chain.InsertChain(bs); err != nil {
- panic(err)
- }
- for _, block := range bs {
- chain.TrieDB().Commit(block.Root(), false)
- }
- txconfig := legacypool.DefaultConfig
- txconfig.Journal = "" // Don't litter the disk with test journals
-
- pool := legacypool.New(txconfig, chain)
- txpool, _ := txpool.New(new(big.Int).SetUint64(txconfig.PriceLimit), chain, []txpool.SubPool{pool})
-
- return &testBackend{
- db: db,
- chain: chain,
- txpool: txpool,
- }
-}
-
-// close tears down the transaction pool and chain behind the mock backend.
-func (b *testBackend) close() {
- b.txpool.Close()
- b.chain.Stop()
-}
-
-func (b *testBackend) Chain() *core.BlockChain { return b.chain }
-func (b *testBackend) TxPool() TxPool { return b.txpool }
-
-func (b *testBackend) RunPeer(peer *Peer, handler Handler) error {
- // Normally the backend would do peer maintenance and handshakes. All that
- // is omitted and we will just give control back to the handler.
- return handler(peer)
-}
-func (b *testBackend) PeerInfo(enode.ID) interface{} { panic("not implemented") }
-
-func (b *testBackend) AcceptTxs() bool {
- panic("data processing tests should be done in the handler package")
-}
-func (b *testBackend) Handle(*Peer, Packet) error {
- panic("data processing tests should be done in the handler package")
-}
-
-// Tests that block headers can be retrieved from a remote chain based on user queries.
-func TestGetBlockHeaders67(t *testing.T) { testGetBlockHeaders(t, ETH67) }
-func TestGetBlockHeaders68(t *testing.T) { testGetBlockHeaders(t, ETH68) }
-
-func testGetBlockHeaders(t *testing.T, protocol uint) {
- t.Parallel()
-
- backend := newTestBackend(maxHeadersServe + 15)
- defer backend.close()
-
- peer, _ := newTestPeer("peer", protocol, backend)
- defer peer.close()
-
- // Create a "random" unknown hash for testing
- var unknown common.Hash
- for i := range unknown {
- unknown[i] = byte(i)
- }
- getHashes := func(from, limit uint64) (hashes []common.Hash) {
- for i := uint64(0); i < limit; i++ {
- hashes = append(hashes, backend.chain.GetCanonicalHash(from-1-i))
- }
- return hashes
- }
- // Create a batch of tests for various scenarios
- limit := uint64(maxHeadersServe)
- tests := []struct {
- query *GetBlockHeadersRequest // The query to execute for header retrieval
- expect []common.Hash // The hashes of the block whose headers are expected
- }{
- // A single random block should be retrievable by hash
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Hash: backend.chain.GetBlockByNumber(limit / 2).Hash()}, Amount: 1},
- []common.Hash{backend.chain.GetBlockByNumber(limit / 2).Hash()},
- },
- // A single random block should be retrievable by number
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: limit / 2}, Amount: 1},
- []common.Hash{backend.chain.GetBlockByNumber(limit / 2).Hash()},
- },
- // Multiple headers should be retrievable in both directions
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: limit / 2}, Amount: 3},
- []common.Hash{
- backend.chain.GetBlockByNumber(limit / 2).Hash(),
- backend.chain.GetBlockByNumber(limit/2 + 1).Hash(),
- backend.chain.GetBlockByNumber(limit/2 + 2).Hash(),
- },
- }, {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: limit / 2}, Amount: 3, Reverse: true},
- []common.Hash{
- backend.chain.GetBlockByNumber(limit / 2).Hash(),
- backend.chain.GetBlockByNumber(limit/2 - 1).Hash(),
- backend.chain.GetBlockByNumber(limit/2 - 2).Hash(),
- },
- },
- // Multiple headers with skip lists should be retrievable
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3},
- []common.Hash{
- backend.chain.GetBlockByNumber(limit / 2).Hash(),
- backend.chain.GetBlockByNumber(limit/2 + 4).Hash(),
- backend.chain.GetBlockByNumber(limit/2 + 8).Hash(),
- },
- }, {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: limit / 2}, Skip: 3, Amount: 3, Reverse: true},
- []common.Hash{
- backend.chain.GetBlockByNumber(limit / 2).Hash(),
- backend.chain.GetBlockByNumber(limit/2 - 4).Hash(),
- backend.chain.GetBlockByNumber(limit/2 - 8).Hash(),
- },
- },
- // The chain endpoints should be retrievable
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 0}, Amount: 1},
- []common.Hash{backend.chain.GetBlockByNumber(0).Hash()},
- },
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: backend.chain.CurrentBlock().Number.Uint64()}, Amount: 1},
- []common.Hash{backend.chain.CurrentBlock().Hash()},
- },
- { // If the peer requests a bit into the future, we deliver what we have
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: backend.chain.CurrentBlock().Number.Uint64()}, Amount: 10},
- []common.Hash{backend.chain.CurrentBlock().Hash()},
- },
- // Ensure protocol limits are honored
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: backend.chain.CurrentBlock().Number.Uint64() - 1}, Amount: limit + 10, Reverse: true},
- getHashes(backend.chain.CurrentBlock().Number.Uint64(), limit),
- },
- // Check that requesting more than available is handled gracefully
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: backend.chain.CurrentBlock().Number.Uint64() - 4}, Skip: 3, Amount: 3},
- []common.Hash{
- backend.chain.GetBlockByNumber(backend.chain.CurrentBlock().Number.Uint64() - 4).Hash(),
- backend.chain.GetBlockByNumber(backend.chain.CurrentBlock().Number.Uint64()).Hash(),
- },
- }, {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 4}, Skip: 3, Amount: 3, Reverse: true},
- []common.Hash{
- backend.chain.GetBlockByNumber(4).Hash(),
- backend.chain.GetBlockByNumber(0).Hash(),
- },
- },
- // Check that requesting more than available is handled gracefully, even if mid skip
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: backend.chain.CurrentBlock().Number.Uint64() - 4}, Skip: 2, Amount: 3},
- []common.Hash{
- backend.chain.GetBlockByNumber(backend.chain.CurrentBlock().Number.Uint64() - 4).Hash(),
- backend.chain.GetBlockByNumber(backend.chain.CurrentBlock().Number.Uint64() - 1).Hash(),
- },
- }, {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 4}, Skip: 2, Amount: 3, Reverse: true},
- []common.Hash{
- backend.chain.GetBlockByNumber(4).Hash(),
- backend.chain.GetBlockByNumber(1).Hash(),
- },
- },
- // Check a corner case where requesting more can iterate past the endpoints
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 2}, Amount: 5, Reverse: true},
- []common.Hash{
- backend.chain.GetBlockByNumber(2).Hash(),
- backend.chain.GetBlockByNumber(1).Hash(),
- backend.chain.GetBlockByNumber(0).Hash(),
- },
- },
- // Check a corner case where skipping overflow loops back into the chain start
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Hash: backend.chain.GetBlockByNumber(3).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1},
- []common.Hash{
- backend.chain.GetBlockByNumber(3).Hash(),
- },
- },
- // Check a corner case where skipping overflow loops back to the same header
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Hash: backend.chain.GetBlockByNumber(1).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64},
- []common.Hash{
- backend.chain.GetBlockByNumber(1).Hash(),
- },
- },
- // Check that non existing headers aren't returned
- {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Hash: unknown}, Amount: 1},
- []common.Hash{},
- }, {
- &GetBlockHeadersRequest{Origin: HashOrNumber{Number: backend.chain.CurrentBlock().Number.Uint64() + 1}, Amount: 1},
- []common.Hash{},
- },
- }
- // Run each of the tests and verify the results against the chain
- for i, tt := range tests {
- // Collect the headers to expect in the response
- var headers []*types.Header
- for _, hash := range tt.expect {
- headers = append(headers, backend.chain.GetBlockByHash(hash).Header())
- }
- // Send the hash request and verify the response
- p2p.Send(peer.app, GetBlockHeadersMsg, &GetBlockHeadersPacket{
- RequestId: 123,
- GetBlockHeadersRequest: tt.query,
- })
- if err := p2p.ExpectMsg(peer.app, BlockHeadersMsg, &BlockHeadersPacket{
- RequestId: 123,
- BlockHeadersRequest: headers,
- }); err != nil {
- t.Errorf("test %d: headers mismatch: %v", i, err)
- }
- // If the test used number origins, repeat with hashes as the too
- if tt.query.Origin.Hash == (common.Hash{}) {
- if origin := backend.chain.GetBlockByNumber(tt.query.Origin.Number); origin != nil {
- tt.query.Origin.Hash, tt.query.Origin.Number = origin.Hash(), 0
-
- p2p.Send(peer.app, GetBlockHeadersMsg, &GetBlockHeadersPacket{
- RequestId: 456,
- GetBlockHeadersRequest: tt.query,
- })
- expected := &BlockHeadersPacket{RequestId: 456, BlockHeadersRequest: headers}
- if err := p2p.ExpectMsg(peer.app, BlockHeadersMsg, expected); err != nil {
- t.Errorf("test %d by hash: headers mismatch: %v", i, err)
- }
- }
- }
- }
-}
-
-// Tests that block contents can be retrieved from a remote chain based on their hashes.
-func TestGetBlockBodies67(t *testing.T) { testGetBlockBodies(t, ETH67) }
-func TestGetBlockBodies68(t *testing.T) { testGetBlockBodies(t, ETH68) }
-
-func testGetBlockBodies(t *testing.T, protocol uint) {
- t.Parallel()
-
- gen := func(n int, g *core.BlockGen) {
- if n%2 == 0 {
- w := &types.Withdrawal{
- Address: common.Address{0xaa},
- Amount: 42,
- }
- g.AddWithdrawal(w)
- }
- }
-
- backend := newTestBackendWithGenerator(maxBodiesServe+15, true, gen)
- defer backend.close()
-
- peer, _ := newTestPeer("peer", protocol, backend)
- defer peer.close()
-
- // Create a batch of tests for various scenarios
- limit := maxBodiesServe
- tests := []struct {
- random int // Number of blocks to fetch randomly from the chain
- explicit []common.Hash // Explicitly requested blocks
- available []bool // Availability of explicitly requested blocks
- expected int // Total number of existing blocks to expect
- }{
- {1, nil, nil, 1}, // A single random block should be retrievable
- {10, nil, nil, 10}, // Multiple random blocks should be retrievable
- {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable
- {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned
- {0, []common.Hash{backend.chain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable
- {0, []common.Hash{backend.chain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable
- {0, []common.Hash{{}}, []bool{false}, 0}, // A non existent block should not be returned
-
- // Existing and non-existing blocks interleaved should not cause problems
- {0, []common.Hash{
- {},
- backend.chain.GetBlockByNumber(1).Hash(),
- {},
- backend.chain.GetBlockByNumber(10).Hash(),
- {},
- backend.chain.GetBlockByNumber(100).Hash(),
- {},
- }, []bool{false, true, false, true, false, true, false}, 3},
- }
- // Run each of the tests and verify the results against the chain
- for i, tt := range tests {
- // Collect the hashes to request, and the response to expect
- var (
- hashes []common.Hash
- bodies []*BlockBody
- seen = make(map[int64]bool)
- )
- for j := 0; j < tt.random; j++ {
- for {
- num := rand.Int63n(int64(backend.chain.CurrentBlock().Number.Uint64()))
- if !seen[num] {
- seen[num] = true
-
- block := backend.chain.GetBlockByNumber(uint64(num))
- hashes = append(hashes, block.Hash())
- if len(bodies) < tt.expected {
- bodies = append(bodies, &BlockBody{Transactions: block.Transactions(), Uncles: block.Uncles(), Withdrawals: block.Withdrawals()})
- }
- break
- }
- }
- }
- for j, hash := range tt.explicit {
- hashes = append(hashes, hash)
- if tt.available[j] && len(bodies) < tt.expected {
- block := backend.chain.GetBlockByHash(hash)
- bodies = append(bodies, &BlockBody{Transactions: block.Transactions(), Uncles: block.Uncles(), Withdrawals: block.Withdrawals()})
- }
- }
-
- // Send the hash request and verify the response
- p2p.Send(peer.app, GetBlockBodiesMsg, &GetBlockBodiesPacket{
- RequestId: 123,
- GetBlockBodiesRequest: hashes,
- })
- if err := p2p.ExpectMsg(peer.app, BlockBodiesMsg, &BlockBodiesPacket{
- RequestId: 123,
- BlockBodiesResponse: bodies,
- }); err != nil {
- t.Fatalf("test %d: bodies mismatch: %v", i, err)
- }
- }
-}
-
-// Tests that the transaction receipts can be retrieved based on hashes.
-func TestGetBlockReceipts67(t *testing.T) { testGetBlockReceipts(t, ETH67) }
-func TestGetBlockReceipts68(t *testing.T) { testGetBlockReceipts(t, ETH68) }
-
-func testGetBlockReceipts(t *testing.T, protocol uint) {
- t.Parallel()
-
- // Define three accounts to simulate transactions with
- acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
- acc2Key, _ := crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
- acc1Addr := crypto.PubkeyToAddress(acc1Key.PublicKey)
- acc2Addr := crypto.PubkeyToAddress(acc2Key.PublicKey)
-
- signer := types.HomesteadSigner{}
- // Create a chain generator with some simple transactions (blatantly stolen from @fjl/chain_markets_test)
- generator := func(i int, block *core.BlockGen) {
- switch i {
- case 0:
- // In block 1, the test bank sends account #1 some ether.
- tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(10_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testKey)
- block.AddTx(tx)
- case 1:
- // In block 2, the test bank sends some more ether to account #1.
- // acc1Addr passes it on to account #2.
- tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(testAddr), acc1Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, testKey)
- tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(acc1Addr), acc2Addr, big.NewInt(1_000_000_000_000_000), params.TxGas, block.BaseFee(), nil), signer, acc1Key)
- block.AddTx(tx1)
- block.AddTx(tx2)
- case 2:
- // Block 3 is empty but was mined by account #2.
- block.SetCoinbase(acc2Addr)
- block.SetExtra([]byte("yeehaw"))
- case 3:
- // Block 4 includes blocks 2 and 3 as uncle headers (with modified extra data).
- b2 := block.PrevBlock(1).Header()
- b2.Extra = []byte("foo")
- block.AddUncle(b2)
- b3 := block.PrevBlock(2).Header()
- b3.Extra = []byte("foo")
- block.AddUncle(b3)
- }
- }
- // Assemble the test environment
- backend := newTestBackendWithGenerator(4, false, generator)
- defer backend.close()
-
- peer, _ := newTestPeer("peer", protocol, backend)
- defer peer.close()
-
- // Collect the hashes to request, and the response to expect
- var (
- hashes []common.Hash
- receipts [][]*types.Receipt
- )
- for i := uint64(0); i <= backend.chain.CurrentBlock().Number.Uint64(); i++ {
- block := backend.chain.GetBlockByNumber(i)
-
- hashes = append(hashes, block.Hash())
- receipts = append(receipts, backend.chain.GetReceiptsByHash(block.Hash()))
- }
- // Send the hash request and verify the response
- p2p.Send(peer.app, GetReceiptsMsg, &GetReceiptsPacket{
- RequestId: 123,
- GetReceiptsRequest: hashes,
- })
- if err := p2p.ExpectMsg(peer.app, ReceiptsMsg, &ReceiptsPacket{
- RequestId: 123,
- ReceiptsResponse: receipts,
- }); err != nil {
- t.Errorf("receipts mismatch: %v", err)
- }
-}
diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go
deleted file mode 100644
index 069e92dadf..0000000000
--- a/eth/protocols/eth/handlers.go
+++ /dev/null
@@ -1,501 +0,0 @@
-// Copyright 2021 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 eth
-
-import (
- "encoding/json"
- "fmt"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-func handleGetBlockHeaders(backend Backend, msg Decoder, peer *Peer) error {
- // Decode the complex header query
- var query GetBlockHeadersPacket
- if err := msg.Decode(&query); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- response := ServiceGetBlockHeadersQuery(backend.Chain(), query.GetBlockHeadersRequest, peer)
- return peer.ReplyBlockHeadersRLP(query.RequestId, response)
-}
-
-// ServiceGetBlockHeadersQuery assembles the response to a header query. It is
-// exposed to allow external packages to test protocol behavior.
-func ServiceGetBlockHeadersQuery(chain *core.BlockChain, query *GetBlockHeadersRequest, peer *Peer) []rlp.RawValue {
- if query.Skip == 0 {
- // The fast path: when the request is for a contiguous segment of headers.
- return serviceContiguousBlockHeaderQuery(chain, query)
- } else {
- return serviceNonContiguousBlockHeaderQuery(chain, query, peer)
- }
-}
-
-func serviceNonContiguousBlockHeaderQuery(chain *core.BlockChain, query *GetBlockHeadersRequest, peer *Peer) []rlp.RawValue {
- hashMode := query.Origin.Hash != (common.Hash{})
- first := true
- maxNonCanonical := uint64(100)
-
- // Gather headers until the fetch or network limits is reached
- var (
- bytes common.StorageSize
- headers []rlp.RawValue
- unknown bool
- lookups int
- )
- for !unknown && len(headers) < int(query.Amount) && bytes < softResponseLimit &&
- len(headers) < maxHeadersServe && lookups < 2*maxHeadersServe {
- lookups++
- // Retrieve the next header satisfying the query
- var origin *types.Header
- if hashMode {
- if first {
- first = false
- origin = chain.GetHeaderByHash(query.Origin.Hash)
- if origin != nil {
- query.Origin.Number = origin.Number.Uint64()
- }
- } else {
- origin = chain.GetHeader(query.Origin.Hash, query.Origin.Number)
- }
- } else {
- origin = chain.GetHeaderByNumber(query.Origin.Number)
- }
- if origin == nil {
- break
- }
- if rlpData, err := rlp.EncodeToBytes(origin); err != nil {
- log.Crit("Unable to encode our own headers", "err", err)
- } else {
- headers = append(headers, rlp.RawValue(rlpData))
- bytes += common.StorageSize(len(rlpData))
- }
- // Advance to the next header of the query
- switch {
- case hashMode && query.Reverse:
- // Hash based traversal towards the genesis block
- ancestor := query.Skip + 1
- if ancestor == 0 {
- unknown = true
- } else {
- query.Origin.Hash, query.Origin.Number = chain.GetAncestor(query.Origin.Hash, query.Origin.Number, ancestor, &maxNonCanonical)
- unknown = (query.Origin.Hash == common.Hash{})
- }
- case hashMode && !query.Reverse:
- // Hash based traversal towards the leaf block
- var (
- current = origin.Number.Uint64()
- next = current + query.Skip + 1
- )
- if next <= current {
- infos, _ := json.MarshalIndent(peer.Peer.Info(), "", " ")
- peer.Log().Warn("GetBlockHeaders skip overflow attack", "current", current, "skip", query.Skip, "next", next, "attacker", infos)
- unknown = true
- } else {
- if header := chain.GetHeaderByNumber(next); header != nil {
- nextHash := header.Hash()
- expOldHash, _ := chain.GetAncestor(nextHash, next, query.Skip+1, &maxNonCanonical)
- if expOldHash == query.Origin.Hash {
- query.Origin.Hash, query.Origin.Number = nextHash, next
- } else {
- unknown = true
- }
- } else {
- unknown = true
- }
- }
- case query.Reverse:
- // Number based traversal towards the genesis block
- if query.Origin.Number >= query.Skip+1 {
- query.Origin.Number -= query.Skip + 1
- } else {
- unknown = true
- }
-
- case !query.Reverse:
- // Number based traversal towards the leaf block
- query.Origin.Number += query.Skip + 1
- }
- }
- return headers
-}
-
-func serviceContiguousBlockHeaderQuery(chain *core.BlockChain, query *GetBlockHeadersRequest) []rlp.RawValue {
- count := query.Amount
- if count > maxHeadersServe {
- count = maxHeadersServe
- }
- if query.Origin.Hash == (common.Hash{}) {
- // Number mode, just return the canon chain segment. The backend
- // delivers in [N, N-1, N-2..] descending order, so we need to
- // accommodate for that.
- from := query.Origin.Number
- if !query.Reverse {
- from = from + count - 1
- }
- headers := chain.GetHeadersFrom(from, count)
- if !query.Reverse {
- for i, j := 0, len(headers)-1; i < j; i, j = i+1, j-1 {
- headers[i], headers[j] = headers[j], headers[i]
- }
- }
- return headers
- }
- // Hash mode.
- var (
- headers []rlp.RawValue
- hash = query.Origin.Hash
- header = chain.GetHeaderByHash(hash)
- )
- if header != nil {
- rlpData, _ := rlp.EncodeToBytes(header)
- headers = append(headers, rlpData)
- } else {
- // We don't even have the origin header
- return headers
- }
- num := header.Number.Uint64()
- if !query.Reverse {
- // Theoretically, we are tasked to deliver header by hash H, and onwards.
- // However, if H is not canon, we will be unable to deliver any descendants of
- // H.
- if canonHash := chain.GetCanonicalHash(num); canonHash != hash {
- // Not canon, we can't deliver descendants
- return headers
- }
- descendants := chain.GetHeadersFrom(num+count-1, count-1)
- for i, j := 0, len(descendants)-1; i < j; i, j = i+1, j-1 {
- descendants[i], descendants[j] = descendants[j], descendants[i]
- }
- headers = append(headers, descendants...)
- return headers
- }
- { // Last mode: deliver ancestors of H
- for i := uint64(1); header != nil && i < count; i++ {
- header = chain.GetHeaderByHash(header.ParentHash)
- if header == nil {
- break
- }
- rlpData, _ := rlp.EncodeToBytes(header)
- headers = append(headers, rlpData)
- }
- return headers
- }
-}
-
-func handleGetBlockBodies(backend Backend, msg Decoder, peer *Peer) error {
- // Decode the block body retrieval message
- var query GetBlockBodiesPacket
- if err := msg.Decode(&query); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- response := ServiceGetBlockBodiesQuery(backend.Chain(), query.GetBlockBodiesRequest)
- return peer.ReplyBlockBodiesRLP(query.RequestId, response)
-}
-
-// ServiceGetBlockBodiesQuery assembles the response to a body query. It is
-// exposed to allow external packages to test protocol behavior.
-func ServiceGetBlockBodiesQuery(chain *core.BlockChain, query GetBlockBodiesRequest) []rlp.RawValue {
- // Gather blocks until the fetch or network limits is reached
- var (
- bytes int
- bodies []rlp.RawValue
- )
- for lookups, hash := range query {
- if bytes >= softResponseLimit || len(bodies) >= maxBodiesServe ||
- lookups >= 2*maxBodiesServe {
- break
- }
- if data := chain.GetBodyRLP(hash); len(data) != 0 {
- bodies = append(bodies, data)
- bytes += len(data)
- }
- }
- return bodies
-}
-
-func handleGetReceipts(backend Backend, msg Decoder, peer *Peer) error {
- // Decode the block receipts retrieval message
- var query GetReceiptsPacket
- if err := msg.Decode(&query); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- response := ServiceGetReceiptsQuery(backend.Chain(), query.GetReceiptsRequest)
- return peer.ReplyReceiptsRLP(query.RequestId, response)
-}
-
-// ServiceGetReceiptsQuery assembles the response to a receipt query. It is
-// exposed to allow external packages to test protocol behavior.
-func ServiceGetReceiptsQuery(chain *core.BlockChain, query GetReceiptsRequest) []rlp.RawValue {
- // Gather state data until the fetch or network limits is reached
- var (
- bytes int
- receipts []rlp.RawValue
- )
- for lookups, hash := range query {
- if bytes >= softResponseLimit || len(receipts) >= maxReceiptsServe ||
- lookups >= 2*maxReceiptsServe {
- break
- }
- // Retrieve the requested block's receipts
- results := chain.GetReceiptsByHash(hash)
- if results == nil {
- if header := chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
- continue
- }
- }
- // If known, encode and queue for response packet
- if encoded, err := rlp.EncodeToBytes(results); err != nil {
- log.Error("Failed to encode receipt", "err", err)
- } else {
- receipts = append(receipts, encoded)
- bytes += len(encoded)
- }
- }
- return receipts
-}
-
-func handleNewBlockhashes(backend Backend, msg Decoder, peer *Peer) error {
- // A batch of new block announcements just arrived
- ann := new(NewBlockHashesPacket)
- if err := msg.Decode(ann); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- // Mark the hashes as present at the remote node
- for _, block := range *ann {
- peer.markBlock(block.Hash)
- }
- // Deliver them all to the backend for queuing
- return backend.Handle(peer, ann)
-}
-
-func handleNewBlock(backend Backend, msg Decoder, peer *Peer) error {
- // Retrieve and decode the propagated block
- ann := new(NewBlockPacket)
- if err := msg.Decode(ann); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- if err := ann.sanityCheck(); err != nil {
- return err
- }
- if hash := types.CalcUncleHash(ann.Block.Uncles()); hash != ann.Block.UncleHash() {
- log.Warn("Propagated block has invalid uncles", "have", hash, "exp", ann.Block.UncleHash())
- return nil // TODO(karalabe): return error eventually, but wait a few releases
- }
- if hash := types.DeriveSha(ann.Block.Transactions(), trie.NewStackTrie(nil)); hash != ann.Block.TxHash() {
- log.Warn("Propagated block has invalid body", "have", hash, "exp", ann.Block.TxHash())
- return nil // TODO(karalabe): return error eventually, but wait a few releases
- }
- ann.Block.ReceivedAt = msg.Time()
- ann.Block.ReceivedFrom = peer
-
- // Mark the peer as owning the block
- peer.markBlock(ann.Block.Hash())
-
- return backend.Handle(peer, ann)
-}
-
-func handleBlockHeaders(backend Backend, msg Decoder, peer *Peer) error {
- // A batch of headers arrived to one of our previous requests
- res := new(BlockHeadersPacket)
- if err := msg.Decode(res); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- metadata := func() interface{} {
- hashes := make([]common.Hash, len(res.BlockHeadersRequest))
- for i, header := range res.BlockHeadersRequest {
- hashes[i] = header.Hash()
- }
- return hashes
- }
- return peer.dispatchResponse(&Response{
- id: res.RequestId,
- code: BlockHeadersMsg,
- Res: &res.BlockHeadersRequest,
- }, metadata)
-}
-
-func handleBlockBodies(backend Backend, msg Decoder, peer *Peer) error {
- // A batch of block bodies arrived to one of our previous requests
- res := new(BlockBodiesPacket)
- if err := msg.Decode(res); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- metadata := func() interface{} {
- var (
- txsHashes = make([]common.Hash, len(res.BlockBodiesResponse))
- uncleHashes = make([]common.Hash, len(res.BlockBodiesResponse))
- withdrawalHashes = make([]common.Hash, len(res.BlockBodiesResponse))
- )
- hasher := trie.NewStackTrie(nil)
- for i, body := range res.BlockBodiesResponse {
- txsHashes[i] = types.DeriveSha(types.Transactions(body.Transactions), hasher)
- uncleHashes[i] = types.CalcUncleHash(body.Uncles)
- if body.Withdrawals != nil {
- withdrawalHashes[i] = types.DeriveSha(types.Withdrawals(body.Withdrawals), hasher)
- }
- }
- return [][]common.Hash{txsHashes, uncleHashes, withdrawalHashes}
- }
- return peer.dispatchResponse(&Response{
- id: res.RequestId,
- code: BlockBodiesMsg,
- Res: &res.BlockBodiesResponse,
- }, metadata)
-}
-
-func handleReceipts(backend Backend, msg Decoder, peer *Peer) error {
- // A batch of receipts arrived to one of our previous requests
- res := new(ReceiptsPacket)
- if err := msg.Decode(res); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- metadata := func() interface{} {
- hasher := trie.NewStackTrie(nil)
- hashes := make([]common.Hash, len(res.ReceiptsResponse))
- for i, receipt := range res.ReceiptsResponse {
- hashes[i] = types.DeriveSha(types.Receipts(receipt), hasher)
- }
- return hashes
- }
- return peer.dispatchResponse(&Response{
- id: res.RequestId,
- code: ReceiptsMsg,
- Res: &res.ReceiptsResponse,
- }, metadata)
-}
-
-func handleNewPooledTransactionHashes67(backend Backend, msg Decoder, peer *Peer) error {
- // New transaction announcement arrived, make sure we have
- // a valid and fresh chain to handle them
- if !backend.AcceptTxs() {
- return nil
- }
- ann := new(NewPooledTransactionHashesPacket67)
- if err := msg.Decode(ann); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- // Schedule all the unknown hashes for retrieval
- for _, hash := range *ann {
- peer.markTransaction(hash)
- }
- return backend.Handle(peer, ann)
-}
-
-func handleNewPooledTransactionHashes68(backend Backend, msg Decoder, peer *Peer) error {
- // New transaction announcement arrived, make sure we have
- // a valid and fresh chain to handle them
- if !backend.AcceptTxs() {
- return nil
- }
- ann := new(NewPooledTransactionHashesPacket68)
- if err := msg.Decode(ann); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- if len(ann.Hashes) != len(ann.Types) || len(ann.Hashes) != len(ann.Sizes) {
- return fmt.Errorf("%w: message %v: invalid len of fields: %v %v %v", errDecode, msg, len(ann.Hashes), len(ann.Types), len(ann.Sizes))
- }
- // Schedule all the unknown hashes for retrieval
- for _, hash := range ann.Hashes {
- peer.markTransaction(hash)
- }
- return backend.Handle(peer, ann)
-}
-
-func handleGetPooledTransactions(backend Backend, msg Decoder, peer *Peer) error {
- // Decode the pooled transactions retrieval message
- var query GetPooledTransactionsPacket
- if err := msg.Decode(&query); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- hashes, txs := answerGetPooledTransactions(backend, query.GetPooledTransactionsRequest)
- return peer.ReplyPooledTransactionsRLP(query.RequestId, hashes, txs)
-}
-
-func answerGetPooledTransactions(backend Backend, query GetPooledTransactionsRequest) ([]common.Hash, []rlp.RawValue) {
- // Gather transactions until the fetch or network limits is reached
- var (
- bytes int
- hashes []common.Hash
- txs []rlp.RawValue
- )
- for _, hash := range query {
- if bytes >= softResponseLimit {
- break
- }
- // Retrieve the requested transaction, skipping if unknown to us
- tx := backend.TxPool().Get(hash)
- if tx == nil {
- continue
- }
- // If known, encode and queue for response packet
- if encoded, err := rlp.EncodeToBytes(tx); err != nil {
- log.Error("Failed to encode transaction", "err", err)
- } else {
- hashes = append(hashes, hash)
- txs = append(txs, encoded)
- bytes += len(encoded)
- }
- }
- return hashes, txs
-}
-
-func handleTransactions(backend Backend, msg Decoder, peer *Peer) error {
- // Transactions arrived, make sure we have a valid and fresh chain to handle them
- if !backend.AcceptTxs() {
- return nil
- }
- // Transactions can be processed, parse all of them and deliver to the pool
- var txs TransactionsPacket
- if err := msg.Decode(&txs); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- for i, tx := range txs {
- // Validate and mark the remote transaction
- if tx == nil {
- return fmt.Errorf("%w: transaction %d is nil", errDecode, i)
- }
- peer.markTransaction(tx.Hash())
- }
- return backend.Handle(peer, &txs)
-}
-
-func handlePooledTransactions(backend Backend, msg Decoder, peer *Peer) error {
- // Transactions arrived, make sure we have a valid and fresh chain to handle them
- if !backend.AcceptTxs() {
- return nil
- }
- // Transactions can be processed, parse all of them and deliver to the pool
- var txs PooledTransactionsPacket
- if err := msg.Decode(&txs); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- for i, tx := range txs.PooledTransactionsResponse {
- // Validate and mark the remote transaction
- if tx == nil {
- return fmt.Errorf("%w: transaction %d is nil", errDecode, i)
- }
- peer.markTransaction(tx.Hash())
- }
- requestTracker.Fulfil(peer.id, peer.version, PooledTransactionsMsg, txs.RequestId)
-
- return backend.Handle(peer, &txs.PooledTransactionsResponse)
-}
diff --git a/eth/protocols/eth/handshake.go b/eth/protocols/eth/handshake.go
deleted file mode 100644
index ea16a85b1e..0000000000
--- a/eth/protocols/eth/handshake.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "errors"
- "fmt"
- "math/big"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/forkid"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/p2p"
-)
-
-const (
- // handshakeTimeout is the maximum allowed time for the `eth` handshake to
- // complete before dropping the connection.= as malicious.
- handshakeTimeout = 5 * time.Second
-)
-
-// Handshake executes the eth protocol handshake, negotiating version number,
-// network IDs, difficulties, head and genesis blocks.
-func (p *Peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis common.Hash, forkID forkid.ID, forkFilter forkid.Filter) error {
- // Send out own handshake in a new thread
- errc := make(chan error, 2)
-
- var status StatusPacket // safe to read after two values have been received from errc
-
- go func() {
- errc <- p2p.Send(p.rw, StatusMsg, &StatusPacket{
- ProtocolVersion: uint32(p.version),
- NetworkID: network,
- TD: td,
- Head: head,
- Genesis: genesis,
- ForkID: forkID,
- })
- }()
- go func() {
- errc <- p.readStatus(network, &status, genesis, forkFilter)
- }()
- timeout := time.NewTimer(handshakeTimeout)
- defer timeout.Stop()
- for i := 0; i < 2; i++ {
- select {
- case err := <-errc:
- if err != nil {
- markError(p, err)
- return err
- }
- case <-timeout.C:
- markError(p, p2p.DiscReadTimeout)
- return p2p.DiscReadTimeout
- }
- }
- p.td, p.head = status.TD, status.Head
-
- // TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times
- // larger, it will still fit within 100 bits
- if tdlen := p.td.BitLen(); tdlen > 100 {
- return fmt.Errorf("too large total difficulty: bitlen %d", tdlen)
- }
- return nil
-}
-
-// readStatus reads the remote handshake message.
-func (p *Peer) readStatus(network uint64, status *StatusPacket, genesis common.Hash, forkFilter forkid.Filter) error {
- msg, err := p.rw.ReadMsg()
- if err != nil {
- return err
- }
- if msg.Code != StatusMsg {
- return fmt.Errorf("%w: first msg has code %x (!= %x)", errNoStatusMsg, msg.Code, StatusMsg)
- }
- if msg.Size > maxMessageSize {
- return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize)
- }
- // Decode the handshake and make sure everything matches
- if err := msg.Decode(&status); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- if status.NetworkID != network {
- return fmt.Errorf("%w: %d (!= %d)", errNetworkIDMismatch, status.NetworkID, network)
- }
- if uint(status.ProtocolVersion) != p.version {
- return fmt.Errorf("%w: %d (!= %d)", errProtocolVersionMismatch, status.ProtocolVersion, p.version)
- }
- if status.Genesis != genesis {
- return fmt.Errorf("%w: %x (!= %x)", errGenesisMismatch, status.Genesis, genesis)
- }
- if err := forkFilter(status.ForkID); err != nil {
- return fmt.Errorf("%w: %v", errForkIDRejected, err)
- }
- return nil
-}
-
-// markError registers the error with the corresponding metric.
-func markError(p *Peer, err error) {
- if !metrics.Enabled {
- return
- }
- m := meters.get(p.Inbound())
- switch errors.Unwrap(err) {
- case errNetworkIDMismatch:
- m.networkIDMismatch.Mark(1)
- case errProtocolVersionMismatch:
- m.protocolVersionMismatch.Mark(1)
- case errGenesisMismatch:
- m.genesisMismatch.Mark(1)
- case errForkIDRejected:
- m.forkidRejected.Mark(1)
- case p2p.DiscReadTimeout:
- m.timeoutError.Mark(1)
- default:
- m.peerError.Mark(1)
- }
-}
diff --git a/eth/protocols/eth/handshake_test.go b/eth/protocols/eth/handshake_test.go
deleted file mode 100644
index d96cfc8165..0000000000
--- a/eth/protocols/eth/handshake_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "errors"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/forkid"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
-)
-
-// Tests that handshake failures are detected and reported correctly.
-func TestHandshake67(t *testing.T) { testHandshake(t, ETH67) }
-func TestHandshake68(t *testing.T) { testHandshake(t, ETH68) }
-
-func testHandshake(t *testing.T, protocol uint) {
- t.Parallel()
-
- // Create a test backend only to have some valid genesis chain
- backend := newTestBackend(3)
- defer backend.close()
-
- var (
- genesis = backend.chain.Genesis()
- head = backend.chain.CurrentBlock()
- td = backend.chain.GetTd(head.Hash(), head.Number.Uint64())
- forkID = forkid.NewID(backend.chain.Config(), backend.chain.Genesis(), backend.chain.CurrentHeader().Number.Uint64(), backend.chain.CurrentHeader().Time)
- )
- tests := []struct {
- code uint64
- data interface{}
- want error
- }{
- {
- code: TransactionsMsg, data: []interface{}{},
- want: errNoStatusMsg,
- },
- {
- code: StatusMsg, data: StatusPacket{10, 1, td, head.Hash(), genesis.Hash(), forkID},
- want: errProtocolVersionMismatch,
- },
- {
- code: StatusMsg, data: StatusPacket{uint32(protocol), 999, td, head.Hash(), genesis.Hash(), forkID},
- want: errNetworkIDMismatch,
- },
- {
- code: StatusMsg, data: StatusPacket{uint32(protocol), 1, td, head.Hash(), common.Hash{3}, forkID},
- want: errGenesisMismatch,
- },
- {
- code: StatusMsg, data: StatusPacket{uint32(protocol), 1, td, head.Hash(), genesis.Hash(), forkid.ID{Hash: [4]byte{0x00, 0x01, 0x02, 0x03}}},
- want: errForkIDRejected,
- },
- }
- for i, test := range tests {
- // Create the two peers to shake with each other
- app, net := p2p.MsgPipe()
- defer app.Close()
- defer net.Close()
-
- peer := NewPeer(protocol, p2p.NewPeer(enode.ID{}, "peer", nil), net, nil)
- defer peer.Close()
-
- // Send the junk test with one peer, check the handshake failure
- go p2p.Send(app, test.code, test.data)
-
- err := peer.Handshake(1, td, head.Hash(), genesis.Hash(), forkID, forkid.NewFilter(backend.chain))
- if err == nil {
- t.Errorf("test %d: protocol returned nil error, want %q", i, test.want)
- } else if !errors.Is(err, test.want) {
- t.Errorf("test %d: wrong error: got %q, want %q", i, err, test.want)
- }
- }
-}
diff --git a/eth/protocols/eth/metrics.go b/eth/protocols/eth/metrics.go
deleted file mode 100644
index 5e0aee39f8..0000000000
--- a/eth/protocols/eth/metrics.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2023 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 eth
-
-import "github.com/ethereum/go-ethereum/metrics"
-
-// meters stores ingress and egress handshake meters.
-var meters bidirectionalMeters
-
-// bidirectionalMeters stores ingress and egress handshake meters.
-type bidirectionalMeters struct {
- ingress *hsMeters
- egress *hsMeters
-}
-
-// get returns the corresponding meter depending if ingress or egress is
-// desired.
-func (h *bidirectionalMeters) get(ingress bool) *hsMeters {
- if ingress {
- return h.ingress
- }
- return h.egress
-}
-
-// hsMeters is a collection of meters which track metrics related to the
-// eth subprotocol handshake.
-type hsMeters struct {
- // peerError measures the number of errors related to incorrect peer
- // behaviour, such as invalid message code, size, encoding, etc.
- peerError metrics.Meter
-
- // timeoutError measures the number of timeouts.
- timeoutError metrics.Meter
-
- // networkIDMismatch measures the number of network id mismatch errors.
- networkIDMismatch metrics.Meter
-
- // protocolVersionMismatch measures the number of differing protocol
- // versions.
- protocolVersionMismatch metrics.Meter
-
- // genesisMismatch measures the number of differing genesises.
- genesisMismatch metrics.Meter
-
- // forkidRejected measures the number of differing forkids.
- forkidRejected metrics.Meter
-}
-
-// newHandshakeMeters registers and returns handshake meters for the given
-// base.
-func newHandshakeMeters(base string) *hsMeters {
- return &hsMeters{
- peerError: metrics.NewRegisteredMeter(base+"error/peer", nil),
- timeoutError: metrics.NewRegisteredMeter(base+"error/timeout", nil),
- networkIDMismatch: metrics.NewRegisteredMeter(base+"error/network", nil),
- protocolVersionMismatch: metrics.NewRegisteredMeter(base+"error/version", nil),
- genesisMismatch: metrics.NewRegisteredMeter(base+"error/genesis", nil),
- forkidRejected: metrics.NewRegisteredMeter(base+"error/forkid", nil),
- }
-}
-
-func init() {
- meters = bidirectionalMeters{
- ingress: newHandshakeMeters("eth/protocols/eth/ingress/handshake/"),
- egress: newHandshakeMeters("eth/protocols/eth/egress/handshake/"),
- }
-}
diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go
deleted file mode 100644
index 98ad22a8cf..0000000000
--- a/eth/protocols/eth/peer.go
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "math/big"
- "math/rand"
- "sync"
-
- mapset "github.com/deckarep/golang-set/v2"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-const (
- // maxKnownTxs is the maximum transactions hashes to keep in the known list
- // before starting to randomly evict them.
- maxKnownTxs = 32768
-
- // maxKnownBlocks is the maximum block hashes to keep in the known list
- // before starting to randomly evict them.
- maxKnownBlocks = 1024
-
- // maxQueuedTxs is the maximum number of transactions to queue up before dropping
- // older broadcasts.
- maxQueuedTxs = 4096
-
- // maxQueuedTxAnns is the maximum number of transaction announcements to queue up
- // before dropping older announcements.
- maxQueuedTxAnns = 4096
-
- // maxQueuedBlocks is the maximum number of block propagations to queue up before
- // dropping broadcasts. There's not much point in queueing stale blocks, so a few
- // that might cover uncles should be enough.
- maxQueuedBlocks = 4
-
- // maxQueuedBlockAnns is the maximum number of block announcements to queue up before
- // dropping broadcasts. Similarly to block propagations, there's no point to queue
- // above some healthy uncle limit, so use that.
- maxQueuedBlockAnns = 4
-)
-
-// max is a helper function which returns the larger of the two given integers.
-func max(a, b int) int {
- if a > b {
- return a
- }
- return b
-}
-
-// Peer is a collection of relevant information we have about a `eth` peer.
-type Peer struct {
- id string // Unique ID for the peer, cached
-
- *p2p.Peer // The embedded P2P package peer
- rw p2p.MsgReadWriter // Input/output streams for snap
- version uint // Protocol version negotiated
-
- head common.Hash // Latest advertised head block hash
- td *big.Int // Latest advertised head block total difficulty
-
- knownBlocks *knownCache // Set of block hashes known to be known by this peer
- queuedBlocks chan *blockPropagation // Queue of blocks to broadcast to the peer
- queuedBlockAnns chan *types.Block // Queue of blocks to announce to the peer
-
- txpool TxPool // Transaction pool used by the broadcasters for liveness checks
- knownTxs *knownCache // Set of transaction hashes known to be known by this peer
- txBroadcast chan []common.Hash // Channel used to queue transaction propagation requests
- txAnnounce chan []common.Hash // Channel used to queue transaction announcement requests
-
- reqDispatch chan *request // Dispatch channel to send requests and track then until fulfillment
- reqCancel chan *cancel // Dispatch channel to cancel pending requests and untrack them
- resDispatch chan *response // Dispatch channel to fulfil pending requests and untrack them
-
- term chan struct{} // Termination channel to stop the broadcasters
- lock sync.RWMutex // Mutex protecting the internal fields
-}
-
-// NewPeer create a wrapper for a network connection and negotiated protocol
-// version.
-func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, txpool TxPool) *Peer {
- peer := &Peer{
- id: p.ID().String(),
- Peer: p,
- rw: rw,
- version: version,
- knownTxs: newKnownCache(maxKnownTxs),
- knownBlocks: newKnownCache(maxKnownBlocks),
- queuedBlocks: make(chan *blockPropagation, maxQueuedBlocks),
- queuedBlockAnns: make(chan *types.Block, maxQueuedBlockAnns),
- txBroadcast: make(chan []common.Hash),
- txAnnounce: make(chan []common.Hash),
- reqDispatch: make(chan *request),
- reqCancel: make(chan *cancel),
- resDispatch: make(chan *response),
- txpool: txpool,
- term: make(chan struct{}),
- }
- // Start up all the broadcasters
- go peer.broadcastBlocks()
- go peer.broadcastTransactions()
- go peer.announceTransactions()
- go peer.dispatcher()
-
- return peer
-}
-
-// Close signals the broadcast goroutine to terminate. Only ever call this if
-// you created the peer yourself via NewPeer. Otherwise let whoever created it
-// clean it up!
-func (p *Peer) Close() {
- close(p.term)
-}
-
-// ID retrieves the peer's unique identifier.
-func (p *Peer) ID() string {
- return p.id
-}
-
-// Version retrieves the peer's negotiated `eth` protocol version.
-func (p *Peer) Version() uint {
- return p.version
-}
-
-// Head retrieves the current head hash and total difficulty of the peer.
-func (p *Peer) Head() (hash common.Hash, td *big.Int) {
- p.lock.RLock()
- defer p.lock.RUnlock()
-
- copy(hash[:], p.head[:])
- return hash, new(big.Int).Set(p.td)
-}
-
-// SetHead updates the head hash and total difficulty of the peer.
-func (p *Peer) SetHead(hash common.Hash, td *big.Int) {
- p.lock.Lock()
- defer p.lock.Unlock()
-
- copy(p.head[:], hash[:])
- p.td.Set(td)
-}
-
-// KnownBlock returns whether peer is known to already have a block.
-func (p *Peer) KnownBlock(hash common.Hash) bool {
- return p.knownBlocks.Contains(hash)
-}
-
-// KnownTransaction returns whether peer is known to already have a transaction.
-func (p *Peer) KnownTransaction(hash common.Hash) bool {
- return p.knownTxs.Contains(hash)
-}
-
-// markBlock marks a block as known for the peer, ensuring that the block will
-// never be propagated to this particular peer.
-func (p *Peer) markBlock(hash common.Hash) {
- // If we reached the memory allowance, drop a previously known block hash
- p.knownBlocks.Add(hash)
-}
-
-// markTransaction marks a transaction as known for the peer, ensuring that it
-// will never be propagated to this particular peer.
-func (p *Peer) markTransaction(hash common.Hash) {
- // If we reached the memory allowance, drop a previously known transaction hash
- p.knownTxs.Add(hash)
-}
-
-// SendTransactions sends transactions to the peer and includes the hashes
-// in its transaction hash set for future reference.
-//
-// This method is a helper used by the async transaction sender. Don't call it
-// directly as the queueing (memory) and transmission (bandwidth) costs should
-// not be managed directly.
-//
-// The reasons this is public is to allow packages using this protocol to write
-// tests that directly send messages without having to do the async queueing.
-func (p *Peer) SendTransactions(txs types.Transactions) error {
- // Mark all the transactions as known, but ensure we don't overflow our limits
- for _, tx := range txs {
- p.knownTxs.Add(tx.Hash())
- }
- return p2p.Send(p.rw, TransactionsMsg, txs)
-}
-
-// AsyncSendTransactions queues a list of transactions (by hash) to eventually
-// propagate to a remote peer. The number of pending sends are capped (new ones
-// will force old sends to be dropped)
-func (p *Peer) AsyncSendTransactions(hashes []common.Hash) {
- select {
- case p.txBroadcast <- hashes:
- // Mark all the transactions as known, but ensure we don't overflow our limits
- p.knownTxs.Add(hashes...)
- case <-p.term:
- p.Log().Debug("Dropping transaction propagation", "count", len(hashes))
- }
-}
-
-// sendPooledTransactionHashes66 sends transaction hashes to the peer and includes
-// them in its transaction hash set for future reference.
-//
-// This method is a helper used by the async transaction announcer. Don't call it
-// directly as the queueing (memory) and transmission (bandwidth) costs should
-// not be managed directly.
-func (p *Peer) sendPooledTransactionHashes66(hashes []common.Hash) error {
- // Mark all the transactions as known, but ensure we don't overflow our limits
- p.knownTxs.Add(hashes...)
- return p2p.Send(p.rw, NewPooledTransactionHashesMsg, NewPooledTransactionHashesPacket67(hashes))
-}
-
-// sendPooledTransactionHashes68 sends transaction hashes (tagged with their type
-// and size) to the peer and includes them in its transaction hash set for future
-// reference.
-//
-// This method is a helper used by the async transaction announcer. Don't call it
-// directly as the queueing (memory) and transmission (bandwidth) costs should
-// not be managed directly.
-func (p *Peer) sendPooledTransactionHashes68(hashes []common.Hash, types []byte, sizes []uint32) error {
- // Mark all the transactions as known, but ensure we don't overflow our limits
- p.knownTxs.Add(hashes...)
- return p2p.Send(p.rw, NewPooledTransactionHashesMsg, NewPooledTransactionHashesPacket68{Types: types, Sizes: sizes, Hashes: hashes})
-}
-
-// AsyncSendPooledTransactionHashes queues a list of transactions hashes to eventually
-// announce to a remote peer. The number of pending sends are capped (new ones
-// will force old sends to be dropped)
-func (p *Peer) AsyncSendPooledTransactionHashes(hashes []common.Hash) {
- select {
- case p.txAnnounce <- hashes:
- // Mark all the transactions as known, but ensure we don't overflow our limits
- p.knownTxs.Add(hashes...)
- case <-p.term:
- p.Log().Debug("Dropping transaction announcement", "count", len(hashes))
- }
-}
-
-// ReplyPooledTransactionsRLP is the response to RequestTxs.
-func (p *Peer) ReplyPooledTransactionsRLP(id uint64, hashes []common.Hash, txs []rlp.RawValue) error {
- // Mark all the transactions as known, but ensure we don't overflow our limits
- p.knownTxs.Add(hashes...)
-
- // Not packed into PooledTransactionsResponse to avoid RLP decoding
- return p2p.Send(p.rw, PooledTransactionsMsg, &PooledTransactionsRLPPacket{
- RequestId: id,
- PooledTransactionsRLPResponse: txs,
- })
-}
-
-// SendNewBlockHashes announces the availability of a number of blocks through
-// a hash notification.
-func (p *Peer) SendNewBlockHashes(hashes []common.Hash, numbers []uint64) error {
- // Mark all the block hashes as known, but ensure we don't overflow our limits
- p.knownBlocks.Add(hashes...)
-
- request := make(NewBlockHashesPacket, len(hashes))
- for i := 0; i < len(hashes); i++ {
- request[i].Hash = hashes[i]
- request[i].Number = numbers[i]
- }
- return p2p.Send(p.rw, NewBlockHashesMsg, request)
-}
-
-// AsyncSendNewBlockHash queues the availability of a block for propagation to a
-// remote peer. If the peer's broadcast queue is full, the event is silently
-// dropped.
-func (p *Peer) AsyncSendNewBlockHash(block *types.Block) {
- select {
- case p.queuedBlockAnns <- block:
- // Mark all the block hash as known, but ensure we don't overflow our limits
- p.knownBlocks.Add(block.Hash())
- default:
- p.Log().Debug("Dropping block announcement", "number", block.NumberU64(), "hash", block.Hash())
- }
-}
-
-// SendNewBlock propagates an entire block to a remote peer.
-func (p *Peer) SendNewBlock(block *types.Block, td *big.Int) error {
- // Mark all the block hash as known, but ensure we don't overflow our limits
- p.knownBlocks.Add(block.Hash())
- return p2p.Send(p.rw, NewBlockMsg, &NewBlockPacket{
- Block: block,
- TD: td,
- })
-}
-
-// AsyncSendNewBlock queues an entire block for propagation to a remote peer. If
-// the peer's broadcast queue is full, the event is silently dropped.
-func (p *Peer) AsyncSendNewBlock(block *types.Block, td *big.Int) {
- select {
- case p.queuedBlocks <- &blockPropagation{block: block, td: td}:
- // Mark all the block hash as known, but ensure we don't overflow our limits
- p.knownBlocks.Add(block.Hash())
- default:
- p.Log().Debug("Dropping block propagation", "number", block.NumberU64(), "hash", block.Hash())
- }
-}
-
-// ReplyBlockHeadersRLP is the response to GetBlockHeaders.
-func (p *Peer) ReplyBlockHeadersRLP(id uint64, headers []rlp.RawValue) error {
- return p2p.Send(p.rw, BlockHeadersMsg, &BlockHeadersRLPPacket{
- RequestId: id,
- BlockHeadersRLPResponse: headers,
- })
-}
-
-// ReplyBlockBodiesRLP is the response to GetBlockBodies.
-func (p *Peer) ReplyBlockBodiesRLP(id uint64, bodies []rlp.RawValue) error {
- // Not packed into BlockBodiesResponse to avoid RLP decoding
- return p2p.Send(p.rw, BlockBodiesMsg, &BlockBodiesRLPPacket{
- RequestId: id,
- BlockBodiesRLPResponse: bodies,
- })
-}
-
-// ReplyReceiptsRLP is the response to GetReceipts.
-func (p *Peer) ReplyReceiptsRLP(id uint64, receipts []rlp.RawValue) error {
- return p2p.Send(p.rw, ReceiptsMsg, &ReceiptsRLPPacket{
- RequestId: id,
- ReceiptsRLPResponse: receipts,
- })
-}
-
-// RequestOneHeader is a wrapper around the header query functions to fetch a
-// single header. It is used solely by the fetcher.
-func (p *Peer) RequestOneHeader(hash common.Hash, sink chan *Response) (*Request, error) {
- p.Log().Debug("Fetching single header", "hash", hash)
- id := rand.Uint64()
-
- req := &Request{
- id: id,
- sink: sink,
- code: GetBlockHeadersMsg,
- want: BlockHeadersMsg,
- data: &GetBlockHeadersPacket{
- RequestId: id,
- GetBlockHeadersRequest: &GetBlockHeadersRequest{
- Origin: HashOrNumber{Hash: hash},
- Amount: uint64(1),
- Skip: uint64(0),
- Reverse: false,
- },
- },
- }
- if err := p.dispatchRequest(req); err != nil {
- return nil, err
- }
- return req, nil
-}
-
-// RequestHeadersByHash fetches a batch of blocks' headers corresponding to the
-// specified header query, based on the hash of an origin block.
-func (p *Peer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool, sink chan *Response) (*Request, error) {
- p.Log().Debug("Fetching batch of headers", "count", amount, "fromhash", origin, "skip", skip, "reverse", reverse)
- id := rand.Uint64()
-
- req := &Request{
- id: id,
- sink: sink,
- code: GetBlockHeadersMsg,
- want: BlockHeadersMsg,
- data: &GetBlockHeadersPacket{
- RequestId: id,
- GetBlockHeadersRequest: &GetBlockHeadersRequest{
- Origin: HashOrNumber{Hash: origin},
- Amount: uint64(amount),
- Skip: uint64(skip),
- Reverse: reverse,
- },
- },
- }
- if err := p.dispatchRequest(req); err != nil {
- return nil, err
- }
- return req, nil
-}
-
-// RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the
-// specified header query, based on the number of an origin block.
-func (p *Peer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool, sink chan *Response) (*Request, error) {
- p.Log().Debug("Fetching batch of headers", "count", amount, "fromnum", origin, "skip", skip, "reverse", reverse)
- id := rand.Uint64()
-
- req := &Request{
- id: id,
- sink: sink,
- code: GetBlockHeadersMsg,
- want: BlockHeadersMsg,
- data: &GetBlockHeadersPacket{
- RequestId: id,
- GetBlockHeadersRequest: &GetBlockHeadersRequest{
- Origin: HashOrNumber{Number: origin},
- Amount: uint64(amount),
- Skip: uint64(skip),
- Reverse: reverse,
- },
- },
- }
- if err := p.dispatchRequest(req); err != nil {
- return nil, err
- }
- return req, nil
-}
-
-// RequestBodies fetches a batch of blocks' bodies corresponding to the hashes
-// specified.
-func (p *Peer) RequestBodies(hashes []common.Hash, sink chan *Response) (*Request, error) {
- p.Log().Debug("Fetching batch of block bodies", "count", len(hashes))
- id := rand.Uint64()
-
- req := &Request{
- id: id,
- sink: sink,
- code: GetBlockBodiesMsg,
- want: BlockBodiesMsg,
- data: &GetBlockBodiesPacket{
- RequestId: id,
- GetBlockBodiesRequest: hashes,
- },
- }
- if err := p.dispatchRequest(req); err != nil {
- return nil, err
- }
- return req, nil
-}
-
-// RequestReceipts fetches a batch of transaction receipts from a remote node.
-func (p *Peer) RequestReceipts(hashes []common.Hash, sink chan *Response) (*Request, error) {
- p.Log().Debug("Fetching batch of receipts", "count", len(hashes))
- id := rand.Uint64()
-
- req := &Request{
- id: id,
- sink: sink,
- code: GetReceiptsMsg,
- want: ReceiptsMsg,
- data: &GetReceiptsPacket{
- RequestId: id,
- GetReceiptsRequest: hashes,
- },
- }
- if err := p.dispatchRequest(req); err != nil {
- return nil, err
- }
- return req, nil
-}
-
-// RequestTxs fetches a batch of transactions from a remote node.
-func (p *Peer) RequestTxs(hashes []common.Hash) error {
- p.Log().Debug("Fetching batch of transactions", "count", len(hashes))
- id := rand.Uint64()
-
- requestTracker.Track(p.id, p.version, GetPooledTransactionsMsg, PooledTransactionsMsg, id)
- return p2p.Send(p.rw, GetPooledTransactionsMsg, &GetPooledTransactionsPacket{
- RequestId: id,
- GetPooledTransactionsRequest: hashes,
- })
-}
-
-// knownCache is a cache for known hashes.
-type knownCache struct {
- hashes mapset.Set[common.Hash]
- max int
-}
-
-// newKnownCache creates a new knownCache with a max capacity.
-func newKnownCache(max int) *knownCache {
- return &knownCache{
- max: max,
- hashes: mapset.NewSet[common.Hash](),
- }
-}
-
-// Add adds a list of elements to the set.
-func (k *knownCache) Add(hashes ...common.Hash) {
- for k.hashes.Cardinality() > max(0, k.max-len(hashes)) {
- k.hashes.Pop()
- }
- for _, hash := range hashes {
- k.hashes.Add(hash)
- }
-}
-
-// Contains returns whether the given item is in the set.
-func (k *knownCache) Contains(hash common.Hash) bool {
- return k.hashes.Contains(hash)
-}
-
-// Cardinality returns the number of elements in the set.
-func (k *knownCache) Cardinality() int {
- return k.hashes.Cardinality()
-}
diff --git a/eth/protocols/eth/peer_test.go b/eth/protocols/eth/peer_test.go
deleted file mode 100644
index efbbbc6fff..0000000000
--- a/eth/protocols/eth/peer_test.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2020 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 .
-
-// This file contains some shares testing functionality, common to multiple
-// different files and modules being tested.
-
-package eth
-
-import (
- "crypto/rand"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
-)
-
-// testPeer is a simulated peer to allow testing direct network calls.
-type testPeer struct {
- *Peer
-
- net p2p.MsgReadWriter // Network layer reader/writer to simulate remote messaging
- app *p2p.MsgPipeRW // Application layer reader/writer to simulate the local side
-}
-
-// newTestPeer creates a new peer registered at the given data backend.
-func newTestPeer(name string, version uint, backend Backend) (*testPeer, <-chan error) {
- // Create a message pipe to communicate through
- app, net := p2p.MsgPipe()
-
- // Start the peer on a new thread
- var id enode.ID
- rand.Read(id[:])
-
- peer := NewPeer(version, p2p.NewPeer(id, name, nil), net, backend.TxPool())
- errc := make(chan error, 1)
- go func() {
- defer app.Close()
-
- errc <- backend.RunPeer(peer, func(peer *Peer) error {
- return Handle(backend, peer)
- })
- }()
- return &testPeer{app: app, net: net, Peer: peer}, errc
-}
-
-// close terminates the local side of the peer, notifying the remote protocol
-// manager of termination.
-func (p *testPeer) close() {
- p.Peer.Close()
- p.app.Close()
-}
-
-func TestPeerSet(t *testing.T) {
- size := 5
- s := newKnownCache(size)
-
- // add 10 items
- for i := 0; i < size*2; i++ {
- s.Add(common.Hash{byte(i)})
- }
-
- if s.Cardinality() != size {
- t.Fatalf("wrong size, expected %d but found %d", size, s.Cardinality())
- }
-
- vals := []common.Hash{}
- for i := 10; i < 20; i++ {
- vals = append(vals, common.Hash{byte(i)})
- }
-
- // add item in batch
- s.Add(vals...)
- if s.Cardinality() < size {
- t.Fatalf("bad size")
- }
-}
diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go
deleted file mode 100644
index 0f44f83de1..0000000000
--- a/eth/protocols/eth/protocol.go
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "errors"
- "fmt"
- "io"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/forkid"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// Constants to match up protocol versions and messages
-const (
- ETH67 = 67
- ETH68 = 68
-)
-
-// ProtocolName is the official short name of the `eth` protocol used during
-// devp2p capability negotiation.
-const ProtocolName = "eth"
-
-// ProtocolVersions are the supported versions of the `eth` protocol (first
-// is primary).
-var ProtocolVersions = []uint{ETH68, ETH67}
-
-// protocolLengths are the number of implemented message corresponding to
-// different protocol versions.
-var protocolLengths = map[uint]uint64{ETH68: 17, ETH67: 17}
-
-// maxMessageSize is the maximum cap on the size of a protocol message.
-const maxMessageSize = 10 * 1024 * 1024
-
-const (
- StatusMsg = 0x00
- NewBlockHashesMsg = 0x01
- TransactionsMsg = 0x02
- GetBlockHeadersMsg = 0x03
- BlockHeadersMsg = 0x04
- GetBlockBodiesMsg = 0x05
- BlockBodiesMsg = 0x06
- NewBlockMsg = 0x07
- NewPooledTransactionHashesMsg = 0x08
- GetPooledTransactionsMsg = 0x09
- PooledTransactionsMsg = 0x0a
- GetReceiptsMsg = 0x0f
- ReceiptsMsg = 0x10
-)
-
-var (
- errNoStatusMsg = errors.New("no status message")
- errMsgTooLarge = errors.New("message too long")
- errDecode = errors.New("invalid message")
- errInvalidMsgCode = errors.New("invalid message code")
- errProtocolVersionMismatch = errors.New("protocol version mismatch")
- errNetworkIDMismatch = errors.New("network ID mismatch")
- errGenesisMismatch = errors.New("genesis mismatch")
- errForkIDRejected = errors.New("fork ID rejected")
-)
-
-// Packet represents a p2p message in the `eth` protocol.
-type Packet interface {
- Name() string // Name returns a string corresponding to the message type.
- Kind() byte // Kind returns the message type.
-}
-
-// StatusPacket is the network packet for the status message.
-type StatusPacket struct {
- ProtocolVersion uint32
- NetworkID uint64
- TD *big.Int
- Head common.Hash
- Genesis common.Hash
- ForkID forkid.ID
-}
-
-// NewBlockHashesPacket is the network packet for the block announcements.
-type NewBlockHashesPacket []struct {
- Hash common.Hash // Hash of one particular block being announced
- Number uint64 // Number of one particular block being announced
-}
-
-// Unpack retrieves the block hashes and numbers from the announcement packet
-// and returns them in a split flat format that's more consistent with the
-// internal data structures.
-func (p *NewBlockHashesPacket) Unpack() ([]common.Hash, []uint64) {
- var (
- hashes = make([]common.Hash, len(*p))
- numbers = make([]uint64, len(*p))
- )
- for i, body := range *p {
- hashes[i], numbers[i] = body.Hash, body.Number
- }
- return hashes, numbers
-}
-
-// TransactionsPacket is the network packet for broadcasting new transactions.
-type TransactionsPacket []*types.Transaction
-
-// GetBlockHeadersRequest represents a block header query.
-type GetBlockHeadersRequest struct {
- Origin HashOrNumber // Block from which to retrieve headers
- Amount uint64 // Maximum number of headers to retrieve
- Skip uint64 // Blocks to skip between consecutive headers
- Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis)
-}
-
-// GetBlockHeadersPacket represents a block header query with request ID wrapping.
-type GetBlockHeadersPacket struct {
- RequestId uint64
- *GetBlockHeadersRequest
-}
-
-// HashOrNumber is a combined field for specifying an origin block.
-type HashOrNumber struct {
- Hash common.Hash // Block hash from which to retrieve headers (excludes Number)
- Number uint64 // Block hash from which to retrieve headers (excludes Hash)
-}
-
-// EncodeRLP is a specialized encoder for HashOrNumber to encode only one of the
-// two contained union fields.
-func (hn *HashOrNumber) EncodeRLP(w io.Writer) error {
- if hn.Hash == (common.Hash{}) {
- return rlp.Encode(w, hn.Number)
- }
- if hn.Number != 0 {
- return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
- }
- return rlp.Encode(w, hn.Hash)
-}
-
-// DecodeRLP is a specialized decoder for HashOrNumber to decode the contents
-// into either a block hash or a block number.
-func (hn *HashOrNumber) DecodeRLP(s *rlp.Stream) error {
- _, size, err := s.Kind()
- switch {
- case err != nil:
- return err
- case size == 32:
- hn.Number = 0
- return s.Decode(&hn.Hash)
- case size <= 8:
- hn.Hash = common.Hash{}
- return s.Decode(&hn.Number)
- default:
- return fmt.Errorf("invalid input size %d for origin", size)
- }
-}
-
-// BlockHeadersRequest represents a block header response.
-type BlockHeadersRequest []*types.Header
-
-// BlockHeadersPacket represents a block header response over with request ID wrapping.
-type BlockHeadersPacket struct {
- RequestId uint64
- BlockHeadersRequest
-}
-
-// BlockHeadersRLPResponse represents a block header response, to use when we already
-// have the headers rlp encoded.
-type BlockHeadersRLPResponse []rlp.RawValue
-
-// BlockHeadersRLPPacket represents a block header response with request ID wrapping.
-type BlockHeadersRLPPacket struct {
- RequestId uint64
- BlockHeadersRLPResponse
-}
-
-// NewBlockPacket is the network packet for the block propagation message.
-type NewBlockPacket struct {
- Block *types.Block
- TD *big.Int
-}
-
-// sanityCheck verifies that the values are reasonable, as a DoS protection
-func (request *NewBlockPacket) sanityCheck() error {
- if err := request.Block.SanityCheck(); err != nil {
- return err
- }
- //TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times
- // larger, it will still fit within 100 bits
- if tdlen := request.TD.BitLen(); tdlen > 100 {
- return fmt.Errorf("too large block TD: bitlen %d", tdlen)
- }
- return nil
-}
-
-// GetBlockBodiesRequest represents a block body query.
-type GetBlockBodiesRequest []common.Hash
-
-// GetBlockBodiesPacket represents a block body query with request ID wrapping.
-type GetBlockBodiesPacket struct {
- RequestId uint64
- GetBlockBodiesRequest
-}
-
-// BlockBodiesResponse is the network packet for block content distribution.
-type BlockBodiesResponse []*BlockBody
-
-// BlockBodiesPacket is the network packet for block content distribution with
-// request ID wrapping.
-type BlockBodiesPacket struct {
- RequestId uint64
- BlockBodiesResponse
-}
-
-// BlockBodiesRLPResponse is used for replying to block body requests, in cases
-// where we already have them RLP-encoded, and thus can avoid the decode-encode
-// roundtrip.
-type BlockBodiesRLPResponse []rlp.RawValue
-
-// BlockBodiesRLPPacket is the BlockBodiesRLPResponse with request ID wrapping.
-type BlockBodiesRLPPacket struct {
- RequestId uint64
- BlockBodiesRLPResponse
-}
-
-// BlockBody represents the data content of a single block.
-type BlockBody struct {
- Transactions []*types.Transaction // Transactions contained within a block
- Uncles []*types.Header // Uncles contained within a block
- Withdrawals []*types.Withdrawal `rlp:"optional"` // Withdrawals contained within a block
-}
-
-// Unpack retrieves the transactions and uncles from the range packet and returns
-// them in a split flat format that's more consistent with the internal data structures.
-func (p *BlockBodiesResponse) Unpack() ([][]*types.Transaction, [][]*types.Header, [][]*types.Withdrawal) {
- // TODO(matt): add support for withdrawals to fetchers
- var (
- txset = make([][]*types.Transaction, len(*p))
- uncleset = make([][]*types.Header, len(*p))
- withdrawalset = make([][]*types.Withdrawal, len(*p))
- )
- for i, body := range *p {
- txset[i], uncleset[i], withdrawalset[i] = body.Transactions, body.Uncles, body.Withdrawals
- }
- return txset, uncleset, withdrawalset
-}
-
-// GetReceiptsRequest represents a block receipts query.
-type GetReceiptsRequest []common.Hash
-
-// GetReceiptsPacket represents a block receipts query with request ID wrapping.
-type GetReceiptsPacket struct {
- RequestId uint64
- GetReceiptsRequest
-}
-
-// ReceiptsResponse is the network packet for block receipts distribution.
-type ReceiptsResponse [][]*types.Receipt
-
-// ReceiptsPacket is the network packet for block receipts distribution with
-// request ID wrapping.
-type ReceiptsPacket struct {
- RequestId uint64
- ReceiptsResponse
-}
-
-// ReceiptsRLPResponse is used for receipts, when we already have it encoded
-type ReceiptsRLPResponse []rlp.RawValue
-
-// ReceiptsRLPPacket is ReceiptsRLPResponse with request ID wrapping.
-type ReceiptsRLPPacket struct {
- RequestId uint64
- ReceiptsRLPResponse
-}
-
-// NewPooledTransactionHashesPacket67 represents a transaction announcement packet on eth/67.
-type NewPooledTransactionHashesPacket67 []common.Hash
-
-// NewPooledTransactionHashesPacket68 represents a transaction announcement packet on eth/68 and newer.
-type NewPooledTransactionHashesPacket68 struct {
- Types []byte
- Sizes []uint32
- Hashes []common.Hash
-}
-
-// GetPooledTransactionsRequest represents a transaction query.
-type GetPooledTransactionsRequest []common.Hash
-
-// GetPooledTransactionsPacket represents a transaction query with request ID wrapping.
-type GetPooledTransactionsPacket struct {
- RequestId uint64
- GetPooledTransactionsRequest
-}
-
-// PooledTransactionsResponse is the network packet for transaction distribution.
-type PooledTransactionsResponse []*types.Transaction
-
-// PooledTransactionsPacket is the network packet for transaction distribution
-// with request ID wrapping.
-type PooledTransactionsPacket struct {
- RequestId uint64
- PooledTransactionsResponse
-}
-
-// PooledTransactionsRLPResponse is the network packet for transaction distribution, used
-// in the cases we already have them in rlp-encoded form
-type PooledTransactionsRLPResponse []rlp.RawValue
-
-// PooledTransactionsRLPPacket is PooledTransactionsRLPResponse with request ID wrapping.
-type PooledTransactionsRLPPacket struct {
- RequestId uint64
- PooledTransactionsRLPResponse
-}
-
-func (*StatusPacket) Name() string { return "Status" }
-func (*StatusPacket) Kind() byte { return StatusMsg }
-
-func (*NewBlockHashesPacket) Name() string { return "NewBlockHashes" }
-func (*NewBlockHashesPacket) Kind() byte { return NewBlockHashesMsg }
-
-func (*TransactionsPacket) Name() string { return "Transactions" }
-func (*TransactionsPacket) Kind() byte { return TransactionsMsg }
-
-func (*GetBlockHeadersRequest) Name() string { return "GetBlockHeaders" }
-func (*GetBlockHeadersRequest) Kind() byte { return GetBlockHeadersMsg }
-
-func (*BlockHeadersRequest) Name() string { return "BlockHeaders" }
-func (*BlockHeadersRequest) Kind() byte { return BlockHeadersMsg }
-
-func (*GetBlockBodiesRequest) Name() string { return "GetBlockBodies" }
-func (*GetBlockBodiesRequest) Kind() byte { return GetBlockBodiesMsg }
-
-func (*BlockBodiesResponse) Name() string { return "BlockBodies" }
-func (*BlockBodiesResponse) Kind() byte { return BlockBodiesMsg }
-
-func (*NewBlockPacket) Name() string { return "NewBlock" }
-func (*NewBlockPacket) Kind() byte { return NewBlockMsg }
-
-func (*NewPooledTransactionHashesPacket67) Name() string { return "NewPooledTransactionHashes" }
-func (*NewPooledTransactionHashesPacket67) Kind() byte { return NewPooledTransactionHashesMsg }
-func (*NewPooledTransactionHashesPacket68) Name() string { return "NewPooledTransactionHashes" }
-func (*NewPooledTransactionHashesPacket68) Kind() byte { return NewPooledTransactionHashesMsg }
-
-func (*GetPooledTransactionsRequest) Name() string { return "GetPooledTransactions" }
-func (*GetPooledTransactionsRequest) Kind() byte { return GetPooledTransactionsMsg }
-
-func (*PooledTransactionsResponse) Name() string { return "PooledTransactions" }
-func (*PooledTransactionsResponse) Kind() byte { return PooledTransactionsMsg }
-
-func (*GetReceiptsRequest) Name() string { return "GetReceipts" }
-func (*GetReceiptsRequest) Kind() byte { return GetReceiptsMsg }
-
-func (*ReceiptsResponse) Name() string { return "Receipts" }
-func (*ReceiptsResponse) Kind() byte { return ReceiptsMsg }
diff --git a/eth/protocols/eth/protocol_test.go b/eth/protocols/eth/protocol_test.go
deleted file mode 100644
index bc2545dea2..0000000000
--- a/eth/protocols/eth/protocol_test.go
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2020 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 eth
-
-import (
- "bytes"
- "math/big"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// Tests that the custom union field encoder and decoder works correctly.
-func TestGetBlockHeadersDataEncodeDecode(t *testing.T) {
- // Create a "random" hash for testing
- var hash common.Hash
- for i := range hash {
- hash[i] = byte(i)
- }
- // Assemble some table driven tests
- tests := []struct {
- packet *GetBlockHeadersRequest
- fail bool
- }{
- // Providing the origin as either a hash or a number should both work
- {fail: false, packet: &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 314}}},
- {fail: false, packet: &GetBlockHeadersRequest{Origin: HashOrNumber{Hash: hash}}},
-
- // Providing arbitrary query field should also work
- {fail: false, packet: &GetBlockHeadersRequest{Origin: HashOrNumber{Number: 314}, Amount: 314, Skip: 1, Reverse: true}},
- {fail: false, packet: &GetBlockHeadersRequest{Origin: HashOrNumber{Hash: hash}, Amount: 314, Skip: 1, Reverse: true}},
-
- // Providing both the origin hash and origin number must fail
- {fail: true, packet: &GetBlockHeadersRequest{Origin: HashOrNumber{Hash: hash, Number: 314}}},
- }
- // Iterate over each of the tests and try to encode and then decode
- for i, tt := range tests {
- bytes, err := rlp.EncodeToBytes(tt.packet)
- if err != nil && !tt.fail {
- t.Fatalf("test %d: failed to encode packet: %v", i, err)
- } else if err == nil && tt.fail {
- t.Fatalf("test %d: encode should have failed", i)
- }
- if !tt.fail {
- packet := new(GetBlockHeadersRequest)
- if err := rlp.DecodeBytes(bytes, packet); err != nil {
- t.Fatalf("test %d: failed to decode packet: %v", i, err)
- }
- if packet.Origin.Hash != tt.packet.Origin.Hash || packet.Origin.Number != tt.packet.Origin.Number || packet.Amount != tt.packet.Amount ||
- packet.Skip != tt.packet.Skip || packet.Reverse != tt.packet.Reverse {
- t.Fatalf("test %d: encode decode mismatch: have %+v, want %+v", i, packet, tt.packet)
- }
- }
- }
-}
-
-// TestEmptyMessages tests encoding of empty messages.
-func TestEmptyMessages(t *testing.T) {
- // All empty messages encodes to the same format
- want := common.FromHex("c4820457c0")
-
- for i, msg := range []interface{}{
- // Headers
- GetBlockHeadersPacket{1111, nil},
- BlockHeadersPacket{1111, nil},
- // Bodies
- GetBlockBodiesPacket{1111, nil},
- BlockBodiesPacket{1111, nil},
- BlockBodiesRLPPacket{1111, nil},
- // Receipts
- GetReceiptsPacket{1111, nil},
- ReceiptsPacket{1111, nil},
- // Transactions
- GetPooledTransactionsPacket{1111, nil},
- PooledTransactionsPacket{1111, nil},
- PooledTransactionsRLPPacket{1111, nil},
-
- // Headers
- BlockHeadersPacket{1111, BlockHeadersRequest([]*types.Header{})},
- // Bodies
- GetBlockBodiesPacket{1111, GetBlockBodiesRequest([]common.Hash{})},
- BlockBodiesPacket{1111, BlockBodiesResponse([]*BlockBody{})},
- BlockBodiesRLPPacket{1111, BlockBodiesRLPResponse([]rlp.RawValue{})},
- // Receipts
- GetReceiptsPacket{1111, GetReceiptsRequest([]common.Hash{})},
- ReceiptsPacket{1111, ReceiptsResponse([][]*types.Receipt{})},
- // Transactions
- GetPooledTransactionsPacket{1111, GetPooledTransactionsRequest([]common.Hash{})},
- PooledTransactionsPacket{1111, PooledTransactionsResponse([]*types.Transaction{})},
- PooledTransactionsRLPPacket{1111, PooledTransactionsRLPResponse([]rlp.RawValue{})},
- } {
- if have, _ := rlp.EncodeToBytes(msg); !bytes.Equal(have, want) {
- t.Errorf("test %d, type %T, have\n\t%x\nwant\n\t%x", i, msg, have, want)
- }
- }
-}
-
-// TestMessages tests the encoding of all messages.
-func TestMessages(t *testing.T) {
- // Some basic structs used during testing
- var (
- header *types.Header
- blockBody *BlockBody
- blockBodyRlp rlp.RawValue
- txs []*types.Transaction
- txRlps []rlp.RawValue
- hashes []common.Hash
- receipts []*types.Receipt
- receiptsRlp rlp.RawValue
-
- err error
- )
- header = &types.Header{
- Difficulty: big.NewInt(2222),
- Number: big.NewInt(3333),
- GasLimit: 4444,
- GasUsed: 5555,
- Time: 6666,
- Extra: []byte{0x77, 0x88},
- }
- // Init the transactions, taken from a different test
- {
- for _, hexrlp := range []string{
- "f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10",
- "f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb",
- } {
- var tx *types.Transaction
- rlpdata := common.FromHex(hexrlp)
- if err := rlp.DecodeBytes(rlpdata, &tx); err != nil {
- t.Fatal(err)
- }
- txs = append(txs, tx)
- txRlps = append(txRlps, rlpdata)
- }
- }
- // init the block body data, both object and rlp form
- blockBody = &BlockBody{
- Transactions: txs,
- Uncles: []*types.Header{header},
- }
- blockBodyRlp, err = rlp.EncodeToBytes(blockBody)
- if err != nil {
- t.Fatal(err)
- }
-
- hashes = []common.Hash{
- common.HexToHash("deadc0de"),
- common.HexToHash("feedbeef"),
- }
- // init the receipts
- {
- receipts = []*types.Receipt{
- {
- Status: types.ReceiptStatusFailed,
- CumulativeGasUsed: 1,
- Logs: []*types.Log{
- {
- Address: common.BytesToAddress([]byte{0x11}),
- Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")},
- Data: []byte{0x01, 0x00, 0xff},
- },
- },
- TxHash: hashes[0],
- ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}),
- GasUsed: 111111,
- },
- }
- rlpData, err := rlp.EncodeToBytes(receipts)
- if err != nil {
- t.Fatal(err)
- }
- receiptsRlp = rlpData
- }
-
- for i, tc := range []struct {
- message interface{}
- want []byte
- }{
- {
- GetBlockHeadersPacket{1111, &GetBlockHeadersRequest{HashOrNumber{hashes[0], 0}, 5, 5, false}},
- common.FromHex("e8820457e4a000000000000000000000000000000000000000000000000000000000deadc0de050580"),
- },
- {
- GetBlockHeadersPacket{1111, &GetBlockHeadersRequest{HashOrNumber{common.Hash{}, 9999}, 5, 5, false}},
- common.FromHex("ca820457c682270f050580"),
- },
- {
- BlockHeadersPacket{1111, BlockHeadersRequest{header}},
- common.FromHex("f90202820457f901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"),
- },
- {
- GetBlockBodiesPacket{1111, GetBlockBodiesRequest(hashes)},
- common.FromHex("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"),
- },
- {
- BlockBodiesPacket{1111, BlockBodiesResponse([]*BlockBody{blockBody})},
- common.FromHex("f902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"),
- },
- { // Identical to non-rlp-shortcut version
- BlockBodiesRLPPacket{1111, BlockBodiesRLPResponse([]rlp.RawValue{blockBodyRlp})},
- common.FromHex("f902dc820457f902d6f902d3f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afbf901fcf901f9a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008208ae820d0582115c8215b3821a0a827788a00000000000000000000000000000000000000000000000000000000000000000880000000000000000"),
- },
- {
- GetReceiptsPacket{1111, GetReceiptsRequest(hashes)},
- common.FromHex("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"),
- },
- {
- ReceiptsPacket{1111, ReceiptsResponse([][]*types.Receipt{receipts})},
- common.FromHex("f90172820457f9016cf90169f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"),
- },
- {
- ReceiptsRLPPacket{1111, ReceiptsRLPResponse([]rlp.RawValue{receiptsRlp})},
- common.FromHex("f90172820457f9016cf90169f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"),
- },
- {
- GetPooledTransactionsPacket{1111, GetPooledTransactionsRequest(hashes)},
- common.FromHex("f847820457f842a000000000000000000000000000000000000000000000000000000000deadc0dea000000000000000000000000000000000000000000000000000000000feedbeef"),
- },
- {
- PooledTransactionsPacket{1111, PooledTransactionsResponse(txs)},
- common.FromHex("f8d7820457f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb"),
- },
- {
- PooledTransactionsRLPPacket{1111, PooledTransactionsRLPResponse(txRlps)},
- common.FromHex("f8d7820457f8d2f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb"),
- },
- } {
- if have, _ := rlp.EncodeToBytes(tc.message); !bytes.Equal(have, tc.want) {
- t.Errorf("test %d, type %T, have\n\t%x\nwant\n\t%x", i, tc.message, have, tc.want)
- }
- }
-}
diff --git a/eth/protocols/eth/tracker.go b/eth/protocols/eth/tracker.go
deleted file mode 100644
index 324fd22839..0000000000
--- a/eth/protocols/eth/tracker.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 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 eth
-
-import (
- "time"
-
- "github.com/ethereum/go-ethereum/p2p/tracker"
-)
-
-// requestTracker is a singleton tracker for eth/66 and newer request times.
-var requestTracker = tracker.New(ProtocolName, 5*time.Minute)
diff --git a/eth/protocols/snap/discovery.go b/eth/protocols/snap/discovery.go
deleted file mode 100644
index 684ec7e632..0000000000
--- a/eth/protocols/snap/discovery.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2020 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 snap
-
-import (
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// enrEntry is the ENR entry which advertises `snap` protocol on the discovery.
-type enrEntry struct {
- // Ignore additional fields (for forward compatibility).
- Rest []rlp.RawValue `rlp:"tail"`
-}
-
-// ENRKey implements enr.Entry.
-func (e enrEntry) ENRKey() string {
- return "snap"
-}
diff --git a/eth/protocols/snap/handler.go b/eth/protocols/snap/handler.go
deleted file mode 100644
index bd7ce9e715..0000000000
--- a/eth/protocols/snap/handler.go
+++ /dev/null
@@ -1,577 +0,0 @@
-// Copyright 2020 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 snap
-
-import (
- "bytes"
- "fmt"
- "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/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
- "github.com/ethereum/go-ethereum/p2p/enr"
- "github.com/ethereum/go-ethereum/trie"
- "github.com/ethereum/go-ethereum/trie/trienode"
-)
-
-const (
- // softResponseLimit is the target maximum size of replies to data retrievals.
- softResponseLimit = 2 * 1024 * 1024
-
- // maxCodeLookups is the maximum number of bytecodes to serve. This number is
- // there to limit the number of disk lookups.
- maxCodeLookups = 1024
-
- // stateLookupSlack defines the ratio by how much a state response can exceed
- // the requested limit in order to try and avoid breaking up contracts into
- // multiple packages and proving them.
- stateLookupSlack = 0.1
-
- // maxTrieNodeLookups is the maximum number of state trie nodes to serve. This
- // number is there to limit the number of disk lookups.
- maxTrieNodeLookups = 1024
-
- // maxTrieNodeTimeSpent is the maximum time we should spend on looking up trie nodes.
- // If we spend too much time, then it's a fairly high chance of timing out
- // at the remote side, which means all the work is in vain.
- maxTrieNodeTimeSpent = 5 * time.Second
-)
-
-// Handler is a callback to invoke from an outside runner after the boilerplate
-// exchanges have passed.
-type Handler func(peer *Peer) error
-
-// Backend defines the data retrieval methods to serve remote requests and the
-// callback methods to invoke on remote deliveries.
-type Backend interface {
- // Chain retrieves the blockchain object to serve data.
- Chain() *core.BlockChain
-
- // RunPeer is invoked when a peer joins on the `eth` protocol. The handler
- // should do any peer maintenance work, handshakes and validations. If all
- // is passed, control should be given back to the `handler` to process the
- // inbound messages going forward.
- RunPeer(peer *Peer, handler Handler) error
-
- // PeerInfo retrieves all known `snap` information about a peer.
- PeerInfo(id enode.ID) interface{}
-
- // Handle is a callback to be invoked when a data packet is received from
- // the remote peer. Only packets not consumed by the protocol handler will
- // be forwarded to the backend.
- Handle(peer *Peer, packet Packet) error
-}
-
-// MakeProtocols constructs the P2P protocol definitions for `snap`.
-func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol {
- // Filter the discovery iterator for nodes advertising snap support.
- dnsdisc = enode.Filter(dnsdisc, func(n *enode.Node) bool {
- var snap enrEntry
- return n.Load(&snap) == nil
- })
-
- protocols := make([]p2p.Protocol, len(ProtocolVersions))
- for i, version := range ProtocolVersions {
- version := version // Closure
-
- protocols[i] = p2p.Protocol{
- Name: ProtocolName,
- Version: version,
- Length: protocolLengths[version],
- Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
- return backend.RunPeer(NewPeer(version, p, rw), func(peer *Peer) error {
- return Handle(backend, peer)
- })
- },
- NodeInfo: func() interface{} {
- return nodeInfo(backend.Chain())
- },
- PeerInfo: func(id enode.ID) interface{} {
- return backend.PeerInfo(id)
- },
- Attributes: []enr.Entry{&enrEntry{}},
- DialCandidates: dnsdisc,
- }
- }
- return protocols
-}
-
-// Handle is the callback invoked to manage the life cycle of a `snap` peer.
-// When this function terminates, the peer is disconnected.
-func Handle(backend Backend, peer *Peer) error {
- for {
- if err := HandleMessage(backend, peer); err != nil {
- peer.Log().Debug("Message handling failed in `snap`", "err", err)
- return err
- }
- }
-}
-
-// HandleMessage is invoked whenever an inbound message is received from a
-// remote peer on the `snap` protocol. The remote connection is torn down upon
-// returning any error.
-func HandleMessage(backend Backend, peer *Peer) error {
- // Read the next message from the remote peer, and ensure it's fully consumed
- msg, err := peer.rw.ReadMsg()
- if err != nil {
- return err
- }
- if msg.Size > maxMessageSize {
- return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize)
- }
- defer msg.Discard()
- start := time.Now()
- // Track the amount of time it takes to serve the request and run the handler
- if metrics.Enabled {
- h := fmt.Sprintf("%s/%s/%d/%#02x", p2p.HandleHistName, ProtocolName, peer.Version(), msg.Code)
- defer func(start time.Time) {
- sampler := func() metrics.Sample {
- return metrics.ResettingSample(
- metrics.NewExpDecaySample(1028, 0.015),
- )
- }
- metrics.GetOrRegisterHistogramLazy(h, nil, sampler).Update(time.Since(start).Microseconds())
- }(start)
- }
- // Handle the message depending on its contents
- switch {
- case msg.Code == GetAccountRangeMsg:
- // Decode the account retrieval request
- var req GetAccountRangePacket
- if err := msg.Decode(&req); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- // Service the request, potentially returning nothing in case of errors
- accounts, proofs := ServiceGetAccountRangeQuery(backend.Chain(), &req)
-
- // Send back anything accumulated (or empty in case of errors)
- return p2p.Send(peer.rw, AccountRangeMsg, &AccountRangePacket{
- ID: req.ID,
- Accounts: accounts,
- Proof: proofs,
- })
-
- case msg.Code == AccountRangeMsg:
- // A range of accounts arrived to one of our previous requests
- res := new(AccountRangePacket)
- if err := msg.Decode(res); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- // Ensure the range is monotonically increasing
- for i := 1; i < len(res.Accounts); i++ {
- if bytes.Compare(res.Accounts[i-1].Hash[:], res.Accounts[i].Hash[:]) >= 0 {
- return fmt.Errorf("accounts not monotonically increasing: #%d [%x] vs #%d [%x]", i-1, res.Accounts[i-1].Hash[:], i, res.Accounts[i].Hash[:])
- }
- }
- requestTracker.Fulfil(peer.id, peer.version, AccountRangeMsg, res.ID)
-
- return backend.Handle(peer, res)
-
- case msg.Code == GetStorageRangesMsg:
- // Decode the storage retrieval request
- var req GetStorageRangesPacket
- if err := msg.Decode(&req); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- // Service the request, potentially returning nothing in case of errors
- slots, proofs := ServiceGetStorageRangesQuery(backend.Chain(), &req)
-
- // Send back anything accumulated (or empty in case of errors)
- return p2p.Send(peer.rw, StorageRangesMsg, &StorageRangesPacket{
- ID: req.ID,
- Slots: slots,
- Proof: proofs,
- })
-
- case msg.Code == StorageRangesMsg:
- // A range of storage slots arrived to one of our previous requests
- res := new(StorageRangesPacket)
- if err := msg.Decode(res); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- // Ensure the ranges are monotonically increasing
- for i, slots := range res.Slots {
- for j := 1; j < len(slots); j++ {
- if bytes.Compare(slots[j-1].Hash[:], slots[j].Hash[:]) >= 0 {
- return fmt.Errorf("storage slots not monotonically increasing for account #%d: #%d [%x] vs #%d [%x]", i, j-1, slots[j-1].Hash[:], j, slots[j].Hash[:])
- }
- }
- }
- requestTracker.Fulfil(peer.id, peer.version, StorageRangesMsg, res.ID)
-
- return backend.Handle(peer, res)
-
- case msg.Code == GetByteCodesMsg:
- // Decode bytecode retrieval request
- var req GetByteCodesPacket
- if err := msg.Decode(&req); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- // Service the request, potentially returning nothing in case of errors
- codes := ServiceGetByteCodesQuery(backend.Chain(), &req)
-
- // Send back anything accumulated (or empty in case of errors)
- return p2p.Send(peer.rw, ByteCodesMsg, &ByteCodesPacket{
- ID: req.ID,
- Codes: codes,
- })
-
- case msg.Code == ByteCodesMsg:
- // A batch of byte codes arrived to one of our previous requests
- res := new(ByteCodesPacket)
- if err := msg.Decode(res); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- requestTracker.Fulfil(peer.id, peer.version, ByteCodesMsg, res.ID)
-
- return backend.Handle(peer, res)
-
- case msg.Code == GetTrieNodesMsg:
- // Decode trie node retrieval request
- var req GetTrieNodesPacket
- if err := msg.Decode(&req); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- // Service the request, potentially returning nothing in case of errors
- nodes, err := ServiceGetTrieNodesQuery(backend.Chain(), &req, start)
- if err != nil {
- return err
- }
- // Send back anything accumulated (or empty in case of errors)
- return p2p.Send(peer.rw, TrieNodesMsg, &TrieNodesPacket{
- ID: req.ID,
- Nodes: nodes,
- })
-
- case msg.Code == TrieNodesMsg:
- // A batch of trie nodes arrived to one of our previous requests
- res := new(TrieNodesPacket)
- if err := msg.Decode(res); err != nil {
- return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
- }
- requestTracker.Fulfil(peer.id, peer.version, TrieNodesMsg, res.ID)
-
- return backend.Handle(peer, res)
-
- default:
- return fmt.Errorf("%w: %v", errInvalidMsgCode, msg.Code)
- }
-}
-
-// ServiceGetAccountRangeQuery assembles the response to an account range query.
-// It is exposed to allow external packages to test protocol behavior.
-func ServiceGetAccountRangeQuery(chain *core.BlockChain, req *GetAccountRangePacket) ([]*AccountData, [][]byte) {
- if req.Bytes > softResponseLimit {
- req.Bytes = softResponseLimit
- }
- // Retrieve the requested state and bail out if non existent
- tr, err := trie.New(trie.StateTrieID(req.Root), chain.TrieDB())
- if err != nil {
- return nil, nil
- }
- it, err := chain.Snapshots().AccountIterator(req.Root, req.Origin)
- if err != nil {
- return nil, nil
- }
- // Iterate over the requested range and pile accounts up
- var (
- accounts []*AccountData
- size uint64
- last common.Hash
- )
- for it.Next() {
- hash, account := it.Hash(), common.CopyBytes(it.Account())
-
- // Track the returned interval for the Merkle proofs
- last = hash
-
- // Assemble the reply item
- size += uint64(common.HashLength + len(account))
- accounts = append(accounts, &AccountData{
- Hash: hash,
- Body: account,
- })
- // If we've exceeded the request threshold, abort
- if bytes.Compare(hash[:], req.Limit[:]) >= 0 {
- break
- }
- if size > req.Bytes {
- break
- }
- }
- it.Release()
-
- // Generate the Merkle proofs for the first and last account
- proof := trienode.NewProofSet()
- if err := tr.Prove(req.Origin[:], proof); err != nil {
- log.Warn("Failed to prove account range", "origin", req.Origin, "err", err)
- return nil, nil
- }
- if last != (common.Hash{}) {
- if err := tr.Prove(last[:], proof); err != nil {
- log.Warn("Failed to prove account range", "last", last, "err", err)
- return nil, nil
- }
- }
- var proofs [][]byte
- for _, blob := range proof.List() {
- proofs = append(proofs, blob)
- }
- return accounts, proofs
-}
-
-func ServiceGetStorageRangesQuery(chain *core.BlockChain, req *GetStorageRangesPacket) ([][]*StorageData, [][]byte) {
- if req.Bytes > softResponseLimit {
- req.Bytes = softResponseLimit
- }
- // TODO(karalabe): Do we want to enforce > 0 accounts and 1 account if origin is set?
- // TODO(karalabe): - Logging locally is not ideal as remote faults annoy the local user
- // TODO(karalabe): - Dropping the remote peer is less flexible wrt client bugs (slow is better than non-functional)
-
- // Calculate the hard limit at which to abort, even if mid storage trie
- hardLimit := uint64(float64(req.Bytes) * (1 + stateLookupSlack))
-
- // Retrieve storage ranges until the packet limit is reached
- var (
- slots [][]*StorageData
- proofs [][]byte
- size uint64
- )
- for _, account := range req.Accounts {
- // If we've exceeded the requested data limit, abort without opening
- // a new storage range (that we'd need to prove due to exceeded size)
- if size >= req.Bytes {
- break
- }
- // The first account might start from a different origin and end sooner
- var origin common.Hash
- if len(req.Origin) > 0 {
- origin, req.Origin = common.BytesToHash(req.Origin), nil
- }
- var limit = common.MaxHash
- if len(req.Limit) > 0 {
- limit, req.Limit = common.BytesToHash(req.Limit), nil
- }
- // Retrieve the requested state and bail out if non existent
- it, err := chain.Snapshots().StorageIterator(req.Root, account, origin)
- if err != nil {
- return nil, nil
- }
- // Iterate over the requested range and pile slots up
- var (
- storage []*StorageData
- last common.Hash
- abort bool
- )
- for it.Next() {
- if size >= hardLimit {
- abort = true
- break
- }
- hash, slot := it.Hash(), common.CopyBytes(it.Slot())
-
- // Track the returned interval for the Merkle proofs
- last = hash
-
- // Assemble the reply item
- size += uint64(common.HashLength + len(slot))
- storage = append(storage, &StorageData{
- Hash: hash,
- Body: slot,
- })
- // If we've exceeded the request threshold, abort
- if bytes.Compare(hash[:], limit[:]) >= 0 {
- break
- }
- }
- if len(storage) > 0 {
- slots = append(slots, storage)
- }
- it.Release()
-
- // Generate the Merkle proofs for the first and last storage slot, but
- // only if the response was capped. If the entire storage trie included
- // in the response, no need for any proofs.
- if origin != (common.Hash{}) || (abort && len(storage) > 0) {
- // Request started at a non-zero hash or was capped prematurely, add
- // the endpoint Merkle proofs
- accTrie, err := trie.NewStateTrie(trie.StateTrieID(req.Root), chain.TrieDB())
- if err != nil {
- return nil, nil
- }
- acc, err := accTrie.GetAccountByHash(account)
- if err != nil || acc == nil {
- return nil, nil
- }
- id := trie.StorageTrieID(req.Root, account, acc.Root)
- stTrie, err := trie.NewStateTrie(id, chain.TrieDB())
- if err != nil {
- return nil, nil
- }
- proof := trienode.NewProofSet()
- if err := stTrie.Prove(origin[:], proof); err != nil {
- log.Warn("Failed to prove storage range", "origin", req.Origin, "err", err)
- return nil, nil
- }
- if last != (common.Hash{}) {
- if err := stTrie.Prove(last[:], proof); err != nil {
- log.Warn("Failed to prove storage range", "last", last, "err", err)
- return nil, nil
- }
- }
- for _, blob := range proof.List() {
- proofs = append(proofs, blob)
- }
- // Proof terminates the reply as proofs are only added if a node
- // refuses to serve more data (exception when a contract fetch is
- // finishing, but that's that).
- break
- }
- }
- return slots, proofs
-}
-
-// ServiceGetByteCodesQuery assembles the response to a byte codes query.
-// It is exposed to allow external packages to test protocol behavior.
-func ServiceGetByteCodesQuery(chain *core.BlockChain, req *GetByteCodesPacket) [][]byte {
- if req.Bytes > softResponseLimit {
- req.Bytes = softResponseLimit
- }
- if len(req.Hashes) > maxCodeLookups {
- req.Hashes = req.Hashes[:maxCodeLookups]
- }
- // Retrieve bytecodes until the packet size limit is reached
- var (
- codes [][]byte
- bytes uint64
- )
- for _, hash := range req.Hashes {
- if hash == types.EmptyCodeHash {
- // Peers should not request the empty code, but if they do, at
- // least sent them back a correct response without db lookups
- codes = append(codes, []byte{})
- } else if blob, err := chain.ContractCodeWithPrefix(hash); err == nil {
- codes = append(codes, blob)
- bytes += uint64(len(blob))
- }
- if bytes > req.Bytes {
- break
- }
- }
- return codes
-}
-
-// ServiceGetTrieNodesQuery assembles the response to a trie nodes query.
-// It is exposed to allow external packages to test protocol behavior.
-func ServiceGetTrieNodesQuery(chain *core.BlockChain, req *GetTrieNodesPacket, start time.Time) ([][]byte, error) {
- if req.Bytes > softResponseLimit {
- req.Bytes = softResponseLimit
- }
- // Make sure we have the state associated with the request
- triedb := chain.TrieDB()
-
- accTrie, err := trie.NewStateTrie(trie.StateTrieID(req.Root), triedb)
- if err != nil {
- // We don't have the requested state available, bail out
- return nil, nil
- }
- // The 'snap' might be nil, in which case we cannot serve storage slots.
- snap := chain.Snapshots().Snapshot(req.Root)
- // Retrieve trie nodes until the packet size limit is reached
- var (
- nodes [][]byte
- bytes uint64
- loads int // Trie hash expansions to count database reads
- )
- for _, pathset := range req.Paths {
- switch len(pathset) {
- case 0:
- // Ensure we penalize invalid requests
- return nil, fmt.Errorf("%w: zero-item pathset requested", errBadRequest)
-
- case 1:
- // If we're only retrieving an account trie node, fetch it directly
- blob, resolved, err := accTrie.GetNode(pathset[0])
- loads += resolved // always account database reads, even for failures
- if err != nil {
- break
- }
- nodes = append(nodes, blob)
- bytes += uint64(len(blob))
-
- default:
- var stRoot common.Hash
- // Storage slots requested, open the storage trie and retrieve from there
- if snap == nil {
- // We don't have the requested state snapshotted yet (or it is stale),
- // but can look up the account via the trie instead.
- account, err := accTrie.GetAccountByHash(common.BytesToHash(pathset[0]))
- loads += 8 // We don't know the exact cost of lookup, this is an estimate
- if err != nil || account == nil {
- break
- }
- stRoot = account.Root
- } else {
- account, err := snap.Account(common.BytesToHash(pathset[0]))
- loads++ // always account database reads, even for failures
- if err != nil || account == nil {
- break
- }
- stRoot = common.BytesToHash(account.Root)
- }
- id := trie.StorageTrieID(req.Root, common.BytesToHash(pathset[0]), stRoot)
- stTrie, err := trie.NewStateTrie(id, triedb)
- loads++ // always account database reads, even for failures
- if err != nil {
- break
- }
- for _, path := range pathset[1:] {
- blob, resolved, err := stTrie.GetNode(path)
- loads += resolved // always account database reads, even for failures
- if err != nil {
- break
- }
- nodes = append(nodes, blob)
- bytes += uint64(len(blob))
-
- // Sanity check limits to avoid DoS on the store trie loads
- if bytes > req.Bytes || loads > maxTrieNodeLookups || time.Since(start) > maxTrieNodeTimeSpent {
- break
- }
- }
- }
- // Abort request processing if we've exceeded our limits
- if bytes > req.Bytes || loads > maxTrieNodeLookups || time.Since(start) > maxTrieNodeTimeSpent {
- break
- }
- }
- return nodes, nil
-}
-
-// NodeInfo represents a short summary of the `snap` sub-protocol metadata
-// known about the host peer.
-type NodeInfo struct{}
-
-// nodeInfo retrieves some `snap` protocol metadata about the running host node.
-func nodeInfo(chain *core.BlockChain) *NodeInfo {
- return &NodeInfo{}
-}
diff --git a/eth/protocols/snap/handler_fuzzing_test.go b/eth/protocols/snap/handler_fuzzing_test.go
deleted file mode 100644
index daed7ed44a..0000000000
--- a/eth/protocols/snap/handler_fuzzing_test.go
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2021 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 snap
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "math/big"
- "testing"
- "time"
-
- "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/vm"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- fuzz "github.com/google/gofuzz"
-)
-
-func FuzzARange(f *testing.F) {
- f.Fuzz(func(t *testing.T, data []byte) {
- doFuzz(data, &GetAccountRangePacket{}, GetAccountRangeMsg)
- })
-}
-
-func FuzzSRange(f *testing.F) {
- f.Fuzz(func(t *testing.T, data []byte) {
- doFuzz(data, &GetStorageRangesPacket{}, GetStorageRangesMsg)
- })
-}
-
-func FuzzByteCodes(f *testing.F) {
- f.Fuzz(func(t *testing.T, data []byte) {
- doFuzz(data, &GetByteCodesPacket{}, GetByteCodesMsg)
- })
-}
-
-func FuzzTrieNodes(f *testing.F) {
- f.Fuzz(func(t *testing.T, data []byte) {
- doFuzz(data, &GetTrieNodesPacket{}, GetTrieNodesMsg)
- })
-}
-
-func doFuzz(input []byte, obj interface{}, code int) {
- bc := getChain()
- defer bc.Stop()
- fuzz.NewFromGoFuzz(input).Fuzz(obj)
- var data []byte
- switch p := obj.(type) {
- case *GetTrieNodesPacket:
- p.Root = trieRoot
- data, _ = rlp.EncodeToBytes(obj)
- default:
- data, _ = rlp.EncodeToBytes(obj)
- }
- cli := &dummyRW{
- code: uint64(code),
- data: data,
- }
- peer := NewFakePeer(65, "gazonk01", cli)
- err := HandleMessage(&dummyBackend{bc}, peer)
- switch {
- case err == nil && cli.writeCount != 1:
- panic(fmt.Sprintf("Expected 1 response, got %d", cli.writeCount))
- case err != nil && cli.writeCount != 0:
- panic(fmt.Sprintf("Expected 0 response, got %d", cli.writeCount))
- }
-}
-
-var trieRoot common.Hash
-
-func getChain() *core.BlockChain {
- ga := make(core.GenesisAlloc, 1000)
- var a = make([]byte, 20)
- var mkStorage = func(k, v int) (common.Hash, common.Hash) {
- var kB = make([]byte, 32)
- var vB = make([]byte, 32)
- binary.LittleEndian.PutUint64(kB, uint64(k))
- binary.LittleEndian.PutUint64(vB, uint64(v))
- return common.BytesToHash(kB), common.BytesToHash(vB)
- }
- storage := make(map[common.Hash]common.Hash)
- for i := 0; i < 10; i++ {
- k, v := mkStorage(i, i)
- storage[k] = v
- }
- for i := 0; i < 1000; i++ {
- binary.LittleEndian.PutUint64(a, uint64(i+0xff))
- acc := core.GenesisAccount{Balance: big.NewInt(int64(i))}
- if i%2 == 1 {
- acc.Storage = storage
- }
- ga[common.BytesToAddress(a)] = acc
- }
- gspec := &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: ga,
- }
- _, blocks, _ := core.GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *core.BlockGen) {})
- cacheConf := &core.CacheConfig{
- TrieCleanLimit: 0,
- TrieDirtyLimit: 0,
- TrieTimeLimit: 5 * time.Minute,
- TrieCleanNoPrefetch: true,
- SnapshotLimit: 100,
- SnapshotWait: true,
- }
- trieRoot = blocks[len(blocks)-1].Root()
- bc, _ := core.NewBlockChain(rawdb.NewMemoryDatabase(), cacheConf, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
- if _, err := bc.InsertChain(blocks); err != nil {
- panic(err)
- }
- return bc
-}
-
-type dummyBackend struct {
- chain *core.BlockChain
-}
-
-func (d *dummyBackend) Chain() *core.BlockChain { return d.chain }
-func (d *dummyBackend) RunPeer(*Peer, Handler) error { return nil }
-func (d *dummyBackend) PeerInfo(enode.ID) interface{} { return "Foo" }
-func (d *dummyBackend) Handle(*Peer, Packet) error { return nil }
-
-type dummyRW struct {
- code uint64
- data []byte
- writeCount int
-}
-
-func (d *dummyRW) ReadMsg() (p2p.Msg, error) {
- return p2p.Msg{
- Code: d.code,
- Payload: bytes.NewReader(d.data),
- ReceivedAt: time.Now(),
- Size: uint32(len(d.data)),
- }, nil
-}
-
-func (d *dummyRW) WriteMsg(msg p2p.Msg) error {
- d.writeCount++
- return nil
-}
diff --git a/eth/protocols/snap/metrics.go b/eth/protocols/snap/metrics.go
deleted file mode 100644
index a7d071953f..0000000000
--- a/eth/protocols/snap/metrics.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2023 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 snap
-
-import (
- metrics "github.com/ethereum/go-ethereum/metrics"
-)
-
-var (
- ingressRegistrationErrorName = "eth/protocols/snap/ingress/registration/error"
- egressRegistrationErrorName = "eth/protocols/snap/egress/registration/error"
-
- IngressRegistrationErrorMeter = metrics.NewRegisteredMeter(ingressRegistrationErrorName, nil)
- EgressRegistrationErrorMeter = metrics.NewRegisteredMeter(egressRegistrationErrorName, nil)
-
- // deletionGauge is the metric to track how many trie node deletions
- // are performed in total during the sync process.
- deletionGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/delete", nil)
-
- // lookupGauge is the metric to track how many trie node lookups are
- // performed to determine if node needs to be deleted.
- lookupGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/lookup", nil)
-
- // boundaryAccountNodesGauge is the metric to track how many boundary trie
- // nodes in account trie are met.
- boundaryAccountNodesGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/boundary/account", nil)
-
- // boundaryAccountNodesGauge is the metric to track how many boundary trie
- // nodes in storage tries are met.
- boundaryStorageNodesGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/boundary/storage", nil)
-
- // smallStorageGauge is the metric to track how many storages are small enough
- // to retrieved in one or two request.
- smallStorageGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/storage/small", nil)
-
- // largeStorageGauge is the metric to track how many storages are large enough
- // to retrieved concurrently.
- largeStorageGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/storage/large", nil)
-
- // skipStorageHealingGauge is the metric to track how many storages are retrieved
- // in multiple requests but healing is not necessary.
- skipStorageHealingGauge = metrics.NewRegisteredGauge("eth/protocols/snap/sync/storage/noheal", nil)
-)
diff --git a/eth/protocols/snap/peer.go b/eth/protocols/snap/peer.go
deleted file mode 100644
index 3db6e22cbd..0000000000
--- a/eth/protocols/snap/peer.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2020 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 snap
-
-import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
-)
-
-// Peer is a collection of relevant information we have about a `snap` peer.
-type Peer struct {
- id string // Unique ID for the peer, cached
-
- *p2p.Peer // The embedded P2P package peer
- rw p2p.MsgReadWriter // Input/output streams for snap
- version uint // Protocol version negotiated
-
- logger log.Logger // Contextual logger with the peer id injected
-}
-
-// NewPeer create a wrapper for a network connection and negotiated protocol
-// version.
-func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) *Peer {
- id := p.ID().String()
- return &Peer{
- id: id,
- Peer: p,
- rw: rw,
- version: version,
- logger: log.New("peer", id[:8]),
- }
-}
-
-// NewFakePeer create a fake snap peer without a backing p2p peer, for testing purposes.
-func NewFakePeer(version uint, id string, rw p2p.MsgReadWriter) *Peer {
- return &Peer{
- id: id,
- rw: rw,
- version: version,
- logger: log.New("peer", id[:8]),
- }
-}
-
-// ID retrieves the peer's unique identifier.
-func (p *Peer) ID() string {
- return p.id
-}
-
-// Version retrieves the peer's negotiated `snap` protocol version.
-func (p *Peer) Version() uint {
- return p.version
-}
-
-// Log overrides the P2P logger with the higher level one containing only the id.
-func (p *Peer) Log() log.Logger {
- return p.logger
-}
-
-// RequestAccountRange fetches a batch of accounts rooted in a specific account
-// trie, starting with the origin.
-func (p *Peer) RequestAccountRange(id uint64, root common.Hash, origin, limit common.Hash, bytes uint64) error {
- p.logger.Trace("Fetching range of accounts", "reqid", id, "root", root, "origin", origin, "limit", limit, "bytes", common.StorageSize(bytes))
-
- requestTracker.Track(p.id, p.version, GetAccountRangeMsg, AccountRangeMsg, id)
- return p2p.Send(p.rw, GetAccountRangeMsg, &GetAccountRangePacket{
- ID: id,
- Root: root,
- Origin: origin,
- Limit: limit,
- Bytes: bytes,
- })
-}
-
-// RequestStorageRanges fetches a batch of storage slots belonging to one or more
-// accounts. If slots from only one account is requested, an origin marker may also
-// be used to retrieve from there.
-func (p *Peer) RequestStorageRanges(id uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, bytes uint64) error {
- if len(accounts) == 1 && origin != nil {
- p.logger.Trace("Fetching range of large storage slots", "reqid", id, "root", root, "account", accounts[0], "origin", common.BytesToHash(origin), "limit", common.BytesToHash(limit), "bytes", common.StorageSize(bytes))
- } else {
- p.logger.Trace("Fetching ranges of small storage slots", "reqid", id, "root", root, "accounts", len(accounts), "first", accounts[0], "bytes", common.StorageSize(bytes))
- }
- requestTracker.Track(p.id, p.version, GetStorageRangesMsg, StorageRangesMsg, id)
- return p2p.Send(p.rw, GetStorageRangesMsg, &GetStorageRangesPacket{
- ID: id,
- Root: root,
- Accounts: accounts,
- Origin: origin,
- Limit: limit,
- Bytes: bytes,
- })
-}
-
-// RequestByteCodes fetches a batch of bytecodes by hash.
-func (p *Peer) RequestByteCodes(id uint64, hashes []common.Hash, bytes uint64) error {
- p.logger.Trace("Fetching set of byte codes", "reqid", id, "hashes", len(hashes), "bytes", common.StorageSize(bytes))
-
- requestTracker.Track(p.id, p.version, GetByteCodesMsg, ByteCodesMsg, id)
- return p2p.Send(p.rw, GetByteCodesMsg, &GetByteCodesPacket{
- ID: id,
- Hashes: hashes,
- Bytes: bytes,
- })
-}
-
-// RequestTrieNodes fetches a batch of account or storage trie nodes rooted in
-// a specific state trie.
-func (p *Peer) RequestTrieNodes(id uint64, root common.Hash, paths []TrieNodePathSet, bytes uint64) error {
- p.logger.Trace("Fetching set of trie nodes", "reqid", id, "root", root, "pathsets", len(paths), "bytes", common.StorageSize(bytes))
-
- requestTracker.Track(p.id, p.version, GetTrieNodesMsg, TrieNodesMsg, id)
- return p2p.Send(p.rw, GetTrieNodesMsg, &GetTrieNodesPacket{
- ID: id,
- Root: root,
- Paths: paths,
- Bytes: bytes,
- })
-}
diff --git a/eth/protocols/snap/protocol.go b/eth/protocols/snap/protocol.go
deleted file mode 100644
index 0db206b081..0000000000
--- a/eth/protocols/snap/protocol.go
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2020 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 snap
-
-import (
- "errors"
- "fmt"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// Constants to match up protocol versions and messages
-const (
- SNAP1 = 1
-)
-
-// ProtocolName is the official short name of the `snap` protocol used during
-// devp2p capability negotiation.
-const ProtocolName = "snap"
-
-// ProtocolVersions are the supported versions of the `snap` protocol (first
-// is primary).
-var ProtocolVersions = []uint{SNAP1}
-
-// protocolLengths are the number of implemented message corresponding to
-// different protocol versions.
-var protocolLengths = map[uint]uint64{SNAP1: 8}
-
-// maxMessageSize is the maximum cap on the size of a protocol message.
-const maxMessageSize = 10 * 1024 * 1024
-
-const (
- GetAccountRangeMsg = 0x00
- AccountRangeMsg = 0x01
- GetStorageRangesMsg = 0x02
- StorageRangesMsg = 0x03
- GetByteCodesMsg = 0x04
- ByteCodesMsg = 0x05
- GetTrieNodesMsg = 0x06
- TrieNodesMsg = 0x07
-)
-
-var (
- errMsgTooLarge = errors.New("message too long")
- errDecode = errors.New("invalid message")
- errInvalidMsgCode = errors.New("invalid message code")
- errBadRequest = errors.New("bad request")
-)
-
-// Packet represents a p2p message in the `snap` protocol.
-type Packet interface {
- Name() string // Name returns a string corresponding to the message type.
- Kind() byte // Kind returns the message type.
-}
-
-// GetAccountRangePacket represents an account query.
-type GetAccountRangePacket struct {
- ID uint64 // Request ID to match up responses with
- Root common.Hash // Root hash of the account trie to serve
- Origin common.Hash // Hash of the first account to retrieve
- Limit common.Hash // Hash of the last account to retrieve
- Bytes uint64 // Soft limit at which to stop returning data
-}
-
-// AccountRangePacket represents an account query response.
-type AccountRangePacket struct {
- ID uint64 // ID of the request this is a response for
- Accounts []*AccountData // List of consecutive accounts from the trie
- Proof [][]byte // List of trie nodes proving the account range
-}
-
-// AccountData represents a single account in a query response.
-type AccountData struct {
- Hash common.Hash // Hash of the account
- Body rlp.RawValue // Account body in slim format
-}
-
-// Unpack retrieves the accounts from the range packet and converts from slim
-// wire representation to consensus format. The returned data is RLP encoded
-// since it's expected to be serialized to disk without further interpretation.
-//
-// Note, this method does a round of RLP decoding and reencoding, so only use it
-// once and cache the results if need be. Ideally discard the packet afterwards
-// to not double the memory use.
-func (p *AccountRangePacket) Unpack() ([]common.Hash, [][]byte, error) {
- var (
- hashes = make([]common.Hash, len(p.Accounts))
- accounts = make([][]byte, len(p.Accounts))
- )
- for i, acc := range p.Accounts {
- val, err := types.FullAccountRLP(acc.Body)
- if err != nil {
- return nil, nil, fmt.Errorf("invalid account %x: %v", acc.Body, err)
- }
- hashes[i], accounts[i] = acc.Hash, val
- }
- return hashes, accounts, nil
-}
-
-// GetStorageRangesPacket represents an storage slot query.
-type GetStorageRangesPacket struct {
- ID uint64 // Request ID to match up responses with
- Root common.Hash // Root hash of the account trie to serve
- Accounts []common.Hash // Account hashes of the storage tries to serve
- Origin []byte // Hash of the first storage slot to retrieve (large contract mode)
- Limit []byte // Hash of the last storage slot to retrieve (large contract mode)
- Bytes uint64 // Soft limit at which to stop returning data
-}
-
-// StorageRangesPacket represents a storage slot query response.
-type StorageRangesPacket struct {
- ID uint64 // ID of the request this is a response for
- Slots [][]*StorageData // Lists of consecutive storage slots for the requested accounts
- Proof [][]byte // Merkle proofs for the *last* slot range, if it's incomplete
-}
-
-// StorageData represents a single storage slot in a query response.
-type StorageData struct {
- Hash common.Hash // Hash of the storage slot
- Body []byte // Data content of the slot
-}
-
-// Unpack retrieves the storage slots from the range packet and returns them in
-// a split flat format that's more consistent with the internal data structures.
-func (p *StorageRangesPacket) Unpack() ([][]common.Hash, [][][]byte) {
- var (
- hashset = make([][]common.Hash, len(p.Slots))
- slotset = make([][][]byte, len(p.Slots))
- )
- for i, slots := range p.Slots {
- hashset[i] = make([]common.Hash, len(slots))
- slotset[i] = make([][]byte, len(slots))
- for j, slot := range slots {
- hashset[i][j] = slot.Hash
- slotset[i][j] = slot.Body
- }
- }
- return hashset, slotset
-}
-
-// GetByteCodesPacket represents a contract bytecode query.
-type GetByteCodesPacket struct {
- ID uint64 // Request ID to match up responses with
- Hashes []common.Hash // Code hashes to retrieve the code for
- Bytes uint64 // Soft limit at which to stop returning data
-}
-
-// ByteCodesPacket represents a contract bytecode query response.
-type ByteCodesPacket struct {
- ID uint64 // ID of the request this is a response for
- Codes [][]byte // Requested contract bytecodes
-}
-
-// GetTrieNodesPacket represents a state trie node query.
-type GetTrieNodesPacket struct {
- ID uint64 // Request ID to match up responses with
- Root common.Hash // Root hash of the account trie to serve
- Paths []TrieNodePathSet // Trie node hashes to retrieve the nodes for
- Bytes uint64 // Soft limit at which to stop returning data
-}
-
-// TrieNodePathSet is a list of trie node paths to retrieve. A naive way to
-// represent trie nodes would be a simple list of `account || storage` path
-// segments concatenated, but that would be very wasteful on the network.
-//
-// Instead, this array special cases the first element as the path in the
-// account trie and the remaining elements as paths in the storage trie. To
-// address an account node, the slice should have a length of 1 consisting
-// of only the account path. There's no need to be able to address both an
-// account node and a storage node in the same request as it cannot happen
-// that a slot is accessed before the account path is fully expanded.
-type TrieNodePathSet [][]byte
-
-// TrieNodesPacket represents a state trie node query response.
-type TrieNodesPacket struct {
- ID uint64 // ID of the request this is a response for
- Nodes [][]byte // Requested state trie nodes
-}
-
-func (*GetAccountRangePacket) Name() string { return "GetAccountRange" }
-func (*GetAccountRangePacket) Kind() byte { return GetAccountRangeMsg }
-
-func (*AccountRangePacket) Name() string { return "AccountRange" }
-func (*AccountRangePacket) Kind() byte { return AccountRangeMsg }
-
-func (*GetStorageRangesPacket) Name() string { return "GetStorageRanges" }
-func (*GetStorageRangesPacket) Kind() byte { return GetStorageRangesMsg }
-
-func (*StorageRangesPacket) Name() string { return "StorageRanges" }
-func (*StorageRangesPacket) Kind() byte { return StorageRangesMsg }
-
-func (*GetByteCodesPacket) Name() string { return "GetByteCodes" }
-func (*GetByteCodesPacket) Kind() byte { return GetByteCodesMsg }
-
-func (*ByteCodesPacket) Name() string { return "ByteCodes" }
-func (*ByteCodesPacket) Kind() byte { return ByteCodesMsg }
-
-func (*GetTrieNodesPacket) Name() string { return "GetTrieNodes" }
-func (*GetTrieNodesPacket) Kind() byte { return GetTrieNodesMsg }
-
-func (*TrieNodesPacket) Name() string { return "TrieNodes" }
-func (*TrieNodesPacket) Kind() byte { return TrieNodesMsg }
diff --git a/eth/protocols/snap/range.go b/eth/protocols/snap/range.go
deleted file mode 100644
index 8c98c71d50..0000000000
--- a/eth/protocols/snap/range.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2021 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 snap
-
-import (
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/holiman/uint256"
-)
-
-// hashRange is a utility to handle ranges of hashes, Split up the
-// hash-space into sections, and 'walk' over the sections
-type hashRange struct {
- current *uint256.Int
- step *uint256.Int
-}
-
-// newHashRange creates a new hashRange, initiated at the start position,
-// and with the step set to fill the desired 'num' chunks
-func newHashRange(start common.Hash, num uint64) *hashRange {
- left := new(big.Int).Sub(hashSpace, start.Big())
- step := new(big.Int).Div(
- new(big.Int).Add(left, new(big.Int).SetUint64(num-1)),
- new(big.Int).SetUint64(num),
- )
- step256 := new(uint256.Int)
- step256.SetFromBig(step)
-
- return &hashRange{
- current: new(uint256.Int).SetBytes32(start[:]),
- step: step256,
- }
-}
-
-// Next pushes the hash range to the next interval.
-func (r *hashRange) Next() bool {
- next, overflow := new(uint256.Int).AddOverflow(r.current, r.step)
- if overflow {
- return false
- }
- r.current = next
- return true
-}
-
-// Start returns the first hash in the current interval.
-func (r *hashRange) Start() common.Hash {
- return r.current.Bytes32()
-}
-
-// End returns the last hash in the current interval.
-func (r *hashRange) End() common.Hash {
- // If the end overflows (non divisible range), return a shorter interval
- next, overflow := new(uint256.Int).AddOverflow(r.current, r.step)
- if overflow {
- return common.MaxHash
- }
- return next.SubUint64(next, 1).Bytes32()
-}
-
-// incHash returns the next hash, in lexicographical order (a.k.a plus one)
-func incHash(h common.Hash) common.Hash {
- var a uint256.Int
- a.SetBytes32(h[:])
- a.AddUint64(&a, 1)
- return common.Hash(a.Bytes32())
-}
diff --git a/eth/protocols/snap/range_test.go b/eth/protocols/snap/range_test.go
deleted file mode 100644
index ea643f1361..0000000000
--- a/eth/protocols/snap/range_test.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2021 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 snap
-
-import (
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
-)
-
-// Tests that given a starting hash and a density, the hash ranger can correctly
-// split up the remaining hash space into a fixed number of chunks.
-func TestHashRanges(t *testing.T) {
- tests := []struct {
- head common.Hash
- chunks uint64
- starts []common.Hash
- ends []common.Hash
- }{
- // Simple test case to split the entire hash range into 4 chunks
- {
- head: common.Hash{},
- chunks: 4,
- starts: []common.Hash{
- {},
- common.HexToHash("0x4000000000000000000000000000000000000000000000000000000000000000"),
- common.HexToHash("0x8000000000000000000000000000000000000000000000000000000000000000"),
- common.HexToHash("0xc000000000000000000000000000000000000000000000000000000000000000"),
- },
- ends: []common.Hash{
- common.HexToHash("0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
- common.HexToHash("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
- common.HexToHash("0xbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
- common.MaxHash,
- },
- },
- // Split a divisible part of the hash range up into 2 chunks
- {
- head: common.HexToHash("0x2000000000000000000000000000000000000000000000000000000000000000"),
- chunks: 2,
- starts: []common.Hash{
- {},
- common.HexToHash("0x9000000000000000000000000000000000000000000000000000000000000000"),
- },
- ends: []common.Hash{
- common.HexToHash("0x8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
- common.MaxHash,
- },
- },
- // Split the entire hash range into a non divisible 3 chunks
- {
- head: common.Hash{},
- chunks: 3,
- starts: []common.Hash{
- {},
- common.HexToHash("0x5555555555555555555555555555555555555555555555555555555555555556"),
- common.HexToHash("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac"),
- },
- ends: []common.Hash{
- common.HexToHash("0x5555555555555555555555555555555555555555555555555555555555555555"),
- common.HexToHash("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"),
- common.MaxHash,
- },
- },
- // Split a part of hash range into a non divisible 3 chunks
- {
- head: common.HexToHash("0x2000000000000000000000000000000000000000000000000000000000000000"),
- chunks: 3,
- starts: []common.Hash{
- {},
- common.HexToHash("0x6aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"),
- common.HexToHash("0xb555555555555555555555555555555555555555555555555555555555555556"),
- },
- ends: []common.Hash{
- common.HexToHash("0x6aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
- common.HexToHash("0xb555555555555555555555555555555555555555555555555555555555555555"),
- common.MaxHash,
- },
- },
- // Split a part of hash range into a non divisible 3 chunks, but with a
- // meaningful space size for manual verification.
- // - The head being 0xff...f0, we have 14 hashes left in the space
- // - Chunking up 14 into 3 pieces is 4.(6), but we need the ceil of 5 to avoid a micro-last-chunk
- // - Since the range is not divisible, the last interval will be shorter, capped at 0xff...f
- // - The chunk ranges thus needs to be [..0, ..5], [..6, ..b], [..c, ..f]
- {
- head: common.HexToHash("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0"),
- chunks: 3,
- starts: []common.Hash{
- {},
- common.HexToHash("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6"),
- common.HexToHash("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc"),
- },
- ends: []common.Hash{
- common.HexToHash("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5"),
- common.HexToHash("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb"),
- common.MaxHash,
- },
- },
- }
- for i, tt := range tests {
- r := newHashRange(tt.head, tt.chunks)
-
- var (
- starts = []common.Hash{{}}
- ends = []common.Hash{r.End()}
- )
- for r.Next() {
- starts = append(starts, r.Start())
- ends = append(ends, r.End())
- }
- if len(starts) != len(tt.starts) {
- t.Errorf("test %d: starts count mismatch: have %d, want %d", i, len(starts), len(tt.starts))
- }
- for j := 0; j < len(starts) && j < len(tt.starts); j++ {
- if starts[j] != tt.starts[j] {
- t.Errorf("test %d, start %d: hash mismatch: have %x, want %x", i, j, starts[j], tt.starts[j])
- }
- }
- if len(ends) != len(tt.ends) {
- t.Errorf("test %d: ends count mismatch: have %d, want %d", i, len(ends), len(tt.ends))
- }
- for j := 0; j < len(ends) && j < len(tt.ends); j++ {
- if ends[j] != tt.ends[j] {
- t.Errorf("test %d, end %d: hash mismatch: have %x, want %x", i, j, ends[j], tt.ends[j])
- }
- }
- }
-}
diff --git a/eth/protocols/snap/sort_test.go b/eth/protocols/snap/sort_test.go
deleted file mode 100644
index be0a8c5706..0000000000
--- a/eth/protocols/snap/sort_test.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// 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 snap
-
-import (
- "bytes"
- "fmt"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
-)
-
-func hexToNibbles(s string) []byte {
- if len(s) >= 2 && s[0] == '0' && s[1] == 'x' {
- s = s[2:]
- }
- var s2 []byte
- for _, ch := range []byte(s) {
- s2 = append(s2, '0')
- s2 = append(s2, ch)
- }
- return common.Hex2Bytes(string(s2))
-}
-
-func TestRequestSorting(t *testing.T) {
- // - Path 0x9 -> {0x19}
- // - Path 0x99 -> {0x0099}
- // - Path 0x01234567890123456789012345678901012345678901234567890123456789019 -> {0x0123456789012345678901234567890101234567890123456789012345678901, 0x19}
- // - Path 0x012345678901234567890123456789010123456789012345678901234567890199 -> {0x0123456789012345678901234567890101234567890123456789012345678901, 0x0099}
- var f = func(path string) string {
- data := hexToNibbles(path)
- return string(data)
- }
- var (
- hashes []common.Hash
- paths []string
- )
- for _, x := range []string{
- "0x9",
- "0x012345678901234567890123456789010123456789012345678901234567890195",
- "0x012345678901234567890123456789010123456789012345678901234567890197",
- "0x012345678901234567890123456789010123456789012345678901234567890196",
- "0x99",
- "0x012345678901234567890123456789010123456789012345678901234567890199",
- "0x01234567890123456789012345678901012345678901234567890123456789019",
- "0x0123456789012345678901234567890101234567890123456789012345678901",
- "0x01234567890123456789012345678901012345678901234567890123456789010",
- "0x01234567890123456789012345678901012345678901234567890123456789011",
- } {
- paths = append(paths, f(x))
- hashes = append(hashes, common.Hash{})
- }
- _, _, syncPaths, pathsets := sortByAccountPath(paths, hashes)
- {
- var b = new(bytes.Buffer)
- for i := 0; i < len(syncPaths); i++ {
- fmt.Fprintf(b, "\n%d. paths %x", i, syncPaths[i])
- }
- want := `
-0. paths [0099]
-1. paths [0123456789012345678901234567890101234567890123456789012345678901 00]
-2. paths [0123456789012345678901234567890101234567890123456789012345678901 0095]
-3. paths [0123456789012345678901234567890101234567890123456789012345678901 0096]
-4. paths [0123456789012345678901234567890101234567890123456789012345678901 0097]
-5. paths [0123456789012345678901234567890101234567890123456789012345678901 0099]
-6. paths [0123456789012345678901234567890101234567890123456789012345678901 10]
-7. paths [0123456789012345678901234567890101234567890123456789012345678901 11]
-8. paths [0123456789012345678901234567890101234567890123456789012345678901 19]
-9. paths [19]`
- if have := b.String(); have != want {
- t.Errorf("have:%v\nwant:%v\n", have, want)
- }
- }
- {
- var b = new(bytes.Buffer)
- for i := 0; i < len(pathsets); i++ {
- fmt.Fprintf(b, "\n%d. pathset %x", i, pathsets[i])
- }
- want := `
-0. pathset [0099]
-1. pathset [0123456789012345678901234567890101234567890123456789012345678901 00 0095 0096 0097 0099 10 11 19]
-2. pathset [19]`
- if have := b.String(); have != want {
- t.Errorf("have:%v\nwant:%v\n", have, want)
- }
- }
-}
diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go
deleted file mode 100644
index 887a50775d..0000000000
--- a/eth/protocols/snap/sync.go
+++ /dev/null
@@ -1,3210 +0,0 @@
-// Copyright 2020 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 snap
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- gomath "math"
- "math/big"
- "math/rand"
- "sort"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "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/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/msgrate"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
- "github.com/ethereum/go-ethereum/trie/trienode"
- "golang.org/x/crypto/sha3"
-)
-
-const (
- // minRequestSize is the minimum number of bytes to request from a remote peer.
- // This number is used as the low cap for account and storage range requests.
- // Bytecode and trienode are limited inherently by item count (1).
- minRequestSize = 64 * 1024
-
- // maxRequestSize is the maximum number of bytes to request from a remote peer.
- // This number is used as the high cap for account and storage range requests.
- // Bytecode and trienode are limited more explicitly by the caps below.
- maxRequestSize = 512 * 1024
-
- // maxCodeRequestCount is the maximum number of bytecode blobs to request in a
- // single query. If this number is too low, we're not filling responses fully
- // and waste round trip times. If it's too high, we're capping responses and
- // waste bandwidth.
- //
- // Deployed bytecodes are currently capped at 24KB, so the minimum request
- // size should be maxRequestSize / 24K. Assuming that most contracts do not
- // come close to that, requesting 4x should be a good approximation.
- maxCodeRequestCount = maxRequestSize / (24 * 1024) * 4
-
- // maxTrieRequestCount is the maximum number of trie node blobs to request in
- // a single query. If this number is too low, we're not filling responses fully
- // and waste round trip times. If it's too high, we're capping responses and
- // waste bandwidth.
- maxTrieRequestCount = maxRequestSize / 512
-
- // trienodeHealRateMeasurementImpact is the impact a single measurement has on
- // the local node's trienode processing capacity. A value closer to 0 reacts
- // slower to sudden changes, but it is also more stable against temporary hiccups.
- trienodeHealRateMeasurementImpact = 0.005
-
- // 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
- // heal requests to avoid overloading the local node and exessively expanding
- // the state trie bedth wise.
- maxTrienodeHealThrottle = maxTrieRequestCount
-
- // trienodeHealThrottleIncrease is the multiplier for the throttle when the
- // rate of arriving data is higher than the rate of processing it.
- trienodeHealThrottleIncrease = 1.33
-
- // trienodeHealThrottleDecrease is the divisor for the throttle when the
- // rate of arriving data is lower than the rate of processing it.
- trienodeHealThrottleDecrease = 1.25
-)
-
-var (
- // accountConcurrency is the number of chunks to split the account trie into
- // to allow concurrent retrievals.
- accountConcurrency = 16
-
- // storageConcurrency is the number of chunks to split the a large contract
- // storage trie into to allow concurrent retrievals.
- storageConcurrency = 16
-)
-
-// ErrCancelled is returned from snap syncing if the operation was prematurely
-// terminated.
-var ErrCancelled = errors.New("sync cancelled")
-
-// accountRequest tracks a pending account range request to ensure responses are
-// to actual requests and to validate any security constraints.
-//
-// Concurrency note: account requests and responses are handled concurrently from
-// the main runloop to allow Merkle proof verifications on the peer's thread and
-// to drop on invalid response. The request struct must contain all the data to
-// construct the response without accessing runloop internals (i.e. task). That
-// is only included to allow the runloop to match a response to the task being
-// synced without having yet another set of maps.
-type accountRequest struct {
- peer string // Peer to which this request is assigned
- id uint64 // Request ID of this request
- time time.Time // Timestamp when the request was sent
-
- deliver chan *accountResponse // Channel to deliver successful response on
- revert chan *accountRequest // Channel to deliver request failure on
- cancel chan struct{} // Channel to track sync cancellation
- timeout *time.Timer // Timer to track delivery timeout
- stale chan struct{} // Channel to signal the request was dropped
-
- origin common.Hash // First account requested to allow continuation checks
- limit common.Hash // Last account requested to allow non-overlapping chunking
-
- task *accountTask // Task which this request is filling (only access fields through the runloop!!)
-}
-
-// accountResponse is an already Merkle-verified remote response to an account
-// range request. It contains the subtrie for the requested account range and
-// the database that's going to be filled with the internal nodes on commit.
-type accountResponse struct {
- task *accountTask // Task which this request is filling
-
- hashes []common.Hash // Account hashes in the returned range
- accounts []*types.StateAccount // Expanded accounts in the returned range
-
- cont bool // Whether the account range has a continuation
-}
-
-// bytecodeRequest tracks a pending bytecode request to ensure responses are to
-// actual requests and to validate any security constraints.
-//
-// Concurrency note: bytecode requests and responses are handled concurrently from
-// the main runloop to allow Keccak256 hash verifications on the peer's thread and
-// to drop on invalid response. The request struct must contain all the data to
-// construct the response without accessing runloop internals (i.e. task). That
-// is only included to allow the runloop to match a response to the task being
-// synced without having yet another set of maps.
-type bytecodeRequest struct {
- peer string // Peer to which this request is assigned
- id uint64 // Request ID of this request
- time time.Time // Timestamp when the request was sent
-
- deliver chan *bytecodeResponse // Channel to deliver successful response on
- revert chan *bytecodeRequest // Channel to deliver request failure on
- cancel chan struct{} // Channel to track sync cancellation
- timeout *time.Timer // Timer to track delivery timeout
- stale chan struct{} // Channel to signal the request was dropped
-
- hashes []common.Hash // Bytecode hashes to validate responses
- task *accountTask // Task which this request is filling (only access fields through the runloop!!)
-}
-
-// bytecodeResponse is an already verified remote response to a bytecode request.
-type bytecodeResponse struct {
- task *accountTask // Task which this request is filling
-
- hashes []common.Hash // Hashes of the bytecode to avoid double hashing
- codes [][]byte // Actual bytecodes to store into the database (nil = missing)
-}
-
-// storageRequest tracks a pending storage ranges request to ensure responses are
-// to actual requests and to validate any security constraints.
-//
-// Concurrency note: storage requests and responses are handled concurrently from
-// the main runloop to allow Merkle proof verifications on the peer's thread and
-// to drop on invalid response. The request struct must contain all the data to
-// construct the response without accessing runloop internals (i.e. tasks). That
-// is only included to allow the runloop to match a response to the task being
-// synced without having yet another set of maps.
-type storageRequest struct {
- peer string // Peer to which this request is assigned
- id uint64 // Request ID of this request
- time time.Time // Timestamp when the request was sent
-
- deliver chan *storageResponse // Channel to deliver successful response on
- revert chan *storageRequest // Channel to deliver request failure on
- cancel chan struct{} // Channel to track sync cancellation
- timeout *time.Timer // Timer to track delivery timeout
- stale chan struct{} // Channel to signal the request was dropped
-
- accounts []common.Hash // Account hashes to validate responses
- roots []common.Hash // Storage roots to validate responses
-
- origin common.Hash // First storage slot requested to allow continuation checks
- limit common.Hash // Last storage slot requested to allow non-overlapping chunking
-
- mainTask *accountTask // Task which this response belongs to (only access fields through the runloop!!)
- subTask *storageTask // Task which this response is filling (only access fields through the runloop!!)
-}
-
-// storageResponse is an already Merkle-verified remote response to a storage
-// range request. It contains the subtries for the requested storage ranges and
-// the databases that's going to be filled with the internal nodes on commit.
-type storageResponse struct {
- mainTask *accountTask // Task which this response belongs to
- subTask *storageTask // Task which this response is filling
-
- accounts []common.Hash // Account hashes requested, may be only partially filled
- roots []common.Hash // Storage roots requested, may be only partially filled
-
- hashes [][]common.Hash // Storage slot hashes in the returned range
- slots [][][]byte // Storage slot values in the returned range
-
- cont bool // Whether the last storage range has a continuation
-}
-
-// trienodeHealRequest tracks a pending state trie request to ensure responses
-// are to actual requests and to validate any security constraints.
-//
-// Concurrency note: trie node requests and responses are handled concurrently from
-// the main runloop to allow Keccak256 hash verifications on the peer's thread and
-// to drop on invalid response. The request struct must contain all the data to
-// construct the response without accessing runloop internals (i.e. task). That
-// is only included to allow the runloop to match a response to the task being
-// synced without having yet another set of maps.
-type trienodeHealRequest struct {
- peer string // Peer to which this request is assigned
- id uint64 // Request ID of this request
- time time.Time // Timestamp when the request was sent
-
- deliver chan *trienodeHealResponse // Channel to deliver successful response on
- revert chan *trienodeHealRequest // Channel to deliver request failure on
- cancel chan struct{} // Channel to track sync cancellation
- timeout *time.Timer // Timer to track delivery timeout
- stale chan struct{} // Channel to signal the request was dropped
-
- paths []string // Trie node paths for identifying trie node
- hashes []common.Hash // Trie node hashes to validate responses
-
- task *healTask // Task which this request is filling (only access fields through the runloop!!)
-}
-
-// trienodeHealResponse is an already verified remote response to a trie node request.
-type trienodeHealResponse struct {
- task *healTask // Task which this request is filling
-
- paths []string // Paths of the trie nodes
- hashes []common.Hash // Hashes of the trie nodes to avoid double hashing
- nodes [][]byte // Actual trie nodes to store into the database (nil = missing)
-}
-
-// bytecodeHealRequest tracks a pending bytecode request to ensure responses are to
-// actual requests and to validate any security constraints.
-//
-// Concurrency note: bytecode requests and responses are handled concurrently from
-// the main runloop to allow Keccak256 hash verifications on the peer's thread and
-// to drop on invalid response. The request struct must contain all the data to
-// construct the response without accessing runloop internals (i.e. task). That
-// is only included to allow the runloop to match a response to the task being
-// synced without having yet another set of maps.
-type bytecodeHealRequest struct {
- peer string // Peer to which this request is assigned
- id uint64 // Request ID of this request
- time time.Time // Timestamp when the request was sent
-
- deliver chan *bytecodeHealResponse // Channel to deliver successful response on
- revert chan *bytecodeHealRequest // Channel to deliver request failure on
- cancel chan struct{} // Channel to track sync cancellation
- timeout *time.Timer // Timer to track delivery timeout
- stale chan struct{} // Channel to signal the request was dropped
-
- hashes []common.Hash // Bytecode hashes to validate responses
- task *healTask // Task which this request is filling (only access fields through the runloop!!)
-}
-
-// bytecodeHealResponse is an already verified remote response to a bytecode request.
-type bytecodeHealResponse struct {
- task *healTask // Task which this request is filling
-
- hashes []common.Hash // Hashes of the bytecode to avoid double hashing
- codes [][]byte // Actual bytecodes to store into the database (nil = missing)
-}
-
-// accountTask represents the sync task for a chunk of the account snapshot.
-type accountTask struct {
- // These fields get serialized to leveldb on shutdown
- Next common.Hash // Next account to sync in this interval
- Last common.Hash // Last account to sync in this interval
- SubTasks map[common.Hash][]*storageTask // Storage intervals needing fetching for large contracts
-
- // These fields are internals used during runtime
- req *accountRequest // Pending request to fill this task
- res *accountResponse // Validate response filling this task
- pend int // Number of pending subtasks for this round
-
- needCode []bool // Flags whether the filling accounts need code retrieval
- needState []bool // Flags whether the filling accounts need storage retrieval
- needHeal []bool // Flags whether the filling accounts's state was chunked and need healing
-
- codeTasks map[common.Hash]struct{} // Code hashes that need retrieval
- stateTasks map[common.Hash]common.Hash // Account hashes->roots that need full state retrieval
-
- genBatch ethdb.Batch // Batch used by the node generator
- genTrie *trie.StackTrie // Node generator from storage slots
-
- done bool // Flag whether the task can be removed
-}
-
-// storageTask represents the sync task for a chunk of the storage snapshot.
-type storageTask struct {
- Next common.Hash // Next account to sync in this interval
- Last common.Hash // Last account to sync in this interval
-
- // These fields are internals used during runtime
- root common.Hash // Storage root hash for this instance
- req *storageRequest // Pending request to fill this task
-
- genBatch ethdb.Batch // Batch used by the node generator
- genTrie *trie.StackTrie // Node generator from storage slots
-
- done bool // Flag whether the task can be removed
-}
-
-// healTask represents the sync task for healing the snap-synced chunk boundaries.
-type healTask struct {
- scheduler *trie.Sync // State trie sync scheduler defining the tasks
-
- trieTasks map[string]common.Hash // Set of trie node tasks currently queued for retrieval, indexed by node path
- codeTasks map[common.Hash]struct{} // Set of byte code tasks currently queued for retrieval, indexed by code hash
-}
-
-// SyncProgress is a database entry to allow suspending and resuming a snapshot state
-// sync. Opposed to full and fast sync, there is no way to restart a suspended
-// snap sync without prior knowledge of the suspension point.
-type SyncProgress struct {
- Tasks []*accountTask // The suspended account tasks (contract tasks within)
-
- // Status report during syncing phase
- AccountSynced uint64 // Number of accounts downloaded
- AccountBytes common.StorageSize // Number of account trie bytes persisted to disk
- BytecodeSynced uint64 // Number of bytecodes downloaded
- BytecodeBytes common.StorageSize // Number of bytecode bytes downloaded
- StorageSynced uint64 // Number of storage slots downloaded
- StorageBytes common.StorageSize // Number of storage trie bytes persisted to disk
-
- // Status report during healing phase
- TrienodeHealSynced uint64 // Number of state trie nodes downloaded
- TrienodeHealBytes common.StorageSize // Number of state trie bytes persisted to disk
- BytecodeHealSynced uint64 // Number of bytecodes downloaded
- BytecodeHealBytes common.StorageSize // Number of bytecodes persisted to disk
-}
-
-// SyncPending is analogous to SyncProgress, but it's used to report on pending
-// ephemeral sync progress that doesn't get persisted into the database.
-type SyncPending struct {
- TrienodeHeal uint64 // Number of state trie nodes pending
- BytecodeHeal uint64 // Number of bytecodes pending
-}
-
-// SyncPeer abstracts out the methods required for a peer to be synced against
-// with the goal of allowing the construction of mock peers without the full
-// blown networking.
-type SyncPeer interface {
- // ID retrieves the peer's unique identifier.
- ID() string
-
- // RequestAccountRange fetches a batch of accounts rooted in a specific account
- // trie, starting with the origin.
- RequestAccountRange(id uint64, root, origin, limit common.Hash, bytes uint64) error
-
- // RequestStorageRanges fetches a batch of storage slots belonging to one or
- // more accounts. If slots from only one account is requested, an origin marker
- // may also be used to retrieve from there.
- RequestStorageRanges(id uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, bytes uint64) error
-
- // RequestByteCodes fetches a batch of bytecodes by hash.
- RequestByteCodes(id uint64, hashes []common.Hash, bytes uint64) error
-
- // RequestTrieNodes fetches a batch of account or storage trie nodes rooted in
- // a specific state trie.
- RequestTrieNodes(id uint64, root common.Hash, paths []TrieNodePathSet, bytes uint64) error
-
- // Log retrieves the peer's own contextual logger.
- Log() log.Logger
-}
-
-// Syncer is an Ethereum account and storage trie syncer based on snapshots and
-// the snap protocol. It's purpose is to download all the accounts and storage
-// slots from remote peers and reassemble chunks of the state trie, on top of
-// which a state sync can be run to fix any gaps / overlaps.
-//
-// Every network request has a variety of failure events:
-// - The peer disconnects after task assignment, failing to send the request
-// - The peer disconnects after sending the request, before delivering on it
-// - The peer remains connected, but does not deliver a response in time
-// - The peer delivers a stale response after a previous timeout
-// - The peer delivers a refusal to serve the requested state
-type Syncer struct {
- db ethdb.KeyValueStore // Database to store the trie nodes into (and dedup)
- scheme string // Node scheme used in node database
-
- root common.Hash // Current state trie root being synced
- tasks []*accountTask // Current account task set being synced
- snapped bool // Flag to signal that snap phase is done
- healer *healTask // Current state healing task being executed
- update chan struct{} // Notification channel for possible sync progression
-
- peers map[string]SyncPeer // Currently active peers to download from
- peerJoin *event.Feed // Event feed to react to peers joining
- peerDrop *event.Feed // Event feed to react to peers dropping
- rates *msgrate.Trackers // Message throughput rates for peers
-
- // Request tracking during syncing phase
- statelessPeers map[string]struct{} // Peers that failed to deliver state data
- accountIdlers map[string]struct{} // Peers that aren't serving account requests
- bytecodeIdlers map[string]struct{} // Peers that aren't serving bytecode requests
- storageIdlers map[string]struct{} // Peers that aren't serving storage requests
-
- accountReqs map[uint64]*accountRequest // Account requests currently running
- bytecodeReqs map[uint64]*bytecodeRequest // Bytecode requests currently running
- storageReqs map[uint64]*storageRequest // Storage requests currently running
-
- accountSynced uint64 // Number of accounts downloaded
- accountBytes common.StorageSize // Number of account trie bytes persisted to disk
- bytecodeSynced uint64 // Number of bytecodes downloaded
- bytecodeBytes common.StorageSize // Number of bytecode bytes downloaded
- storageSynced uint64 // Number of storage slots downloaded
- storageBytes common.StorageSize // Number of storage trie bytes persisted to disk
-
- extProgress *SyncProgress // progress that can be exposed to external caller.
-
- // Request tracking during healing phase
- trienodeHealIdlers map[string]struct{} // Peers that aren't serving trie node requests
- bytecodeHealIdlers map[string]struct{} // Peers that aren't serving bytecode requests
-
- trienodeHealReqs map[uint64]*trienodeHealRequest // Trie node requests currently running
- bytecodeHealReqs map[uint64]*bytecodeHealRequest // Bytecode requests currently running
-
- trienodeHealRate float64 // Average heal rate for processing trie node data
- trienodeHealPend atomic.Uint64 // Number of trie nodes currently pending for processing
- trienodeHealThrottle float64 // Divisor for throttling the amount of trienode heal data requested
- trienodeHealThrottled time.Time // Timestamp the last time the throttle was updated
-
- trienodeHealSynced uint64 // Number of state trie nodes downloaded
- trienodeHealBytes common.StorageSize // Number of state trie bytes persisted to disk
- trienodeHealDups uint64 // Number of state trie nodes already processed
- trienodeHealNops uint64 // Number of state trie nodes not requested
- bytecodeHealSynced uint64 // Number of bytecodes downloaded
- bytecodeHealBytes common.StorageSize // Number of bytecodes persisted to disk
- bytecodeHealDups uint64 // Number of bytecodes already processed
- bytecodeHealNops uint64 // Number of bytecodes not requested
-
- stateWriter ethdb.Batch // Shared batch writer used for persisting raw states
- accountHealed uint64 // Number of accounts downloaded during the healing stage
- accountHealedBytes common.StorageSize // Number of raw account bytes persisted to disk during the healing stage
- storageHealed uint64 // Number of storage slots downloaded during the healing stage
- storageHealedBytes common.StorageSize // Number of raw storage bytes persisted to disk during the healing stage
-
- startTime time.Time // Time instance when snapshot sync started
- logTime time.Time // Time instance when status was last reported
-
- pend sync.WaitGroup // Tracks network request goroutines for graceful shutdown
- lock sync.RWMutex // Protects fields that can change outside of sync (peers, reqs, root)
-}
-
-// NewSyncer creates a new snapshot syncer to download the Ethereum state over the
-// snap protocol.
-func NewSyncer(db ethdb.KeyValueStore, scheme string) *Syncer {
- return &Syncer{
- db: db,
- scheme: scheme,
-
- peers: make(map[string]SyncPeer),
- peerJoin: new(event.Feed),
- peerDrop: new(event.Feed),
- rates: msgrate.NewTrackers(log.New("proto", "snap")),
- update: make(chan struct{}, 1),
-
- accountIdlers: make(map[string]struct{}),
- storageIdlers: make(map[string]struct{}),
- bytecodeIdlers: make(map[string]struct{}),
-
- accountReqs: make(map[uint64]*accountRequest),
- storageReqs: make(map[uint64]*storageRequest),
- bytecodeReqs: make(map[uint64]*bytecodeRequest),
-
- trienodeHealIdlers: make(map[string]struct{}),
- bytecodeHealIdlers: make(map[string]struct{}),
-
- trienodeHealReqs: make(map[uint64]*trienodeHealRequest),
- bytecodeHealReqs: make(map[uint64]*bytecodeHealRequest),
- trienodeHealThrottle: maxTrienodeHealThrottle, // Tune downward instead of insta-filling with junk
- stateWriter: db.NewBatch(),
-
- extProgress: new(SyncProgress),
- }
-}
-
-// Register injects a new data source into the syncer's peerset.
-func (s *Syncer) Register(peer SyncPeer) error {
- // Make sure the peer is not registered yet
- id := peer.ID()
-
- s.lock.Lock()
- if _, ok := s.peers[id]; ok {
- log.Error("Snap peer already registered", "id", id)
-
- s.lock.Unlock()
- return errors.New("already registered")
- }
- s.peers[id] = peer
- s.rates.Track(id, msgrate.NewTracker(s.rates.MeanCapacities(), s.rates.MedianRoundTrip()))
-
- // Mark the peer as idle, even if no sync is running
- s.accountIdlers[id] = struct{}{}
- s.storageIdlers[id] = struct{}{}
- s.bytecodeIdlers[id] = struct{}{}
- s.trienodeHealIdlers[id] = struct{}{}
- s.bytecodeHealIdlers[id] = struct{}{}
- s.lock.Unlock()
-
- // Notify any active syncs that a new peer can be assigned data
- s.peerJoin.Send(id)
- return nil
-}
-
-// Unregister injects a new data source into the syncer's peerset.
-func (s *Syncer) Unregister(id string) error {
- // Remove all traces of the peer from the registry
- s.lock.Lock()
- if _, ok := s.peers[id]; !ok {
- log.Error("Snap peer not registered", "id", id)
-
- s.lock.Unlock()
- return errors.New("not registered")
- }
- delete(s.peers, id)
- s.rates.Untrack(id)
-
- // Remove status markers, even if no sync is running
- delete(s.statelessPeers, id)
-
- delete(s.accountIdlers, id)
- delete(s.storageIdlers, id)
- delete(s.bytecodeIdlers, id)
- delete(s.trienodeHealIdlers, id)
- delete(s.bytecodeHealIdlers, id)
- s.lock.Unlock()
-
- // Notify any active syncs that pending requests need to be reverted
- s.peerDrop.Send(id)
- return nil
-}
-
-// Sync starts (or resumes a previous) sync cycle to iterate over a state trie
-// with the given root and reconstruct the nodes based on the snapshot leaves.
-// Previously downloaded segments will not be redownloaded of fixed, rather any
-// errors will be healed after the leaves are fully accumulated.
-func (s *Syncer) Sync(root common.Hash, cancel chan struct{}) error {
- // Move the trie root from any previous value, revert stateless markers for
- // any peers and initialize the syncer if it was not yet run
- s.lock.Lock()
- s.root = root
- s.healer = &healTask{
- scheduler: state.NewStateSync(root, s.db, s.onHealState, s.scheme),
- trieTasks: make(map[string]common.Hash),
- codeTasks: make(map[common.Hash]struct{}),
- }
- s.statelessPeers = make(map[string]struct{})
- s.lock.Unlock()
-
- if s.startTime == (time.Time{}) {
- s.startTime = time.Now()
- }
- // Retrieve the previous sync status from LevelDB and abort if already synced
- s.loadSyncStatus()
- if len(s.tasks) == 0 && s.healer.scheduler.Pending() == 0 {
- log.Debug("Snapshot sync already completed")
- return nil
- }
- defer func() { // Persist any progress, independent of failure
- for _, task := range s.tasks {
- s.forwardAccountTask(task)
- }
- s.cleanAccountTasks()
- s.saveSyncStatus()
- }()
-
- log.Debug("Starting snapshot sync cycle", "root", root)
-
- // Flush out the last committed raw states
- defer func() {
- if s.stateWriter.ValueSize() > 0 {
- s.stateWriter.Write()
- s.stateWriter.Reset()
- }
- }()
- defer s.report(true)
- // commit any trie- and bytecode-healing data.
- defer s.commitHealer(true)
-
- // Whether sync completed or not, disregard any future packets
- defer func() {
- log.Debug("Terminating snapshot sync cycle", "root", root)
- s.lock.Lock()
- s.accountReqs = make(map[uint64]*accountRequest)
- s.storageReqs = make(map[uint64]*storageRequest)
- s.bytecodeReqs = make(map[uint64]*bytecodeRequest)
- s.trienodeHealReqs = make(map[uint64]*trienodeHealRequest)
- s.bytecodeHealReqs = make(map[uint64]*bytecodeHealRequest)
- s.lock.Unlock()
- }()
- // Keep scheduling sync tasks
- peerJoin := make(chan string, 16)
- peerJoinSub := s.peerJoin.Subscribe(peerJoin)
- defer peerJoinSub.Unsubscribe()
-
- peerDrop := make(chan string, 16)
- peerDropSub := s.peerDrop.Subscribe(peerDrop)
- defer peerDropSub.Unsubscribe()
-
- // Create a set of unique channels for this sync cycle. We need these to be
- // ephemeral so a data race doesn't accidentally deliver something stale on
- // a persistent channel across syncs (yup, this happened)
- var (
- accountReqFails = make(chan *accountRequest)
- storageReqFails = make(chan *storageRequest)
- bytecodeReqFails = make(chan *bytecodeRequest)
- accountResps = make(chan *accountResponse)
- storageResps = make(chan *storageResponse)
- bytecodeResps = make(chan *bytecodeResponse)
- trienodeHealReqFails = make(chan *trienodeHealRequest)
- bytecodeHealReqFails = make(chan *bytecodeHealRequest)
- trienodeHealResps = make(chan *trienodeHealResponse)
- bytecodeHealResps = make(chan *bytecodeHealResponse)
- )
- for {
- // Remove all completed tasks and terminate sync if everything's done
- s.cleanStorageTasks()
- s.cleanAccountTasks()
- if len(s.tasks) == 0 && s.healer.scheduler.Pending() == 0 {
- return nil
- }
- // Assign all the data retrieval tasks to any free peers
- s.assignAccountTasks(accountResps, accountReqFails, cancel)
- s.assignBytecodeTasks(bytecodeResps, bytecodeReqFails, cancel)
- s.assignStorageTasks(storageResps, storageReqFails, cancel)
-
- if len(s.tasks) == 0 {
- // Sync phase done, run heal phase
- s.assignTrienodeHealTasks(trienodeHealResps, trienodeHealReqFails, cancel)
- s.assignBytecodeHealTasks(bytecodeHealResps, bytecodeHealReqFails, cancel)
- }
- // Update sync progress
- s.lock.Lock()
- s.extProgress = &SyncProgress{
- AccountSynced: s.accountSynced,
- AccountBytes: s.accountBytes,
- BytecodeSynced: s.bytecodeSynced,
- BytecodeBytes: s.bytecodeBytes,
- StorageSynced: s.storageSynced,
- StorageBytes: s.storageBytes,
- TrienodeHealSynced: s.trienodeHealSynced,
- TrienodeHealBytes: s.trienodeHealBytes,
- BytecodeHealSynced: s.bytecodeHealSynced,
- BytecodeHealBytes: s.bytecodeHealBytes,
- }
- s.lock.Unlock()
- // Wait for something to happen
- select {
- case <-s.update:
- // Something happened (new peer, delivery, timeout), recheck tasks
- case <-peerJoin:
- // A new peer joined, try to schedule it new tasks
- case id := <-peerDrop:
- s.revertRequests(id)
- case <-cancel:
- return ErrCancelled
-
- case req := <-accountReqFails:
- s.revertAccountRequest(req)
- case req := <-bytecodeReqFails:
- s.revertBytecodeRequest(req)
- case req := <-storageReqFails:
- s.revertStorageRequest(req)
- case req := <-trienodeHealReqFails:
- s.revertTrienodeHealRequest(req)
- case req := <-bytecodeHealReqFails:
- s.revertBytecodeHealRequest(req)
-
- case res := <-accountResps:
- s.processAccountResponse(res)
- case res := <-bytecodeResps:
- s.processBytecodeResponse(res)
- case res := <-storageResps:
- s.processStorageResponse(res)
- case res := <-trienodeHealResps:
- s.processTrienodeHealResponse(res)
- case res := <-bytecodeHealResps:
- s.processBytecodeHealResponse(res)
- }
- // Report stats if something meaningful happened
- s.report(false)
- }
-}
-
-// cleanPath is used to remove the dangling nodes in the stackTrie.
-func (s *Syncer) cleanPath(batch ethdb.Batch, owner common.Hash, path []byte) {
- if owner == (common.Hash{}) && rawdb.ExistsAccountTrieNode(s.db, path) {
- rawdb.DeleteAccountTrieNode(batch, path)
- deletionGauge.Inc(1)
- }
- if owner != (common.Hash{}) && rawdb.ExistsStorageTrieNode(s.db, owner, path) {
- rawdb.DeleteStorageTrieNode(batch, owner, path)
- deletionGauge.Inc(1)
- }
- lookupGauge.Inc(1)
-}
-
-// loadSyncStatus retrieves a previously aborted sync status from the database,
-// or generates a fresh one if none is available.
-func (s *Syncer) loadSyncStatus() {
- var progress SyncProgress
-
- if status := rawdb.ReadSnapshotSyncStatus(s.db); status != nil {
- if err := json.Unmarshal(status, &progress); err != nil {
- log.Error("Failed to decode snap sync status", "err", err)
- } else {
- for _, task := range progress.Tasks {
- log.Debug("Scheduled account sync task", "from", task.Next, "last", task.Last)
- }
- s.tasks = progress.Tasks
- for _, task := range s.tasks {
- task := task // closure for task.genBatch in the stacktrie writer callback
-
- task.genBatch = ethdb.HookedBatch{
- Batch: s.db.NewBatch(),
- OnPut: func(key []byte, value []byte) {
- s.accountBytes += common.StorageSize(len(key) + len(value))
- },
- }
- options := trie.NewStackTrieOptions()
- options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) {
- rawdb.WriteTrieNode(task.genBatch, common.Hash{}, path, hash, blob, s.scheme)
- })
- if s.scheme == rawdb.PathScheme {
- // Configure the dangling node cleaner and also filter out boundary nodes
- // only in the context of the path scheme. Deletion is forbidden in the
- // hash scheme, as it can disrupt state completeness.
- options = options.WithCleaner(func(path []byte) {
- s.cleanPath(task.genBatch, common.Hash{}, path)
- })
- // Skip the left boundary if it's not the first range.
- // Skip the right boundary if it's not the last range.
- options = options.WithSkipBoundary(task.Next != (common.Hash{}), task.Last != common.MaxHash, boundaryAccountNodesGauge)
- }
- task.genTrie = trie.NewStackTrie(options)
- for accountHash, subtasks := range task.SubTasks {
- for _, subtask := range subtasks {
- subtask := subtask // closure for subtask.genBatch in the stacktrie writer callback
-
- subtask.genBatch = ethdb.HookedBatch{
- Batch: s.db.NewBatch(),
- OnPut: func(key []byte, value []byte) {
- s.storageBytes += common.StorageSize(len(key) + len(value))
- },
- }
- owner := accountHash // local assignment for stacktrie writer closure
- options := trie.NewStackTrieOptions()
- options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) {
- rawdb.WriteTrieNode(subtask.genBatch, owner, path, hash, blob, s.scheme)
- })
- if s.scheme == rawdb.PathScheme {
- // Configure the dangling node cleaner and also filter out boundary nodes
- // only in the context of the path scheme. Deletion is forbidden in the
- // hash scheme, as it can disrupt state completeness.
- options = options.WithCleaner(func(path []byte) {
- s.cleanPath(subtask.genBatch, owner, path)
- })
- // Skip the left boundary if it's not the first range.
- // Skip the right boundary if it's not the last range.
- options = options.WithSkipBoundary(subtask.Next != common.Hash{}, subtask.Last != common.MaxHash, boundaryStorageNodesGauge)
- }
- subtask.genTrie = trie.NewStackTrie(options)
- }
- }
- }
- s.lock.Lock()
- defer s.lock.Unlock()
-
- s.snapped = len(s.tasks) == 0
-
- s.accountSynced = progress.AccountSynced
- s.accountBytes = progress.AccountBytes
- s.bytecodeSynced = progress.BytecodeSynced
- s.bytecodeBytes = progress.BytecodeBytes
- s.storageSynced = progress.StorageSynced
- s.storageBytes = progress.StorageBytes
-
- s.trienodeHealSynced = progress.TrienodeHealSynced
- s.trienodeHealBytes = progress.TrienodeHealBytes
- s.bytecodeHealSynced = progress.BytecodeHealSynced
- s.bytecodeHealBytes = progress.BytecodeHealBytes
- return
- }
- }
- // Either we've failed to decode the previous state, or there was none.
- // Start a fresh sync by chunking up the account range and scheduling
- // them for retrieval.
- s.tasks = nil
- s.accountSynced, s.accountBytes = 0, 0
- s.bytecodeSynced, s.bytecodeBytes = 0, 0
- s.storageSynced, s.storageBytes = 0, 0
- s.trienodeHealSynced, s.trienodeHealBytes = 0, 0
- s.bytecodeHealSynced, s.bytecodeHealBytes = 0, 0
-
- var next common.Hash
- step := new(big.Int).Sub(
- new(big.Int).Div(
- new(big.Int).Exp(common.Big2, common.Big256, nil),
- big.NewInt(int64(accountConcurrency)),
- ), common.Big1,
- )
- for i := 0; i < accountConcurrency; i++ {
- last := common.BigToHash(new(big.Int).Add(next.Big(), step))
- if i == accountConcurrency-1 {
- // Make sure we don't overflow if the step is not a proper divisor
- last = common.MaxHash
- }
- batch := ethdb.HookedBatch{
- Batch: s.db.NewBatch(),
- OnPut: func(key []byte, value []byte) {
- s.accountBytes += common.StorageSize(len(key) + len(value))
- },
- }
- options := trie.NewStackTrieOptions()
- options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) {
- rawdb.WriteTrieNode(batch, common.Hash{}, path, hash, blob, s.scheme)
- })
- if s.scheme == rawdb.PathScheme {
- // Configure the dangling node cleaner and also filter out boundary nodes
- // only in the context of the path scheme. Deletion is forbidden in the
- // hash scheme, as it can disrupt state completeness.
- options = options.WithCleaner(func(path []byte) {
- s.cleanPath(batch, common.Hash{}, path)
- })
- // Skip the left boundary if it's not the first range.
- // Skip the right boundary if it's not the last range.
- options = options.WithSkipBoundary(next != common.Hash{}, last != common.MaxHash, boundaryAccountNodesGauge)
- }
- s.tasks = append(s.tasks, &accountTask{
- Next: next,
- Last: last,
- SubTasks: make(map[common.Hash][]*storageTask),
- genBatch: batch,
- genTrie: trie.NewStackTrie(options),
- })
- log.Debug("Created account sync task", "from", next, "last", last)
- next = common.BigToHash(new(big.Int).Add(last.Big(), common.Big1))
- }
-}
-
-// saveSyncStatus marshals the remaining sync tasks into leveldb.
-func (s *Syncer) saveSyncStatus() {
- // Serialize any partial progress to disk before spinning down
- for _, task := range s.tasks {
- if err := task.genBatch.Write(); err != nil {
- log.Error("Failed to persist account slots", "err", err)
- }
- for _, subtasks := range task.SubTasks {
- for _, subtask := range subtasks {
- if err := subtask.genBatch.Write(); err != nil {
- log.Error("Failed to persist storage slots", "err", err)
- }
- }
- }
- }
- // Store the actual progress markers
- progress := &SyncProgress{
- Tasks: s.tasks,
- AccountSynced: s.accountSynced,
- AccountBytes: s.accountBytes,
- BytecodeSynced: s.bytecodeSynced,
- BytecodeBytes: s.bytecodeBytes,
- StorageSynced: s.storageSynced,
- StorageBytes: s.storageBytes,
- TrienodeHealSynced: s.trienodeHealSynced,
- TrienodeHealBytes: s.trienodeHealBytes,
- BytecodeHealSynced: s.bytecodeHealSynced,
- BytecodeHealBytes: s.bytecodeHealBytes,
- }
- status, err := json.Marshal(progress)
- if err != nil {
- panic(err) // This can only fail during implementation
- }
- rawdb.WriteSnapshotSyncStatus(s.db, status)
-}
-
-// Progress returns the snap sync status statistics.
-func (s *Syncer) Progress() (*SyncProgress, *SyncPending) {
- s.lock.Lock()
- defer s.lock.Unlock()
- pending := new(SyncPending)
- if s.healer != nil {
- pending.TrienodeHeal = uint64(len(s.healer.trieTasks))
- pending.BytecodeHeal = uint64(len(s.healer.codeTasks))
- }
- return s.extProgress, pending
-}
-
-// cleanAccountTasks removes account range retrieval tasks that have already been
-// completed.
-func (s *Syncer) cleanAccountTasks() {
- // If the sync was already done before, don't even bother
- if len(s.tasks) == 0 {
- return
- }
- // Sync wasn't finished previously, check for any task that can be finalized
- for i := 0; i < len(s.tasks); i++ {
- if s.tasks[i].done {
- s.tasks = append(s.tasks[:i], s.tasks[i+1:]...)
- i--
- }
- }
- // If everything was just finalized just, generate the account trie and start heal
- if len(s.tasks) == 0 {
- s.lock.Lock()
- s.snapped = true
- s.lock.Unlock()
-
- // Push the final sync report
- s.reportSyncProgress(true)
- }
-}
-
-// cleanStorageTasks iterates over all the account tasks and storage sub-tasks
-// within, cleaning any that have been completed.
-func (s *Syncer) cleanStorageTasks() {
- for _, task := range s.tasks {
- for account, subtasks := range task.SubTasks {
- // Remove storage range retrieval tasks that completed
- for j := 0; j < len(subtasks); j++ {
- if subtasks[j].done {
- subtasks = append(subtasks[:j], subtasks[j+1:]...)
- j--
- }
- }
- if len(subtasks) > 0 {
- task.SubTasks[account] = subtasks
- continue
- }
- // If all storage chunks are done, mark the account as done too
- for j, hash := range task.res.hashes {
- if hash == account {
- task.needState[j] = false
- }
- }
- delete(task.SubTasks, account)
- task.pend--
-
- // If this was the last pending task, forward the account task
- if task.pend == 0 {
- s.forwardAccountTask(task)
- }
- }
- }
-}
-
-// assignAccountTasks attempts to match idle peers to pending account range
-// retrievals.
-func (s *Syncer) assignAccountTasks(success chan *accountResponse, fail chan *accountRequest, cancel chan struct{}) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- // Sort the peers by download capacity to use faster ones if many available
- idlers := &capacitySort{
- ids: make([]string, 0, len(s.accountIdlers)),
- caps: make([]int, 0, len(s.accountIdlers)),
- }
- targetTTL := s.rates.TargetTimeout()
- for id := range s.accountIdlers {
- if _, ok := s.statelessPeers[id]; ok {
- continue
- }
- idlers.ids = append(idlers.ids, id)
- idlers.caps = append(idlers.caps, s.rates.Capacity(id, AccountRangeMsg, targetTTL))
- }
- if len(idlers.ids) == 0 {
- return
- }
- sort.Sort(sort.Reverse(idlers))
-
- // Iterate over all the tasks and try to find a pending one
- for _, task := range s.tasks {
- // Skip any tasks already filling
- if task.req != nil || task.res != nil {
- continue
- }
- // Task pending retrieval, try to find an idle peer. If no such peer
- // exists, we probably assigned tasks for all (or they are stateless).
- // Abort the entire assignment mechanism.
- if len(idlers.ids) == 0 {
- return
- }
- var (
- idle = idlers.ids[0]
- peer = s.peers[idle]
- cap = idlers.caps[0]
- )
- idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
-
- // Matched a pending task to an idle peer, allocate a unique request id
- var reqid uint64
- for {
- reqid = uint64(rand.Int63())
- if reqid == 0 {
- continue
- }
- if _, ok := s.accountReqs[reqid]; ok {
- continue
- }
- break
- }
- // Generate the network query and send it to the peer
- req := &accountRequest{
- peer: idle,
- id: reqid,
- time: time.Now(),
- deliver: success,
- revert: fail,
- cancel: cancel,
- stale: make(chan struct{}),
- origin: task.Next,
- limit: task.Last,
- task: task,
- }
- req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
- peer.Log().Debug("Account range request timed out", "reqid", reqid)
- s.rates.Update(idle, AccountRangeMsg, 0, 0)
- s.scheduleRevertAccountRequest(req)
- })
- s.accountReqs[reqid] = req
- delete(s.accountIdlers, idle)
-
- s.pend.Add(1)
- go func(root common.Hash) {
- defer s.pend.Done()
-
- // Attempt to send the remote request and revert if it fails
- if cap > maxRequestSize {
- cap = maxRequestSize
- }
- if cap < minRequestSize { // Don't bother with peers below a bare minimum performance
- cap = minRequestSize
- }
- if err := peer.RequestAccountRange(reqid, root, req.origin, req.limit, uint64(cap)); err != nil {
- peer.Log().Debug("Failed to request account range", "err", err)
- s.scheduleRevertAccountRequest(req)
- }
- }(s.root)
-
- // Inject the request into the task to block further assignments
- task.req = req
- }
-}
-
-// assignBytecodeTasks attempts to match idle peers to pending code retrievals.
-func (s *Syncer) assignBytecodeTasks(success chan *bytecodeResponse, fail chan *bytecodeRequest, cancel chan struct{}) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- // Sort the peers by download capacity to use faster ones if many available
- idlers := &capacitySort{
- ids: make([]string, 0, len(s.bytecodeIdlers)),
- caps: make([]int, 0, len(s.bytecodeIdlers)),
- }
- targetTTL := s.rates.TargetTimeout()
- for id := range s.bytecodeIdlers {
- if _, ok := s.statelessPeers[id]; ok {
- continue
- }
- idlers.ids = append(idlers.ids, id)
- idlers.caps = append(idlers.caps, s.rates.Capacity(id, ByteCodesMsg, targetTTL))
- }
- if len(idlers.ids) == 0 {
- return
- }
- sort.Sort(sort.Reverse(idlers))
-
- // Iterate over all the tasks and try to find a pending one
- for _, task := range s.tasks {
- // Skip any tasks not in the bytecode retrieval phase
- if task.res == nil {
- continue
- }
- // Skip tasks that are already retrieving (or done with) all codes
- if len(task.codeTasks) == 0 {
- continue
- }
- // Task pending retrieval, try to find an idle peer. If no such peer
- // exists, we probably assigned tasks for all (or they are stateless).
- // Abort the entire assignment mechanism.
- if len(idlers.ids) == 0 {
- return
- }
- var (
- idle = idlers.ids[0]
- peer = s.peers[idle]
- cap = idlers.caps[0]
- )
- idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
-
- // Matched a pending task to an idle peer, allocate a unique request id
- var reqid uint64
- for {
- reqid = uint64(rand.Int63())
- if reqid == 0 {
- continue
- }
- if _, ok := s.bytecodeReqs[reqid]; ok {
- continue
- }
- break
- }
- // Generate the network query and send it to the peer
- if cap > maxCodeRequestCount {
- cap = maxCodeRequestCount
- }
- hashes := make([]common.Hash, 0, cap)
- for hash := range task.codeTasks {
- delete(task.codeTasks, hash)
- hashes = append(hashes, hash)
- if len(hashes) >= cap {
- break
- }
- }
- req := &bytecodeRequest{
- peer: idle,
- id: reqid,
- time: time.Now(),
- deliver: success,
- revert: fail,
- cancel: cancel,
- stale: make(chan struct{}),
- hashes: hashes,
- task: task,
- }
- req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
- peer.Log().Debug("Bytecode request timed out", "reqid", reqid)
- s.rates.Update(idle, ByteCodesMsg, 0, 0)
- s.scheduleRevertBytecodeRequest(req)
- })
- s.bytecodeReqs[reqid] = req
- delete(s.bytecodeIdlers, idle)
-
- s.pend.Add(1)
- go func() {
- defer s.pend.Done()
-
- // Attempt to send the remote request and revert if it fails
- if err := peer.RequestByteCodes(reqid, hashes, maxRequestSize); err != nil {
- log.Debug("Failed to request bytecodes", "err", err)
- s.scheduleRevertBytecodeRequest(req)
- }
- }()
- }
-}
-
-// assignStorageTasks attempts to match idle peers to pending storage range
-// retrievals.
-func (s *Syncer) assignStorageTasks(success chan *storageResponse, fail chan *storageRequest, cancel chan struct{}) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- // Sort the peers by download capacity to use faster ones if many available
- idlers := &capacitySort{
- ids: make([]string, 0, len(s.storageIdlers)),
- caps: make([]int, 0, len(s.storageIdlers)),
- }
- targetTTL := s.rates.TargetTimeout()
- for id := range s.storageIdlers {
- if _, ok := s.statelessPeers[id]; ok {
- continue
- }
- idlers.ids = append(idlers.ids, id)
- idlers.caps = append(idlers.caps, s.rates.Capacity(id, StorageRangesMsg, targetTTL))
- }
- if len(idlers.ids) == 0 {
- return
- }
- sort.Sort(sort.Reverse(idlers))
-
- // Iterate over all the tasks and try to find a pending one
- for _, task := range s.tasks {
- // Skip any tasks not in the storage retrieval phase
- if task.res == nil {
- continue
- }
- // Skip tasks that are already retrieving (or done with) all small states
- if len(task.SubTasks) == 0 && len(task.stateTasks) == 0 {
- continue
- }
- // Task pending retrieval, try to find an idle peer. If no such peer
- // exists, we probably assigned tasks for all (or they are stateless).
- // Abort the entire assignment mechanism.
- if len(idlers.ids) == 0 {
- return
- }
- var (
- idle = idlers.ids[0]
- peer = s.peers[idle]
- cap = idlers.caps[0]
- )
- idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
-
- // Matched a pending task to an idle peer, allocate a unique request id
- var reqid uint64
- for {
- reqid = uint64(rand.Int63())
- if reqid == 0 {
- continue
- }
- if _, ok := s.storageReqs[reqid]; ok {
- continue
- }
- break
- }
- // Generate the network query and send it to the peer. If there are
- // large contract tasks pending, complete those before diving into
- // even more new contracts.
- if cap > maxRequestSize {
- cap = maxRequestSize
- }
- if cap < minRequestSize { // Don't bother with peers below a bare minimum performance
- cap = minRequestSize
- }
- storageSets := cap / 1024
-
- var (
- accounts = make([]common.Hash, 0, storageSets)
- roots = make([]common.Hash, 0, storageSets)
- subtask *storageTask
- )
- for account, subtasks := range task.SubTasks {
- for _, st := range subtasks {
- // Skip any subtasks already filling
- if st.req != nil {
- continue
- }
- // Found an incomplete storage chunk, schedule it
- accounts = append(accounts, account)
- roots = append(roots, st.root)
- subtask = st
- break // Large contract chunks are downloaded individually
- }
- if subtask != nil {
- break // Large contract chunks are downloaded individually
- }
- }
- if subtask == nil {
- // No large contract required retrieval, but small ones available
- for account, root := range task.stateTasks {
- delete(task.stateTasks, account)
-
- accounts = append(accounts, account)
- roots = append(roots, root)
-
- if len(accounts) >= storageSets {
- break
- }
- }
- }
- // If nothing was found, it means this task is actually already fully
- // retrieving, but large contracts are hard to detect. Skip to the next.
- if len(accounts) == 0 {
- continue
- }
- req := &storageRequest{
- peer: idle,
- id: reqid,
- time: time.Now(),
- deliver: success,
- revert: fail,
- cancel: cancel,
- stale: make(chan struct{}),
- accounts: accounts,
- roots: roots,
- mainTask: task,
- subTask: subtask,
- }
- if subtask != nil {
- req.origin = subtask.Next
- req.limit = subtask.Last
- }
- req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
- peer.Log().Debug("Storage request timed out", "reqid", reqid)
- s.rates.Update(idle, StorageRangesMsg, 0, 0)
- s.scheduleRevertStorageRequest(req)
- })
- s.storageReqs[reqid] = req
- delete(s.storageIdlers, idle)
-
- s.pend.Add(1)
- go func(root common.Hash) {
- defer s.pend.Done()
-
- // Attempt to send the remote request and revert if it fails
- var origin, limit []byte
- if subtask != nil {
- origin, limit = req.origin[:], req.limit[:]
- }
- if err := peer.RequestStorageRanges(reqid, root, accounts, origin, limit, uint64(cap)); err != nil {
- log.Debug("Failed to request storage", "err", err)
- s.scheduleRevertStorageRequest(req)
- }
- }(s.root)
-
- // Inject the request into the subtask to block further assignments
- if subtask != nil {
- subtask.req = req
- }
- }
-}
-
-// assignTrienodeHealTasks attempts to match idle peers to trie node requests to
-// heal any trie errors caused by the snap sync's chunked retrieval model.
-func (s *Syncer) assignTrienodeHealTasks(success chan *trienodeHealResponse, fail chan *trienodeHealRequest, cancel chan struct{}) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- // Sort the peers by download capacity to use faster ones if many available
- idlers := &capacitySort{
- ids: make([]string, 0, len(s.trienodeHealIdlers)),
- caps: make([]int, 0, len(s.trienodeHealIdlers)),
- }
- targetTTL := s.rates.TargetTimeout()
- for id := range s.trienodeHealIdlers {
- if _, ok := s.statelessPeers[id]; ok {
- continue
- }
- idlers.ids = append(idlers.ids, id)
- idlers.caps = append(idlers.caps, s.rates.Capacity(id, TrieNodesMsg, targetTTL))
- }
- if len(idlers.ids) == 0 {
- return
- }
- sort.Sort(sort.Reverse(idlers))
-
- // Iterate over pending tasks and try to find a peer to retrieve with
- for len(s.healer.trieTasks) > 0 || s.healer.scheduler.Pending() > 0 {
- // If there are not enough trie tasks queued to fully assign, fill the
- // queue from the state sync scheduler. The trie synced schedules these
- // together with bytecodes, so we need to queue them combined.
- var (
- have = len(s.healer.trieTasks) + len(s.healer.codeTasks)
- want = maxTrieRequestCount + maxCodeRequestCount
- )
- if have < want {
- paths, hashes, codes := s.healer.scheduler.Missing(want - have)
- for i, path := range paths {
- s.healer.trieTasks[path] = hashes[i]
- }
- for _, hash := range codes {
- s.healer.codeTasks[hash] = struct{}{}
- }
- }
- // If all the heal tasks are bytecodes or already downloading, bail
- if len(s.healer.trieTasks) == 0 {
- return
- }
- // Task pending retrieval, try to find an idle peer. If no such peer
- // exists, we probably assigned tasks for all (or they are stateless).
- // Abort the entire assignment mechanism.
- if len(idlers.ids) == 0 {
- return
- }
- var (
- idle = idlers.ids[0]
- peer = s.peers[idle]
- cap = idlers.caps[0]
- )
- idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
-
- // Matched a pending task to an idle peer, allocate a unique request id
- var reqid uint64
- for {
- reqid = uint64(rand.Int63())
- if reqid == 0 {
- continue
- }
- if _, ok := s.trienodeHealReqs[reqid]; ok {
- continue
- }
- break
- }
- // Generate the network query and send it to the peer
- if cap > maxTrieRequestCount {
- cap = maxTrieRequestCount
- }
- cap = int(float64(cap) / s.trienodeHealThrottle)
- if cap <= 0 {
- cap = 1
- }
- var (
- hashes = make([]common.Hash, 0, cap)
- paths = make([]string, 0, cap)
- pathsets = make([]TrieNodePathSet, 0, cap)
- )
- for path, hash := range s.healer.trieTasks {
- delete(s.healer.trieTasks, path)
-
- paths = append(paths, path)
- hashes = append(hashes, hash)
- if len(paths) >= cap {
- break
- }
- }
- // Group requests by account hash
- paths, hashes, _, pathsets = sortByAccountPath(paths, hashes)
- req := &trienodeHealRequest{
- peer: idle,
- id: reqid,
- time: time.Now(),
- deliver: success,
- revert: fail,
- cancel: cancel,
- stale: make(chan struct{}),
- paths: paths,
- hashes: hashes,
- task: s.healer,
- }
- req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
- peer.Log().Debug("Trienode heal request timed out", "reqid", reqid)
- s.rates.Update(idle, TrieNodesMsg, 0, 0)
- s.scheduleRevertTrienodeHealRequest(req)
- })
- s.trienodeHealReqs[reqid] = req
- delete(s.trienodeHealIdlers, idle)
-
- s.pend.Add(1)
- go func(root common.Hash) {
- defer s.pend.Done()
-
- // Attempt to send the remote request and revert if it fails
- if err := peer.RequestTrieNodes(reqid, root, pathsets, maxRequestSize); err != nil {
- log.Debug("Failed to request trienode healers", "err", err)
- s.scheduleRevertTrienodeHealRequest(req)
- }
- }(s.root)
- }
-}
-
-// assignBytecodeHealTasks attempts to match idle peers to bytecode requests to
-// heal any trie errors caused by the snap sync's chunked retrieval model.
-func (s *Syncer) assignBytecodeHealTasks(success chan *bytecodeHealResponse, fail chan *bytecodeHealRequest, cancel chan struct{}) {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- // Sort the peers by download capacity to use faster ones if many available
- idlers := &capacitySort{
- ids: make([]string, 0, len(s.bytecodeHealIdlers)),
- caps: make([]int, 0, len(s.bytecodeHealIdlers)),
- }
- targetTTL := s.rates.TargetTimeout()
- for id := range s.bytecodeHealIdlers {
- if _, ok := s.statelessPeers[id]; ok {
- continue
- }
- idlers.ids = append(idlers.ids, id)
- idlers.caps = append(idlers.caps, s.rates.Capacity(id, ByteCodesMsg, targetTTL))
- }
- if len(idlers.ids) == 0 {
- return
- }
- sort.Sort(sort.Reverse(idlers))
-
- // Iterate over pending tasks and try to find a peer to retrieve with
- for len(s.healer.codeTasks) > 0 || s.healer.scheduler.Pending() > 0 {
- // If there are not enough trie tasks queued to fully assign, fill the
- // queue from the state sync scheduler. The trie synced schedules these
- // together with trie nodes, so we need to queue them combined.
- var (
- have = len(s.healer.trieTasks) + len(s.healer.codeTasks)
- want = maxTrieRequestCount + maxCodeRequestCount
- )
- if have < want {
- paths, hashes, codes := s.healer.scheduler.Missing(want - have)
- for i, path := range paths {
- s.healer.trieTasks[path] = hashes[i]
- }
- for _, hash := range codes {
- s.healer.codeTasks[hash] = struct{}{}
- }
- }
- // If all the heal tasks are trienodes or already downloading, bail
- if len(s.healer.codeTasks) == 0 {
- return
- }
- // Task pending retrieval, try to find an idle peer. If no such peer
- // exists, we probably assigned tasks for all (or they are stateless).
- // Abort the entire assignment mechanism.
- if len(idlers.ids) == 0 {
- return
- }
- var (
- idle = idlers.ids[0]
- peer = s.peers[idle]
- cap = idlers.caps[0]
- )
- idlers.ids, idlers.caps = idlers.ids[1:], idlers.caps[1:]
-
- // Matched a pending task to an idle peer, allocate a unique request id
- var reqid uint64
- for {
- reqid = uint64(rand.Int63())
- if reqid == 0 {
- continue
- }
- if _, ok := s.bytecodeHealReqs[reqid]; ok {
- continue
- }
- break
- }
- // Generate the network query and send it to the peer
- if cap > maxCodeRequestCount {
- cap = maxCodeRequestCount
- }
- hashes := make([]common.Hash, 0, cap)
- for hash := range s.healer.codeTasks {
- delete(s.healer.codeTasks, hash)
-
- hashes = append(hashes, hash)
- if len(hashes) >= cap {
- break
- }
- }
- req := &bytecodeHealRequest{
- peer: idle,
- id: reqid,
- time: time.Now(),
- deliver: success,
- revert: fail,
- cancel: cancel,
- stale: make(chan struct{}),
- hashes: hashes,
- task: s.healer,
- }
- req.timeout = time.AfterFunc(s.rates.TargetTimeout(), func() {
- peer.Log().Debug("Bytecode heal request timed out", "reqid", reqid)
- s.rates.Update(idle, ByteCodesMsg, 0, 0)
- s.scheduleRevertBytecodeHealRequest(req)
- })
- s.bytecodeHealReqs[reqid] = req
- delete(s.bytecodeHealIdlers, idle)
-
- s.pend.Add(1)
- go func() {
- defer s.pend.Done()
-
- // Attempt to send the remote request and revert if it fails
- if err := peer.RequestByteCodes(reqid, hashes, maxRequestSize); err != nil {
- log.Debug("Failed to request bytecode healers", "err", err)
- s.scheduleRevertBytecodeHealRequest(req)
- }
- }()
- }
-}
-
-// revertRequests locates all the currently pending requests from a particular
-// peer and reverts them, rescheduling for others to fulfill.
-func (s *Syncer) revertRequests(peer string) {
- // Gather the requests first, revertals need the lock too
- s.lock.Lock()
- var accountReqs []*accountRequest
- for _, req := range s.accountReqs {
- if req.peer == peer {
- accountReqs = append(accountReqs, req)
- }
- }
- var bytecodeReqs []*bytecodeRequest
- for _, req := range s.bytecodeReqs {
- if req.peer == peer {
- bytecodeReqs = append(bytecodeReqs, req)
- }
- }
- var storageReqs []*storageRequest
- for _, req := range s.storageReqs {
- if req.peer == peer {
- storageReqs = append(storageReqs, req)
- }
- }
- var trienodeHealReqs []*trienodeHealRequest
- for _, req := range s.trienodeHealReqs {
- if req.peer == peer {
- trienodeHealReqs = append(trienodeHealReqs, req)
- }
- }
- var bytecodeHealReqs []*bytecodeHealRequest
- for _, req := range s.bytecodeHealReqs {
- if req.peer == peer {
- bytecodeHealReqs = append(bytecodeHealReqs, req)
- }
- }
- s.lock.Unlock()
-
- // Revert all the requests matching the peer
- for _, req := range accountReqs {
- s.revertAccountRequest(req)
- }
- for _, req := range bytecodeReqs {
- s.revertBytecodeRequest(req)
- }
- for _, req := range storageReqs {
- s.revertStorageRequest(req)
- }
- for _, req := range trienodeHealReqs {
- s.revertTrienodeHealRequest(req)
- }
- for _, req := range bytecodeHealReqs {
- s.revertBytecodeHealRequest(req)
- }
-}
-
-// scheduleRevertAccountRequest asks the event loop to clean up an account range
-// request and return all failed retrieval tasks to the scheduler for reassignment.
-func (s *Syncer) scheduleRevertAccountRequest(req *accountRequest) {
- select {
- case req.revert <- req:
- // Sync event loop notified
- case <-req.cancel:
- // Sync cycle got cancelled
- case <-req.stale:
- // Request already reverted
- }
-}
-
-// revertAccountRequest cleans up an account range request and returns all failed
-// retrieval tasks to the scheduler for reassignment.
-//
-// Note, this needs to run on the event runloop thread to reschedule to idle peers.
-// On peer threads, use scheduleRevertAccountRequest.
-func (s *Syncer) revertAccountRequest(req *accountRequest) {
- log.Debug("Reverting account request", "peer", req.peer, "reqid", req.id)
- select {
- case <-req.stale:
- log.Trace("Account request already reverted", "peer", req.peer, "reqid", req.id)
- return
- default:
- }
- close(req.stale)
-
- // Remove the request from the tracked set
- s.lock.Lock()
- delete(s.accountReqs, req.id)
- s.lock.Unlock()
-
- // If there's a timeout timer still running, abort it and mark the account
- // task as not-pending, ready for rescheduling
- req.timeout.Stop()
- if req.task.req == req {
- req.task.req = nil
- }
-}
-
-// scheduleRevertBytecodeRequest asks the event loop to clean up a bytecode request
-// and return all failed retrieval tasks to the scheduler for reassignment.
-func (s *Syncer) scheduleRevertBytecodeRequest(req *bytecodeRequest) {
- select {
- case req.revert <- req:
- // Sync event loop notified
- case <-req.cancel:
- // Sync cycle got cancelled
- case <-req.stale:
- // Request already reverted
- }
-}
-
-// revertBytecodeRequest cleans up a bytecode request and returns all failed
-// retrieval tasks to the scheduler for reassignment.
-//
-// Note, this needs to run on the event runloop thread to reschedule to idle peers.
-// On peer threads, use scheduleRevertBytecodeRequest.
-func (s *Syncer) revertBytecodeRequest(req *bytecodeRequest) {
- log.Debug("Reverting bytecode request", "peer", req.peer)
- select {
- case <-req.stale:
- log.Trace("Bytecode request already reverted", "peer", req.peer, "reqid", req.id)
- return
- default:
- }
- close(req.stale)
-
- // Remove the request from the tracked set
- s.lock.Lock()
- delete(s.bytecodeReqs, req.id)
- s.lock.Unlock()
-
- // If there's a timeout timer still running, abort it and mark the code
- // retrievals as not-pending, ready for rescheduling
- req.timeout.Stop()
- for _, hash := range req.hashes {
- req.task.codeTasks[hash] = struct{}{}
- }
-}
-
-// scheduleRevertStorageRequest asks the event loop to clean up a storage range
-// request and return all failed retrieval tasks to the scheduler for reassignment.
-func (s *Syncer) scheduleRevertStorageRequest(req *storageRequest) {
- select {
- case req.revert <- req:
- // Sync event loop notified
- case <-req.cancel:
- // Sync cycle got cancelled
- case <-req.stale:
- // Request already reverted
- }
-}
-
-// revertStorageRequest cleans up a storage range request and returns all failed
-// retrieval tasks to the scheduler for reassignment.
-//
-// Note, this needs to run on the event runloop thread to reschedule to idle peers.
-// On peer threads, use scheduleRevertStorageRequest.
-func (s *Syncer) revertStorageRequest(req *storageRequest) {
- log.Debug("Reverting storage request", "peer", req.peer)
- select {
- case <-req.stale:
- log.Trace("Storage request already reverted", "peer", req.peer, "reqid", req.id)
- return
- default:
- }
- close(req.stale)
-
- // Remove the request from the tracked set
- s.lock.Lock()
- delete(s.storageReqs, req.id)
- s.lock.Unlock()
-
- // If there's a timeout timer still running, abort it and mark the storage
- // task as not-pending, ready for rescheduling
- req.timeout.Stop()
- if req.subTask != nil {
- req.subTask.req = nil
- } else {
- for i, account := range req.accounts {
- req.mainTask.stateTasks[account] = req.roots[i]
- }
- }
-}
-
-// scheduleRevertTrienodeHealRequest asks the event loop to clean up a trienode heal
-// request and return all failed retrieval tasks to the scheduler for reassignment.
-func (s *Syncer) scheduleRevertTrienodeHealRequest(req *trienodeHealRequest) {
- select {
- case req.revert <- req:
- // Sync event loop notified
- case <-req.cancel:
- // Sync cycle got cancelled
- case <-req.stale:
- // Request already reverted
- }
-}
-
-// revertTrienodeHealRequest cleans up a trienode heal request and returns all
-// failed retrieval tasks to the scheduler for reassignment.
-//
-// Note, this needs to run on the event runloop thread to reschedule to idle peers.
-// On peer threads, use scheduleRevertTrienodeHealRequest.
-func (s *Syncer) revertTrienodeHealRequest(req *trienodeHealRequest) {
- log.Debug("Reverting trienode heal request", "peer", req.peer)
- select {
- case <-req.stale:
- log.Trace("Trienode heal request already reverted", "peer", req.peer, "reqid", req.id)
- return
- default:
- }
- close(req.stale)
-
- // Remove the request from the tracked set
- s.lock.Lock()
- delete(s.trienodeHealReqs, req.id)
- s.lock.Unlock()
-
- // If there's a timeout timer still running, abort it and mark the trie node
- // retrievals as not-pending, ready for rescheduling
- req.timeout.Stop()
- for i, path := range req.paths {
- req.task.trieTasks[path] = req.hashes[i]
- }
-}
-
-// scheduleRevertBytecodeHealRequest asks the event loop to clean up a bytecode heal
-// request and return all failed retrieval tasks to the scheduler for reassignment.
-func (s *Syncer) scheduleRevertBytecodeHealRequest(req *bytecodeHealRequest) {
- select {
- case req.revert <- req:
- // Sync event loop notified
- case <-req.cancel:
- // Sync cycle got cancelled
- case <-req.stale:
- // Request already reverted
- }
-}
-
-// revertBytecodeHealRequest cleans up a bytecode heal request and returns all
-// failed retrieval tasks to the scheduler for reassignment.
-//
-// Note, this needs to run on the event runloop thread to reschedule to idle peers.
-// On peer threads, use scheduleRevertBytecodeHealRequest.
-func (s *Syncer) revertBytecodeHealRequest(req *bytecodeHealRequest) {
- log.Debug("Reverting bytecode heal request", "peer", req.peer)
- select {
- case <-req.stale:
- log.Trace("Bytecode heal request already reverted", "peer", req.peer, "reqid", req.id)
- return
- default:
- }
- close(req.stale)
-
- // Remove the request from the tracked set
- s.lock.Lock()
- delete(s.bytecodeHealReqs, req.id)
- s.lock.Unlock()
-
- // If there's a timeout timer still running, abort it and mark the code
- // retrievals as not-pending, ready for rescheduling
- req.timeout.Stop()
- for _, hash := range req.hashes {
- req.task.codeTasks[hash] = struct{}{}
- }
-}
-
-// processAccountResponse integrates an already validated account range response
-// into the account tasks.
-func (s *Syncer) processAccountResponse(res *accountResponse) {
- // Switch the task from pending to filling
- res.task.req = nil
- res.task.res = res
-
- // Ensure that the response doesn't overflow into the subsequent task
- last := res.task.Last.Big()
- for i, hash := range res.hashes {
- // Mark the range complete if the last is already included.
- // Keep iteration to delete the extra states if exists.
- cmp := hash.Big().Cmp(last)
- if cmp == 0 {
- res.cont = false
- continue
- }
- if cmp > 0 {
- // Chunk overflown, cut off excess
- res.hashes = res.hashes[:i]
- res.accounts = res.accounts[:i]
- res.cont = false // Mark range completed
- break
- }
- }
- // Iterate over all the accounts and assemble which ones need further sub-
- // filling before the entire account range can be persisted.
- res.task.needCode = make([]bool, len(res.accounts))
- res.task.needState = make([]bool, len(res.accounts))
- res.task.needHeal = make([]bool, len(res.accounts))
-
- res.task.codeTasks = make(map[common.Hash]struct{})
- res.task.stateTasks = make(map[common.Hash]common.Hash)
-
- resumed := make(map[common.Hash]struct{})
-
- res.task.pend = 0
- for i, account := range res.accounts {
- // Check if the account is a contract with an unknown code
- if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
- if !rawdb.HasCodeWithPrefix(s.db, common.BytesToHash(account.CodeHash)) {
- res.task.codeTasks[common.BytesToHash(account.CodeHash)] = struct{}{}
- res.task.needCode[i] = true
- res.task.pend++
- }
- }
- // Check if the account is a contract with an unknown storage trie
- if account.Root != types.EmptyRootHash {
- if !rawdb.HasTrieNode(s.db, res.hashes[i], nil, account.Root, s.scheme) {
- // If there was a previous large state retrieval in progress,
- // don't restart it from scratch. This happens if a sync cycle
- // is interrupted and resumed later. However, *do* update the
- // previous root hash.
- if subtasks, ok := res.task.SubTasks[res.hashes[i]]; ok {
- log.Debug("Resuming large storage retrieval", "account", res.hashes[i], "root", account.Root)
- for _, subtask := range subtasks {
- subtask.root = account.Root
- }
- res.task.needHeal[i] = true
- resumed[res.hashes[i]] = struct{}{}
- } else {
- res.task.stateTasks[res.hashes[i]] = account.Root
- }
- res.task.needState[i] = true
- res.task.pend++
- }
- }
- }
- // Delete any subtasks that have been aborted but not resumed. This may undo
- // some progress if a new peer gives us less accounts than an old one, but for
- // now we have to live with that.
- for hash := range res.task.SubTasks {
- if _, ok := resumed[hash]; !ok {
- log.Debug("Aborting suspended storage retrieval", "account", hash)
- delete(res.task.SubTasks, hash)
- }
- }
- // If the account range contained no contracts, or all have been fully filled
- // beforehand, short circuit storage filling and forward to the next task
- if res.task.pend == 0 {
- s.forwardAccountTask(res.task)
- return
- }
- // Some accounts are incomplete, leave as is for the storage and contract
- // task assigners to pick up and fill
-}
-
-// processBytecodeResponse integrates an already validated bytecode response
-// into the account tasks.
-func (s *Syncer) processBytecodeResponse(res *bytecodeResponse) {
- batch := s.db.NewBatch()
-
- var (
- codes uint64
- )
- for i, hash := range res.hashes {
- code := res.codes[i]
-
- // If the bytecode was not delivered, reschedule it
- if code == nil {
- res.task.codeTasks[hash] = struct{}{}
- continue
- }
- // Code was delivered, mark it not needed any more
- for j, account := range res.task.res.accounts {
- if res.task.needCode[j] && hash == common.BytesToHash(account.CodeHash) {
- res.task.needCode[j] = false
- res.task.pend--
- }
- }
- // Push the bytecode into a database batch
- codes++
- rawdb.WriteCode(batch, hash, code)
- }
- bytes := common.StorageSize(batch.ValueSize())
- if err := batch.Write(); err != nil {
- log.Crit("Failed to persist bytecodes", "err", err)
- }
- s.bytecodeSynced += codes
- s.bytecodeBytes += bytes
-
- log.Debug("Persisted set of bytecodes", "count", codes, "bytes", bytes)
-
- // If this delivery completed the last pending task, forward the account task
- // to the next chunk
- if res.task.pend == 0 {
- s.forwardAccountTask(res.task)
- return
- }
- // Some accounts are still incomplete, leave as is for the storage and contract
- // task assigners to pick up and fill.
-}
-
-// processStorageResponse integrates an already validated storage response
-// into the account tasks.
-func (s *Syncer) processStorageResponse(res *storageResponse) {
- // Switch the subtask from pending to idle
- if res.subTask != nil {
- res.subTask.req = nil
- }
- batch := ethdb.HookedBatch{
- Batch: s.db.NewBatch(),
- OnPut: func(key []byte, value []byte) {
- s.storageBytes += common.StorageSize(len(key) + len(value))
- },
- }
- var (
- slots int
- oldStorageBytes = s.storageBytes
- )
- // Iterate over all the accounts and reconstruct their storage tries from the
- // delivered slots
- for i, account := range res.accounts {
- // If the account was not delivered, reschedule it
- if i >= len(res.hashes) {
- res.mainTask.stateTasks[account] = res.roots[i]
- continue
- }
- // State was delivered, if complete mark as not needed any more, otherwise
- // mark the account as needing healing
- for j, hash := range res.mainTask.res.hashes {
- if account != hash {
- continue
- }
- acc := res.mainTask.res.accounts[j]
-
- // If the packet contains multiple contract storage slots, all
- // but the last are surely complete. The last contract may be
- // chunked, so check it's continuation flag.
- if res.subTask == nil && res.mainTask.needState[j] && (i < len(res.hashes)-1 || !res.cont) {
- res.mainTask.needState[j] = false
- res.mainTask.pend--
- smallStorageGauge.Inc(1)
- }
- // If the last contract was chunked, mark it as needing healing
- // to avoid writing it out to disk prematurely.
- if res.subTask == nil && !res.mainTask.needHeal[j] && i == len(res.hashes)-1 && res.cont {
- res.mainTask.needHeal[j] = true
- }
- // If the last contract was chunked, we need to switch to large
- // contract handling mode
- if res.subTask == nil && i == len(res.hashes)-1 && res.cont {
- // If we haven't yet started a large-contract retrieval, create
- // the subtasks for it within the main account task
- if tasks, ok := res.mainTask.SubTasks[account]; !ok {
- var (
- keys = res.hashes[i]
- chunks = uint64(storageConcurrency)
- lastKey common.Hash
- )
- if len(keys) > 0 {
- lastKey = keys[len(keys)-1]
- }
- // If the number of slots remaining is low, decrease the
- // number of chunks. Somewhere on the order of 10-15K slots
- // fit into a packet of 500KB. A key/slot pair is maximum 64
- // bytes, so pessimistically maxRequestSize/64 = 8K.
- //
- // Chunk so that at least 2 packets are needed to fill a task.
- if estimate, err := estimateRemainingSlots(len(keys), lastKey); err == nil {
- if n := estimate / (2 * (maxRequestSize / 64)); n+1 < chunks {
- chunks = n + 1
- }
- log.Debug("Chunked large contract", "initiators", len(keys), "tail", lastKey, "remaining", estimate, "chunks", chunks)
- } else {
- log.Debug("Chunked large contract", "initiators", len(keys), "tail", lastKey, "chunks", chunks)
- }
- r := newHashRange(lastKey, chunks)
- if chunks == 1 {
- smallStorageGauge.Inc(1)
- } else {
- largeStorageGauge.Inc(1)
- }
- // Our first task is the one that was just filled by this response.
- batch := ethdb.HookedBatch{
- Batch: s.db.NewBatch(),
- OnPut: func(key []byte, value []byte) {
- s.storageBytes += common.StorageSize(len(key) + len(value))
- },
- }
- owner := account // local assignment for stacktrie writer closure
- options := trie.NewStackTrieOptions()
- options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) {
- rawdb.WriteTrieNode(batch, owner, path, hash, blob, s.scheme)
- })
- if s.scheme == rawdb.PathScheme {
- options = options.WithCleaner(func(path []byte) {
- s.cleanPath(batch, owner, path)
- })
- // Keep the left boundary as it's the first range.
- // Skip the right boundary if it's not the last range.
- options = options.WithSkipBoundary(false, r.End() != common.MaxHash, boundaryStorageNodesGauge)
- }
- tasks = append(tasks, &storageTask{
- Next: common.Hash{},
- Last: r.End(),
- root: acc.Root,
- genBatch: batch,
- genTrie: trie.NewStackTrie(options),
- })
- for r.Next() {
- batch := ethdb.HookedBatch{
- Batch: s.db.NewBatch(),
- OnPut: func(key []byte, value []byte) {
- s.storageBytes += common.StorageSize(len(key) + len(value))
- },
- }
- options := trie.NewStackTrieOptions()
- options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) {
- rawdb.WriteTrieNode(batch, owner, path, hash, blob, s.scheme)
- })
- if s.scheme == rawdb.PathScheme {
- // Configure the dangling node cleaner and also filter out boundary nodes
- // only in the context of the path scheme. Deletion is forbidden in the
- // hash scheme, as it can disrupt state completeness.
- options = options.WithCleaner(func(path []byte) {
- s.cleanPath(batch, owner, path)
- })
- // Skip the left boundary as it's not the first range
- // Skip the right boundary if it's not the last range.
- options = options.WithSkipBoundary(true, r.End() != common.MaxHash, boundaryStorageNodesGauge)
- }
- tasks = append(tasks, &storageTask{
- Next: r.Start(),
- Last: r.End(),
- root: acc.Root,
- genBatch: batch,
- genTrie: trie.NewStackTrie(options),
- })
- }
- for _, task := range tasks {
- log.Debug("Created storage sync task", "account", account, "root", acc.Root, "from", task.Next, "last", task.Last)
- }
- res.mainTask.SubTasks[account] = tasks
-
- // Since we've just created the sub-tasks, this response
- // is surely for the first one (zero origin)
- res.subTask = tasks[0]
- }
- }
- // If we're in large contract delivery mode, forward the subtask
- if res.subTask != nil {
- // Ensure the response doesn't overflow into the subsequent task
- last := res.subTask.Last.Big()
- // Find the first overflowing key. While at it, mark res as complete
- // if we find the range to include or pass the 'last'
- index := sort.Search(len(res.hashes[i]), func(k int) bool {
- cmp := res.hashes[i][k].Big().Cmp(last)
- if cmp >= 0 {
- res.cont = false
- }
- return cmp > 0
- })
- if index >= 0 {
- // cut off excess
- res.hashes[i] = res.hashes[i][:index]
- res.slots[i] = res.slots[i][:index]
- }
- // Forward the relevant storage chunk (even if created just now)
- if res.cont {
- res.subTask.Next = incHash(res.hashes[i][len(res.hashes[i])-1])
- } else {
- res.subTask.done = true
- }
- }
- }
- // Iterate over all the complete contracts, reconstruct the trie nodes and
- // push them to disk. If the contract is chunked, the trie nodes will be
- // reconstructed later.
- slots += len(res.hashes[i])
-
- if i < len(res.hashes)-1 || res.subTask == nil {
- // no need to make local reassignment of account: this closure does not outlive the loop
- options := trie.NewStackTrieOptions()
- options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) {
- rawdb.WriteTrieNode(batch, account, path, hash, blob, s.scheme)
- })
- if s.scheme == rawdb.PathScheme {
- // Configure the dangling node cleaner only in the context of the
- // path scheme. Deletion is forbidden in the hash scheme, as it can
- // disrupt state completeness.
- //
- // Notably, boundary nodes can be also kept because the whole storage
- // trie is complete.
- options = options.WithCleaner(func(path []byte) {
- s.cleanPath(batch, account, path)
- })
- }
- tr := trie.NewStackTrie(options)
- for j := 0; j < len(res.hashes[i]); j++ {
- tr.Update(res.hashes[i][j][:], res.slots[i][j])
- }
- tr.Commit()
- }
- // Persist the received storage segments. These flat state maybe
- // outdated during the sync, but it can be fixed later during the
- // snapshot generation.
- for j := 0; j < len(res.hashes[i]); j++ {
- rawdb.WriteStorageSnapshot(batch, account, res.hashes[i][j], res.slots[i][j])
-
- // If we're storing large contracts, generate the trie nodes
- // on the fly to not trash the gluing points
- if i == len(res.hashes)-1 && res.subTask != nil {
- res.subTask.genTrie.Update(res.hashes[i][j][:], res.slots[i][j])
- }
- }
- }
- // Large contracts could have generated new trie nodes, flush them to disk
- if res.subTask != nil {
- if res.subTask.done {
- root := res.subTask.genTrie.Commit()
- if err := res.subTask.genBatch.Write(); err != nil {
- log.Error("Failed to persist stack slots", "err", err)
- }
- res.subTask.genBatch.Reset()
-
- // If the chunk's root is an overflown but full delivery,
- // clear the heal request.
- accountHash := res.accounts[len(res.accounts)-1]
- if root == res.subTask.root && rawdb.HasStorageTrieNode(s.db, accountHash, nil, root) {
- for i, account := range res.mainTask.res.hashes {
- if account == accountHash {
- res.mainTask.needHeal[i] = false
- skipStorageHealingGauge.Inc(1)
- }
- }
- }
- }
- if res.subTask.genBatch.ValueSize() > ethdb.IdealBatchSize {
- if err := res.subTask.genBatch.Write(); err != nil {
- log.Error("Failed to persist stack slots", "err", err)
- }
- res.subTask.genBatch.Reset()
- }
- }
- // Flush anything written just now and update the stats
- if err := batch.Write(); err != nil {
- log.Crit("Failed to persist storage slots", "err", err)
- }
- s.storageSynced += uint64(slots)
-
- log.Debug("Persisted set of storage slots", "accounts", len(res.hashes), "slots", slots, "bytes", s.storageBytes-oldStorageBytes)
-
- // If this delivery completed the last pending task, forward the account task
- // to the next chunk
- if res.mainTask.pend == 0 {
- s.forwardAccountTask(res.mainTask)
- return
- }
- // Some accounts are still incomplete, leave as is for the storage and contract
- // task assigners to pick up and fill.
-}
-
-// processTrienodeHealResponse integrates an already validated trienode response
-// into the healer tasks.
-func (s *Syncer) processTrienodeHealResponse(res *trienodeHealResponse) {
- var (
- start = time.Now()
- fills int
- )
- for i, hash := range res.hashes {
- node := res.nodes[i]
-
- // If the trie node was not delivered, reschedule it
- if node == nil {
- res.task.trieTasks[res.paths[i]] = res.hashes[i]
- continue
- }
- fills++
-
- // Push the trie node into the state syncer
- s.trienodeHealSynced++
- s.trienodeHealBytes += common.StorageSize(len(node))
-
- err := s.healer.scheduler.ProcessNode(trie.NodeSyncResult{Path: res.paths[i], Data: node})
- switch err {
- case nil:
- case trie.ErrAlreadyProcessed:
- s.trienodeHealDups++
- case trie.ErrNotRequested:
- s.trienodeHealNops++
- default:
- log.Error("Invalid trienode processed", "hash", hash, "err", err)
- }
- }
- s.commitHealer(false)
-
- // Calculate the processing rate of one filled trie node
- rate := float64(fills) / (float64(time.Since(start)) / float64(time.Second))
-
- // Update the currently measured trienode queueing and processing throughput.
- //
- // The processing rate needs to be updated uniformly independent if we've
- // processed 1x100 trie nodes or 100x1 to keep the rate consistent even in
- // the face of varying network packets. As such, we cannot just measure the
- // time it took to process N trie nodes and update once, we need one update
- // per trie node.
- //
- // Naively, that would be:
- //
- // for i:=0; i time.Second {
- // Periodically adjust the trie node throttler
- if float64(pending) > 2*s.trienodeHealRate {
- s.trienodeHealThrottle *= trienodeHealThrottleIncrease
- } else {
- s.trienodeHealThrottle /= trienodeHealThrottleDecrease
- }
- if s.trienodeHealThrottle > maxTrienodeHealThrottle {
- s.trienodeHealThrottle = maxTrienodeHealThrottle
- } else if s.trienodeHealThrottle < minTrienodeHealThrottle {
- s.trienodeHealThrottle = minTrienodeHealThrottle
- }
- s.trienodeHealThrottled = time.Now()
-
- log.Debug("Updated trie node heal throttler", "rate", s.trienodeHealRate, "pending", pending, "throttle", s.trienodeHealThrottle)
- }
-}
-
-func (s *Syncer) commitHealer(force bool) {
- if !force && s.healer.scheduler.MemSize() < ethdb.IdealBatchSize {
- return
- }
- batch := s.db.NewBatch()
- if err := s.healer.scheduler.Commit(batch); err != nil {
- log.Error("Failed to commit healing data", "err", err)
- }
- if err := batch.Write(); err != nil {
- log.Crit("Failed to persist healing data", "err", err)
- }
- log.Debug("Persisted set of healing data", "type", "trienodes", "bytes", common.StorageSize(batch.ValueSize()))
-}
-
-// processBytecodeHealResponse integrates an already validated bytecode response
-// into the healer tasks.
-func (s *Syncer) processBytecodeHealResponse(res *bytecodeHealResponse) {
- for i, hash := range res.hashes {
- node := res.codes[i]
-
- // If the trie node was not delivered, reschedule it
- if node == nil {
- res.task.codeTasks[hash] = struct{}{}
- continue
- }
- // Push the trie node into the state syncer
- s.bytecodeHealSynced++
- s.bytecodeHealBytes += common.StorageSize(len(node))
-
- err := s.healer.scheduler.ProcessCode(trie.CodeSyncResult{Hash: hash, Data: node})
- switch err {
- case nil:
- case trie.ErrAlreadyProcessed:
- s.bytecodeHealDups++
- case trie.ErrNotRequested:
- s.bytecodeHealNops++
- default:
- log.Error("Invalid bytecode processed", "hash", hash, "err", err)
- }
- }
- s.commitHealer(false)
-}
-
-// forwardAccountTask takes a filled account task and persists anything available
-// into the database, after which it forwards the next account marker so that the
-// task's next chunk may be filled.
-func (s *Syncer) forwardAccountTask(task *accountTask) {
- // Remove any pending delivery
- res := task.res
- if res == nil {
- return // nothing to forward
- }
- task.res = nil
-
- // Persist the received account segments. These flat state maybe
- // outdated during the sync, but it can be fixed later during the
- // snapshot generation.
- oldAccountBytes := s.accountBytes
-
- batch := ethdb.HookedBatch{
- Batch: s.db.NewBatch(),
- OnPut: func(key []byte, value []byte) {
- s.accountBytes += common.StorageSize(len(key) + len(value))
- },
- }
- for i, hash := range res.hashes {
- if task.needCode[i] || task.needState[i] {
- break
- }
- slim := types.SlimAccountRLP(*res.accounts[i])
- rawdb.WriteAccountSnapshot(batch, hash, slim)
-
- // If the task is complete, drop it into the stack trie to generate
- // account trie nodes for it
- if !task.needHeal[i] {
- full, err := types.FullAccountRLP(slim) // TODO(karalabe): Slim parsing can be omitted
- if err != nil {
- panic(err) // Really shouldn't ever happen
- }
- task.genTrie.Update(hash[:], full)
- }
- }
- // Flush anything written just now and update the stats
- if err := batch.Write(); err != nil {
- log.Crit("Failed to persist accounts", "err", err)
- }
- s.accountSynced += uint64(len(res.accounts))
-
- // Task filling persisted, push it the chunk marker forward to the first
- // account still missing data.
- for i, hash := range res.hashes {
- if task.needCode[i] || task.needState[i] {
- return
- }
- task.Next = incHash(hash)
- }
- // All accounts marked as complete, track if the entire task is done
- task.done = !res.cont
-
- // Stack trie could have generated trie nodes, push them to disk (we need to
- // flush after finalizing task.done. It's fine even if we crash and lose this
- // write as it will only cause more data to be downloaded during heal.
- if task.done {
- task.genTrie.Commit()
- }
- if task.genBatch.ValueSize() > ethdb.IdealBatchSize || task.done {
- if err := task.genBatch.Write(); err != nil {
- log.Error("Failed to persist stack account", "err", err)
- }
- task.genBatch.Reset()
- }
- log.Debug("Persisted range of accounts", "accounts", len(res.accounts), "bytes", s.accountBytes-oldAccountBytes)
-}
-
-// OnAccounts is a callback method to invoke when a range of accounts are
-// received from a remote peer.
-func (s *Syncer) OnAccounts(peer SyncPeer, id uint64, hashes []common.Hash, accounts [][]byte, proof [][]byte) error {
- size := common.StorageSize(len(hashes) * common.HashLength)
- for _, account := range accounts {
- size += common.StorageSize(len(account))
- }
- for _, node := range proof {
- size += common.StorageSize(len(node))
- }
- logger := peer.Log().New("reqid", id)
- logger.Trace("Delivering range of accounts", "hashes", len(hashes), "accounts", len(accounts), "proofs", len(proof), "bytes", size)
-
- // Whether or not the response is valid, we can mark the peer as idle and
- // notify the scheduler to assign a new task. If the response is invalid,
- // we'll drop the peer in a bit.
- defer func() {
- s.lock.Lock()
- defer s.lock.Unlock()
- if _, ok := s.peers[peer.ID()]; ok {
- s.accountIdlers[peer.ID()] = struct{}{}
- }
- select {
- case s.update <- struct{}{}:
- default:
- }
- }()
- s.lock.Lock()
- // Ensure the response is for a valid request
- req, ok := s.accountReqs[id]
- if !ok {
- // Request stale, perhaps the peer timed out but came through in the end
- logger.Warn("Unexpected account range packet")
- s.lock.Unlock()
- return nil
- }
- delete(s.accountReqs, id)
- s.rates.Update(peer.ID(), AccountRangeMsg, time.Since(req.time), int(size))
-
- // Clean up the request timeout timer, we'll see how to proceed further based
- // on the actual delivered content
- if !req.timeout.Stop() {
- // The timeout is already triggered, and this request will be reverted+rescheduled
- s.lock.Unlock()
- return nil
- }
- // Response is valid, but check if peer is signalling that it does not have
- // the requested data. For account range queries that means the state being
- // retrieved was either already pruned remotely, or the peer is not yet
- // synced to our head.
- if len(hashes) == 0 && len(accounts) == 0 && len(proof) == 0 {
- logger.Debug("Peer rejected account range request", "root", s.root)
- s.statelessPeers[peer.ID()] = struct{}{}
- s.lock.Unlock()
-
- // Signal this request as failed, and ready for rescheduling
- s.scheduleRevertAccountRequest(req)
- return nil
- }
- root := s.root
- s.lock.Unlock()
-
- // Reconstruct a partial trie from the response and verify it
- keys := make([][]byte, len(hashes))
- for i, key := range hashes {
- keys[i] = common.CopyBytes(key[:])
- }
- nodes := make(trienode.ProofList, len(proof))
- for i, node := range proof {
- nodes[i] = node
- }
- cont, err := trie.VerifyRangeProof(root, req.origin[:], keys, accounts, nodes.Set())
- if err != nil {
- logger.Warn("Account range failed proof", "err", err)
- // Signal this request as failed, and ready for rescheduling
- s.scheduleRevertAccountRequest(req)
- return err
- }
- accs := make([]*types.StateAccount, len(accounts))
- for i, account := range accounts {
- acc := new(types.StateAccount)
- if err := rlp.DecodeBytes(account, acc); err != nil {
- panic(err) // We created these blobs, we must be able to decode them
- }
- accs[i] = acc
- }
- response := &accountResponse{
- task: req.task,
- hashes: hashes,
- accounts: accs,
- cont: cont,
- }
- select {
- case req.deliver <- response:
- case <-req.cancel:
- case <-req.stale:
- }
- return nil
-}
-
-// OnByteCodes is a callback method to invoke when a batch of contract
-// bytes codes are received from a remote peer.
-func (s *Syncer) OnByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) error {
- s.lock.RLock()
- syncing := !s.snapped
- s.lock.RUnlock()
-
- if syncing {
- return s.onByteCodes(peer, id, bytecodes)
- }
- return s.onHealByteCodes(peer, id, bytecodes)
-}
-
-// onByteCodes is a callback method to invoke when a batch of contract
-// bytes codes are received from a remote peer in the syncing phase.
-func (s *Syncer) onByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) error {
- var size common.StorageSize
- for _, code := range bytecodes {
- size += common.StorageSize(len(code))
- }
- logger := peer.Log().New("reqid", id)
- logger.Trace("Delivering set of bytecodes", "bytecodes", len(bytecodes), "bytes", size)
-
- // Whether or not the response is valid, we can mark the peer as idle and
- // notify the scheduler to assign a new task. If the response is invalid,
- // we'll drop the peer in a bit.
- defer func() {
- s.lock.Lock()
- defer s.lock.Unlock()
- if _, ok := s.peers[peer.ID()]; ok {
- s.bytecodeIdlers[peer.ID()] = struct{}{}
- }
- select {
- case s.update <- struct{}{}:
- default:
- }
- }()
- s.lock.Lock()
- // Ensure the response is for a valid request
- req, ok := s.bytecodeReqs[id]
- if !ok {
- // Request stale, perhaps the peer timed out but came through in the end
- logger.Warn("Unexpected bytecode packet")
- s.lock.Unlock()
- return nil
- }
- delete(s.bytecodeReqs, id)
- s.rates.Update(peer.ID(), ByteCodesMsg, time.Since(req.time), len(bytecodes))
-
- // Clean up the request timeout timer, we'll see how to proceed further based
- // on the actual delivered content
- if !req.timeout.Stop() {
- // The timeout is already triggered, and this request will be reverted+rescheduled
- s.lock.Unlock()
- return nil
- }
-
- // Response is valid, but check if peer is signalling that it does not have
- // the requested data. For bytecode range queries that means the peer is not
- // yet synced.
- if len(bytecodes) == 0 {
- logger.Debug("Peer rejected bytecode request")
- s.statelessPeers[peer.ID()] = struct{}{}
- s.lock.Unlock()
-
- // Signal this request as failed, and ready for rescheduling
- s.scheduleRevertBytecodeRequest(req)
- return nil
- }
- s.lock.Unlock()
-
- // Cross reference the requested bytecodes with the response to find gaps
- // that the serving node is missing
- hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
- hash := make([]byte, 32)
-
- codes := make([][]byte, len(req.hashes))
- for i, j := 0, 0; i < len(bytecodes); i++ {
- // Find the next hash that we've been served, leaving misses with nils
- hasher.Reset()
- hasher.Write(bytecodes[i])
- hasher.Read(hash)
-
- for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) {
- j++
- }
- if j < len(req.hashes) {
- codes[j] = bytecodes[i]
- j++
- continue
- }
- // We've either ran out of hashes, or got unrequested data
- logger.Warn("Unexpected bytecodes", "count", len(bytecodes)-i)
- // Signal this request as failed, and ready for rescheduling
- s.scheduleRevertBytecodeRequest(req)
- return errors.New("unexpected bytecode")
- }
- // Response validated, send it to the scheduler for filling
- response := &bytecodeResponse{
- task: req.task,
- hashes: req.hashes,
- codes: codes,
- }
- select {
- case req.deliver <- response:
- case <-req.cancel:
- case <-req.stale:
- }
- return nil
-}
-
-// OnStorage is a callback method to invoke when ranges of storage slots
-// are received from a remote peer.
-func (s *Syncer) OnStorage(peer SyncPeer, id uint64, hashes [][]common.Hash, slots [][][]byte, proof [][]byte) error {
- // Gather some trace stats to aid in debugging issues
- var (
- hashCount int
- slotCount int
- size common.StorageSize
- )
- for _, hashset := range hashes {
- size += common.StorageSize(common.HashLength * len(hashset))
- hashCount += len(hashset)
- }
- for _, slotset := range slots {
- for _, slot := range slotset {
- size += common.StorageSize(len(slot))
- }
- slotCount += len(slotset)
- }
- for _, node := range proof {
- size += common.StorageSize(len(node))
- }
- logger := peer.Log().New("reqid", id)
- logger.Trace("Delivering ranges of storage slots", "accounts", len(hashes), "hashes", hashCount, "slots", slotCount, "proofs", len(proof), "size", size)
-
- // Whether or not the response is valid, we can mark the peer as idle and
- // notify the scheduler to assign a new task. If the response is invalid,
- // we'll drop the peer in a bit.
- defer func() {
- s.lock.Lock()
- defer s.lock.Unlock()
- if _, ok := s.peers[peer.ID()]; ok {
- s.storageIdlers[peer.ID()] = struct{}{}
- }
- select {
- case s.update <- struct{}{}:
- default:
- }
- }()
- s.lock.Lock()
- // Ensure the response is for a valid request
- req, ok := s.storageReqs[id]
- if !ok {
- // Request stale, perhaps the peer timed out but came through in the end
- logger.Warn("Unexpected storage ranges packet")
- s.lock.Unlock()
- return nil
- }
- delete(s.storageReqs, id)
- s.rates.Update(peer.ID(), StorageRangesMsg, time.Since(req.time), int(size))
-
- // Clean up the request timeout timer, we'll see how to proceed further based
- // on the actual delivered content
- if !req.timeout.Stop() {
- // The timeout is already triggered, and this request will be reverted+rescheduled
- s.lock.Unlock()
- return nil
- }
-
- // Reject the response if the hash sets and slot sets don't match, or if the
- // peer sent more data than requested.
- if len(hashes) != len(slots) {
- s.lock.Unlock()
- s.scheduleRevertStorageRequest(req) // reschedule request
- logger.Warn("Hash and slot set size mismatch", "hashset", len(hashes), "slotset", len(slots))
- return errors.New("hash and slot set size mismatch")
- }
- if len(hashes) > len(req.accounts) {
- s.lock.Unlock()
- s.scheduleRevertStorageRequest(req) // reschedule request
- logger.Warn("Hash set larger than requested", "hashset", len(hashes), "requested", len(req.accounts))
- return errors.New("hash set larger than requested")
- }
- // Response is valid, but check if peer is signalling that it does not have
- // the requested data. For storage range queries that means the state being
- // retrieved was either already pruned remotely, or the peer is not yet
- // synced to our head.
- if len(hashes) == 0 && len(proof) == 0 {
- logger.Debug("Peer rejected storage request")
- s.statelessPeers[peer.ID()] = struct{}{}
- s.lock.Unlock()
- s.scheduleRevertStorageRequest(req) // reschedule request
- return nil
- }
- s.lock.Unlock()
-
- // Reconstruct the partial tries from the response and verify them
- var cont bool
-
- // If a proof was attached while the response is empty, it indicates that the
- // requested range specified with 'origin' is empty. Construct an empty state
- // response locally to finalize the range.
- if len(hashes) == 0 && len(proof) > 0 {
- hashes = append(hashes, []common.Hash{})
- slots = append(slots, [][]byte{})
- }
- for i := 0; i < len(hashes); i++ {
- // Convert the keys and proofs into an internal format
- keys := make([][]byte, len(hashes[i]))
- for j, key := range hashes[i] {
- keys[j] = common.CopyBytes(key[:])
- }
- nodes := make(trienode.ProofList, 0, len(proof))
- if i == len(hashes)-1 {
- for _, node := range proof {
- nodes = append(nodes, node)
- }
- }
- var err error
- if len(nodes) == 0 {
- // No proof has been attached, the response must cover the entire key
- // space and hash to the origin root.
- _, err = trie.VerifyRangeProof(req.roots[i], nil, keys, slots[i], nil)
- if err != nil {
- s.scheduleRevertStorageRequest(req) // reschedule request
- logger.Warn("Storage slots failed proof", "err", err)
- return err
- }
- } else {
- // A proof was attached, the response is only partial, check that the
- // returned data is indeed part of the storage trie
- proofdb := nodes.Set()
-
- cont, err = trie.VerifyRangeProof(req.roots[i], req.origin[:], keys, slots[i], proofdb)
- if err != nil {
- s.scheduleRevertStorageRequest(req) // reschedule request
- logger.Warn("Storage range failed proof", "err", err)
- return err
- }
- }
- }
- // Partial tries reconstructed, send them to the scheduler for storage filling
- response := &storageResponse{
- mainTask: req.mainTask,
- subTask: req.subTask,
- accounts: req.accounts,
- roots: req.roots,
- hashes: hashes,
- slots: slots,
- cont: cont,
- }
- select {
- case req.deliver <- response:
- case <-req.cancel:
- case <-req.stale:
- }
- return nil
-}
-
-// OnTrieNodes is a callback method to invoke when a batch of trie nodes
-// are received from a remote peer.
-func (s *Syncer) OnTrieNodes(peer SyncPeer, id uint64, trienodes [][]byte) error {
- var size common.StorageSize
- for _, node := range trienodes {
- size += common.StorageSize(len(node))
- }
- logger := peer.Log().New("reqid", id)
- logger.Trace("Delivering set of healing trienodes", "trienodes", len(trienodes), "bytes", size)
-
- // Whether or not the response is valid, we can mark the peer as idle and
- // notify the scheduler to assign a new task. If the response is invalid,
- // we'll drop the peer in a bit.
- defer func() {
- s.lock.Lock()
- defer s.lock.Unlock()
- if _, ok := s.peers[peer.ID()]; ok {
- s.trienodeHealIdlers[peer.ID()] = struct{}{}
- }
- select {
- case s.update <- struct{}{}:
- default:
- }
- }()
- s.lock.Lock()
- // Ensure the response is for a valid request
- req, ok := s.trienodeHealReqs[id]
- if !ok {
- // Request stale, perhaps the peer timed out but came through in the end
- logger.Warn("Unexpected trienode heal packet")
- s.lock.Unlock()
- return nil
- }
- delete(s.trienodeHealReqs, id)
- s.rates.Update(peer.ID(), TrieNodesMsg, time.Since(req.time), len(trienodes))
-
- // Clean up the request timeout timer, we'll see how to proceed further based
- // on the actual delivered content
- if !req.timeout.Stop() {
- // The timeout is already triggered, and this request will be reverted+rescheduled
- s.lock.Unlock()
- return nil
- }
-
- // Response is valid, but check if peer is signalling that it does not have
- // the requested data. For bytecode range queries that means the peer is not
- // yet synced.
- if len(trienodes) == 0 {
- logger.Debug("Peer rejected trienode heal request")
- s.statelessPeers[peer.ID()] = struct{}{}
- s.lock.Unlock()
-
- // Signal this request as failed, and ready for rescheduling
- s.scheduleRevertTrienodeHealRequest(req)
- return nil
- }
- s.lock.Unlock()
-
- // Cross reference the requested trienodes with the response to find gaps
- // that the serving node is missing
- var (
- hasher = sha3.NewLegacyKeccak256().(crypto.KeccakState)
- hash = make([]byte, 32)
- nodes = make([][]byte, len(req.hashes))
- fills uint64
- )
- for i, j := 0, 0; i < len(trienodes); i++ {
- // Find the next hash that we've been served, leaving misses with nils
- hasher.Reset()
- hasher.Write(trienodes[i])
- hasher.Read(hash)
-
- for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) {
- j++
- }
- if j < len(req.hashes) {
- nodes[j] = trienodes[i]
- fills++
- j++
- continue
- }
- // We've either ran out of hashes, or got unrequested data
- logger.Warn("Unexpected healing trienodes", "count", len(trienodes)-i)
-
- // Signal this request as failed, and ready for rescheduling
- s.scheduleRevertTrienodeHealRequest(req)
- return errors.New("unexpected healing trienode")
- }
- // Response validated, send it to the scheduler for filling
- s.trienodeHealPend.Add(fills)
- defer func() {
- s.trienodeHealPend.Add(^(fills - 1))
- }()
- response := &trienodeHealResponse{
- paths: req.paths,
- task: req.task,
- hashes: req.hashes,
- nodes: nodes,
- }
- select {
- case req.deliver <- response:
- case <-req.cancel:
- case <-req.stale:
- }
- return nil
-}
-
-// onHealByteCodes is a callback method to invoke when a batch of contract
-// bytes codes are received from a remote peer in the healing phase.
-func (s *Syncer) onHealByteCodes(peer SyncPeer, id uint64, bytecodes [][]byte) error {
- var size common.StorageSize
- for _, code := range bytecodes {
- size += common.StorageSize(len(code))
- }
- logger := peer.Log().New("reqid", id)
- logger.Trace("Delivering set of healing bytecodes", "bytecodes", len(bytecodes), "bytes", size)
-
- // Whether or not the response is valid, we can mark the peer as idle and
- // notify the scheduler to assign a new task. If the response is invalid,
- // we'll drop the peer in a bit.
- defer func() {
- s.lock.Lock()
- defer s.lock.Unlock()
- if _, ok := s.peers[peer.ID()]; ok {
- s.bytecodeHealIdlers[peer.ID()] = struct{}{}
- }
- select {
- case s.update <- struct{}{}:
- default:
- }
- }()
- s.lock.Lock()
- // Ensure the response is for a valid request
- req, ok := s.bytecodeHealReqs[id]
- if !ok {
- // Request stale, perhaps the peer timed out but came through in the end
- logger.Warn("Unexpected bytecode heal packet")
- s.lock.Unlock()
- return nil
- }
- delete(s.bytecodeHealReqs, id)
- s.rates.Update(peer.ID(), ByteCodesMsg, time.Since(req.time), len(bytecodes))
-
- // Clean up the request timeout timer, we'll see how to proceed further based
- // on the actual delivered content
- if !req.timeout.Stop() {
- // The timeout is already triggered, and this request will be reverted+rescheduled
- s.lock.Unlock()
- return nil
- }
-
- // Response is valid, but check if peer is signalling that it does not have
- // the requested data. For bytecode range queries that means the peer is not
- // yet synced.
- if len(bytecodes) == 0 {
- logger.Debug("Peer rejected bytecode heal request")
- s.statelessPeers[peer.ID()] = struct{}{}
- s.lock.Unlock()
-
- // Signal this request as failed, and ready for rescheduling
- s.scheduleRevertBytecodeHealRequest(req)
- return nil
- }
- s.lock.Unlock()
-
- // Cross reference the requested bytecodes with the response to find gaps
- // that the serving node is missing
- hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
- hash := make([]byte, 32)
-
- codes := make([][]byte, len(req.hashes))
- for i, j := 0, 0; i < len(bytecodes); i++ {
- // Find the next hash that we've been served, leaving misses with nils
- hasher.Reset()
- hasher.Write(bytecodes[i])
- hasher.Read(hash)
-
- for j < len(req.hashes) && !bytes.Equal(hash, req.hashes[j][:]) {
- j++
- }
- if j < len(req.hashes) {
- codes[j] = bytecodes[i]
- j++
- continue
- }
- // We've either ran out of hashes, or got unrequested data
- logger.Warn("Unexpected healing bytecodes", "count", len(bytecodes)-i)
- // Signal this request as failed, and ready for rescheduling
- s.scheduleRevertBytecodeHealRequest(req)
- return errors.New("unexpected healing bytecode")
- }
- // Response validated, send it to the scheduler for filling
- response := &bytecodeHealResponse{
- task: req.task,
- hashes: req.hashes,
- codes: codes,
- }
- select {
- case req.deliver <- response:
- case <-req.cancel:
- case <-req.stale:
- }
- return nil
-}
-
-// onHealState is a callback method to invoke when a flat state(account
-// or storage slot) is downloaded during the healing stage. The flat states
-// can be persisted blindly and can be fixed later in the generation stage.
-// Note it's not concurrent safe, please handle the concurrent issue outside.
-func (s *Syncer) onHealState(paths [][]byte, value []byte) error {
- if len(paths) == 1 {
- var account types.StateAccount
- if err := rlp.DecodeBytes(value, &account); err != nil {
- return nil // Returning the error here would drop the remote peer
- }
- blob := types.SlimAccountRLP(account)
- rawdb.WriteAccountSnapshot(s.stateWriter, common.BytesToHash(paths[0]), blob)
- s.accountHealed += 1
- s.accountHealedBytes += common.StorageSize(1 + common.HashLength + len(blob))
- }
- if len(paths) == 2 {
- rawdb.WriteStorageSnapshot(s.stateWriter, common.BytesToHash(paths[0]), common.BytesToHash(paths[1]), value)
- s.storageHealed += 1
- s.storageHealedBytes += common.StorageSize(1 + 2*common.HashLength + len(value))
- }
- if s.stateWriter.ValueSize() > ethdb.IdealBatchSize {
- s.stateWriter.Write() // It's fine to ignore the error here
- s.stateWriter.Reset()
- }
- return nil
-}
-
-// hashSpace is the total size of the 256 bit hash space for accounts.
-var hashSpace = new(big.Int).Exp(common.Big2, common.Big256, nil)
-
-// report calculates various status reports and provides it to the user.
-func (s *Syncer) report(force bool) {
- if len(s.tasks) > 0 {
- s.reportSyncProgress(force)
- return
- }
- s.reportHealProgress(force)
-}
-
-// reportSyncProgress calculates various status reports and provides it to the user.
-func (s *Syncer) reportSyncProgress(force bool) {
- // Don't report all the events, just occasionally
- if !force && time.Since(s.logTime) < 8*time.Second {
- return
- }
- // Don't report anything until we have a meaningful progress
- synced := s.accountBytes + s.bytecodeBytes + s.storageBytes
- if synced == 0 {
- return
- }
- accountGaps := new(big.Int)
- for _, task := range s.tasks {
- accountGaps.Add(accountGaps, new(big.Int).Sub(task.Last.Big(), task.Next.Big()))
- }
- accountFills := new(big.Int).Sub(hashSpace, accountGaps)
- if accountFills.BitLen() == 0 {
- return
- }
- s.logTime = time.Now()
- estBytes := float64(new(big.Int).Div(
- new(big.Int).Mul(new(big.Int).SetUint64(uint64(synced)), hashSpace),
- accountFills,
- ).Uint64())
- // Don't report anything until we have a meaningful progress
- if estBytes < 1.0 {
- return
- }
- elapsed := time.Since(s.startTime)
- estTime := elapsed / time.Duration(synced) * time.Duration(estBytes)
-
- // Create a mega progress report
- var (
- progress = fmt.Sprintf("%.2f%%", float64(synced)*100/estBytes)
- accounts = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(s.accountSynced), s.accountBytes.TerminalString())
- storage = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(s.storageSynced), s.storageBytes.TerminalString())
- bytecode = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(s.bytecodeSynced), s.bytecodeBytes.TerminalString())
- )
- log.Info("Syncing: state download in progress", "synced", progress, "state", synced,
- "accounts", accounts, "slots", storage, "codes", bytecode, "eta", common.PrettyDuration(estTime-elapsed))
-}
-
-// reportHealProgress calculates various status reports and provides it to the user.
-func (s *Syncer) reportHealProgress(force bool) {
- // Don't report all the events, just occasionally
- if !force && time.Since(s.logTime) < 8*time.Second {
- return
- }
- s.logTime = time.Now()
-
- // Create a mega progress report
- var (
- trienode = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(s.trienodeHealSynced), s.trienodeHealBytes.TerminalString())
- bytecode = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(s.bytecodeHealSynced), s.bytecodeHealBytes.TerminalString())
- accounts = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(s.accountHealed), s.accountHealedBytes.TerminalString())
- storage = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(s.storageHealed), s.storageHealedBytes.TerminalString())
- )
- log.Info("Syncing: state healing in progress", "accounts", accounts, "slots", storage,
- "codes", bytecode, "nodes", trienode, "pending", s.healer.scheduler.Pending())
-}
-
-// estimateRemainingSlots tries to determine roughly how many slots are left in
-// a contract storage, based on the number of keys and the last hash. This method
-// assumes that the hashes are lexicographically ordered and evenly distributed.
-func estimateRemainingSlots(hashes int, last common.Hash) (uint64, error) {
- if last == (common.Hash{}) {
- return 0, errors.New("last hash empty")
- }
- space := new(big.Int).Mul(math.MaxBig256, big.NewInt(int64(hashes)))
- space.Div(space, last.Big())
- if !space.IsUint64() {
- // Gigantic address space probably due to too few or malicious slots
- return 0, errors.New("too few slots for estimation")
- }
- return space.Uint64() - uint64(hashes), nil
-}
-
-// capacitySort implements the Sort interface, allowing sorting by peer message
-// throughput. Note, callers should use sort.Reverse to get the desired effect
-// of highest capacity being at the front.
-type capacitySort struct {
- ids []string
- caps []int
-}
-
-func (s *capacitySort) Len() int {
- return len(s.ids)
-}
-
-func (s *capacitySort) Less(i, j int) bool {
- return s.caps[i] < s.caps[j]
-}
-
-func (s *capacitySort) Swap(i, j int) {
- s.ids[i], s.ids[j] = s.ids[j], s.ids[i]
- s.caps[i], s.caps[j] = s.caps[j], s.caps[i]
-}
-
-// healRequestSort implements the Sort interface, allowing sorting trienode
-// heal requests, which is a prerequisite for merging storage-requests.
-type healRequestSort struct {
- paths []string
- hashes []common.Hash
- syncPaths []trie.SyncPath
-}
-
-func (t *healRequestSort) Len() int {
- return len(t.hashes)
-}
-
-func (t *healRequestSort) Less(i, j int) bool {
- a := t.syncPaths[i]
- b := t.syncPaths[j]
- switch bytes.Compare(a[0], b[0]) {
- case -1:
- return true
- case 1:
- return false
- }
- // identical first part
- if len(a) < len(b) {
- return true
- }
- if len(b) < len(a) {
- return false
- }
- if len(a) == 2 {
- return bytes.Compare(a[1], b[1]) < 0
- }
- return false
-}
-
-func (t *healRequestSort) Swap(i, j int) {
- t.paths[i], t.paths[j] = t.paths[j], t.paths[i]
- t.hashes[i], t.hashes[j] = t.hashes[j], t.hashes[i]
- t.syncPaths[i], t.syncPaths[j] = t.syncPaths[j], t.syncPaths[i]
-}
-
-// Merge merges the pathsets, so that several storage requests concerning the
-// same account are merged into one, to reduce bandwidth.
-// OBS: This operation is moot if t has not first been sorted.
-func (t *healRequestSort) Merge() []TrieNodePathSet {
- var result []TrieNodePathSet
- for _, path := range t.syncPaths {
- pathset := TrieNodePathSet(path)
- if len(path) == 1 {
- // It's an account reference.
- result = append(result, pathset)
- } else {
- // It's a storage reference.
- end := len(result) - 1
- if len(result) == 0 || !bytes.Equal(pathset[0], result[end][0]) {
- // The account doesn't match last, create a new entry.
- result = append(result, pathset)
- } else {
- // It's the same account as the previous one, add to the storage
- // paths of that request.
- result[end] = append(result[end], pathset[1])
- }
- }
- }
- return result
-}
-
-// sortByAccountPath takes hashes and paths, and sorts them. After that, it generates
-// the TrieNodePaths and merges paths which belongs to the same account path.
-func sortByAccountPath(paths []string, hashes []common.Hash) ([]string, []common.Hash, []trie.SyncPath, []TrieNodePathSet) {
- var syncPaths []trie.SyncPath
- for _, path := range paths {
- syncPaths = append(syncPaths, trie.NewSyncPath([]byte(path)))
- }
- n := &healRequestSort{paths, hashes, syncPaths}
- sort.Sort(n)
- pathsets := n.Merge()
- return n.paths, n.hashes, n.syncPaths, pathsets
-}
diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go
deleted file mode 100644
index 5d4099a814..0000000000
--- a/eth/protocols/snap/sync_test.go
+++ /dev/null
@@ -1,1974 +0,0 @@
-// Copyright 2021 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 snap
-
-import (
- "bytes"
- "crypto/rand"
- "encoding/binary"
- "fmt"
- "math/big"
- mrand "math/rand"
- "sync"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
- "github.com/ethereum/go-ethereum/trie/testutil"
- "github.com/ethereum/go-ethereum/trie/triedb/pathdb"
- "github.com/ethereum/go-ethereum/trie/trienode"
- "golang.org/x/crypto/sha3"
- "golang.org/x/exp/slices"
-)
-
-func TestHashing(t *testing.T) {
- t.Parallel()
-
- var bytecodes = make([][]byte, 10)
- for i := 0; i < len(bytecodes); i++ {
- buf := make([]byte, 100)
- rand.Read(buf)
- bytecodes[i] = buf
- }
- var want, got string
- var old = func() {
- hasher := sha3.NewLegacyKeccak256()
- for i := 0; i < len(bytecodes); i++ {
- hasher.Reset()
- hasher.Write(bytecodes[i])
- hash := hasher.Sum(nil)
- got = fmt.Sprintf("%v\n%v", got, hash)
- }
- }
- var new = func() {
- hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
- var hash = make([]byte, 32)
- for i := 0; i < len(bytecodes); i++ {
- hasher.Reset()
- hasher.Write(bytecodes[i])
- hasher.Read(hash)
- want = fmt.Sprintf("%v\n%v", want, hash)
- }
- }
- old()
- new()
- if want != got {
- t.Errorf("want\n%v\ngot\n%v\n", want, got)
- }
-}
-
-func BenchmarkHashing(b *testing.B) {
- var bytecodes = make([][]byte, 10000)
- for i := 0; i < len(bytecodes); i++ {
- buf := make([]byte, 100)
- rand.Read(buf)
- bytecodes[i] = buf
- }
- var old = func() {
- hasher := sha3.NewLegacyKeccak256()
- for i := 0; i < len(bytecodes); i++ {
- hasher.Reset()
- hasher.Write(bytecodes[i])
- hasher.Sum(nil)
- }
- }
- var new = func() {
- hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState)
- var hash = make([]byte, 32)
- for i := 0; i < len(bytecodes); i++ {
- hasher.Reset()
- hasher.Write(bytecodes[i])
- hasher.Read(hash)
- }
- }
- b.Run("old", func(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- old()
- }
- })
- b.Run("new", func(b *testing.B) {
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- new()
- }
- })
-}
-
-type (
- accountHandlerFunc func(t *testPeer, requestId uint64, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) error
- storageHandlerFunc func(t *testPeer, requestId uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) error
- trieHandlerFunc func(t *testPeer, requestId uint64, root common.Hash, paths []TrieNodePathSet, cap uint64) error
- codeHandlerFunc func(t *testPeer, id uint64, hashes []common.Hash, max uint64) error
-)
-
-type testPeer struct {
- id string
- test *testing.T
- remote *Syncer
- logger log.Logger
- accountTrie *trie.Trie
- accountValues []*kv
- storageTries map[common.Hash]*trie.Trie
- storageValues map[common.Hash][]*kv
-
- accountRequestHandler accountHandlerFunc
- storageRequestHandler storageHandlerFunc
- trieRequestHandler trieHandlerFunc
- codeRequestHandler codeHandlerFunc
- term func()
-
- // counters
- nAccountRequests int
- nStorageRequests int
- nBytecodeRequests int
- nTrienodeRequests int
-}
-
-func newTestPeer(id string, t *testing.T, term func()) *testPeer {
- peer := &testPeer{
- id: id,
- test: t,
- logger: log.New("id", id),
- accountRequestHandler: defaultAccountRequestHandler,
- trieRequestHandler: defaultTrieRequestHandler,
- storageRequestHandler: defaultStorageRequestHandler,
- codeRequestHandler: defaultCodeRequestHandler,
- term: term,
- }
- //stderrHandler := log.StreamHandler(os.Stderr, log.TerminalFormat(true))
- //peer.logger.SetHandler(stderrHandler)
- return peer
-}
-
-func (t *testPeer) setStorageTries(tries map[common.Hash]*trie.Trie) {
- t.storageTries = make(map[common.Hash]*trie.Trie)
- for root, trie := range tries {
- t.storageTries[root] = trie.Copy()
- }
-}
-
-func (t *testPeer) ID() string { return t.id }
-func (t *testPeer) Log() log.Logger { return t.logger }
-
-func (t *testPeer) Stats() string {
- return fmt.Sprintf(`Account requests: %d
-Storage requests: %d
-Bytecode requests: %d
-Trienode requests: %d
-`, t.nAccountRequests, t.nStorageRequests, t.nBytecodeRequests, t.nTrienodeRequests)
-}
-
-func (t *testPeer) RequestAccountRange(id uint64, root, origin, limit common.Hash, bytes uint64) error {
- t.logger.Trace("Fetching range of accounts", "reqid", id, "root", root, "origin", origin, "limit", limit, "bytes", common.StorageSize(bytes))
- t.nAccountRequests++
- go t.accountRequestHandler(t, id, root, origin, limit, bytes)
- return nil
-}
-
-func (t *testPeer) RequestTrieNodes(id uint64, root common.Hash, paths []TrieNodePathSet, bytes uint64) error {
- t.logger.Trace("Fetching set of trie nodes", "reqid", id, "root", root, "pathsets", len(paths), "bytes", common.StorageSize(bytes))
- t.nTrienodeRequests++
- go t.trieRequestHandler(t, id, root, paths, bytes)
- return nil
-}
-
-func (t *testPeer) RequestStorageRanges(id uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, bytes uint64) error {
- t.nStorageRequests++
- if len(accounts) == 1 && origin != nil {
- t.logger.Trace("Fetching range of large storage slots", "reqid", id, "root", root, "account", accounts[0], "origin", common.BytesToHash(origin), "limit", common.BytesToHash(limit), "bytes", common.StorageSize(bytes))
- } else {
- t.logger.Trace("Fetching ranges of small storage slots", "reqid", id, "root", root, "accounts", len(accounts), "first", accounts[0], "bytes", common.StorageSize(bytes))
- }
- go t.storageRequestHandler(t, id, root, accounts, origin, limit, bytes)
- return nil
-}
-
-func (t *testPeer) RequestByteCodes(id uint64, hashes []common.Hash, bytes uint64) error {
- t.nBytecodeRequests++
- t.logger.Trace("Fetching set of byte codes", "reqid", id, "hashes", len(hashes), "bytes", common.StorageSize(bytes))
- go t.codeRequestHandler(t, id, hashes, bytes)
- return nil
-}
-
-// defaultTrieRequestHandler is a well-behaving handler for trie healing requests
-func defaultTrieRequestHandler(t *testPeer, requestId uint64, root common.Hash, paths []TrieNodePathSet, cap uint64) error {
- // Pass the response
- var nodes [][]byte
- for _, pathset := range paths {
- switch len(pathset) {
- case 1:
- blob, _, err := t.accountTrie.GetNode(pathset[0])
- if err != nil {
- t.logger.Info("Error handling req", "error", err)
- break
- }
- nodes = append(nodes, blob)
- default:
- account := t.storageTries[(common.BytesToHash(pathset[0]))]
- for _, path := range pathset[1:] {
- blob, _, err := account.GetNode(path)
- if err != nil {
- t.logger.Info("Error handling req", "error", err)
- break
- }
- nodes = append(nodes, blob)
- }
- }
- }
- t.remote.OnTrieNodes(t, requestId, nodes)
- return nil
-}
-
-// defaultAccountRequestHandler is a well-behaving handler for AccountRangeRequests
-func defaultAccountRequestHandler(t *testPeer, id uint64, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) error {
- keys, vals, proofs := createAccountRequestResponse(t, root, origin, limit, cap)
- if err := t.remote.OnAccounts(t, id, keys, vals, proofs); err != nil {
- t.test.Errorf("Remote side rejected our delivery: %v", err)
- t.term()
- return err
- }
- return nil
-}
-
-func createAccountRequestResponse(t *testPeer, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) (keys []common.Hash, vals [][]byte, proofs [][]byte) {
- var size uint64
- if limit == (common.Hash{}) {
- limit = common.MaxHash
- }
- for _, entry := range t.accountValues {
- if size > cap {
- break
- }
- if bytes.Compare(origin[:], entry.k) <= 0 {
- keys = append(keys, common.BytesToHash(entry.k))
- vals = append(vals, entry.v)
- size += uint64(32 + len(entry.v))
- }
- // If we've exceeded the request threshold, abort
- if bytes.Compare(entry.k, limit[:]) >= 0 {
- break
- }
- }
- // Unless we send the entire trie, we need to supply proofs
- // Actually, we need to supply proofs either way! This seems to be an implementation
- // quirk in go-ethereum
- proof := trienode.NewProofSet()
- if err := t.accountTrie.Prove(origin[:], proof); err != nil {
- t.logger.Error("Could not prove inexistence of origin", "origin", origin, "error", err)
- }
- if len(keys) > 0 {
- lastK := (keys[len(keys)-1])[:]
- if err := t.accountTrie.Prove(lastK, proof); err != nil {
- t.logger.Error("Could not prove last item", "error", err)
- }
- }
- for _, blob := range proof.List() {
- proofs = append(proofs, blob)
- }
- return keys, vals, proofs
-}
-
-// defaultStorageRequestHandler is a well-behaving storage request handler
-func defaultStorageRequestHandler(t *testPeer, requestId uint64, root common.Hash, accounts []common.Hash, bOrigin, bLimit []byte, max uint64) error {
- hashes, slots, proofs := createStorageRequestResponse(t, root, accounts, bOrigin, bLimit, max)
- if err := t.remote.OnStorage(t, requestId, hashes, slots, proofs); err != nil {
- t.test.Errorf("Remote side rejected our delivery: %v", err)
- t.term()
- }
- return nil
-}
-
-func defaultCodeRequestHandler(t *testPeer, id uint64, hashes []common.Hash, max uint64) error {
- var bytecodes [][]byte
- for _, h := range hashes {
- bytecodes = append(bytecodes, getCodeByHash(h))
- }
- if err := t.remote.OnByteCodes(t, id, bytecodes); err != nil {
- t.test.Errorf("Remote side rejected our delivery: %v", err)
- t.term()
- }
- return nil
-}
-
-func createStorageRequestResponse(t *testPeer, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) (hashes [][]common.Hash, slots [][][]byte, proofs [][]byte) {
- var size uint64
- for _, account := range accounts {
- // The first account might start from a different origin and end sooner
- var originHash common.Hash
- if len(origin) > 0 {
- originHash = common.BytesToHash(origin)
- }
- var limitHash = common.MaxHash
- if len(limit) > 0 {
- limitHash = common.BytesToHash(limit)
- }
- var (
- keys []common.Hash
- vals [][]byte
- abort bool
- )
- for _, entry := range t.storageValues[account] {
- if size >= max {
- abort = true
- break
- }
- if bytes.Compare(entry.k, originHash[:]) < 0 {
- continue
- }
- keys = append(keys, common.BytesToHash(entry.k))
- vals = append(vals, entry.v)
- size += uint64(32 + len(entry.v))
- if bytes.Compare(entry.k, limitHash[:]) >= 0 {
- break
- }
- }
- if len(keys) > 0 {
- hashes = append(hashes, keys)
- slots = append(slots, vals)
- }
- // Generate the Merkle proofs for the first and last storage slot, but
- // only if the response was capped. If the entire storage trie included
- // in the response, no need for any proofs.
- if originHash != (common.Hash{}) || (abort && len(keys) > 0) {
- // If we're aborting, we need to prove the first and last item
- // This terminates the response (and thus the loop)
- proof := trienode.NewProofSet()
- stTrie := t.storageTries[account]
-
- // Here's a potential gotcha: when constructing the proof, we cannot
- // use the 'origin' slice directly, but must use the full 32-byte
- // hash form.
- if err := stTrie.Prove(originHash[:], proof); err != nil {
- t.logger.Error("Could not prove inexistence of origin", "origin", originHash, "error", err)
- }
- if len(keys) > 0 {
- lastK := (keys[len(keys)-1])[:]
- if err := stTrie.Prove(lastK, proof); err != nil {
- t.logger.Error("Could not prove last item", "error", err)
- }
- }
- for _, blob := range proof.List() {
- proofs = append(proofs, blob)
- }
- break
- }
- }
- return hashes, slots, proofs
-}
-
-// createStorageRequestResponseAlwaysProve tests a cornercase, where the peer always
-// supplies the proof for the last account, even if it is 'complete'.
-func createStorageRequestResponseAlwaysProve(t *testPeer, root common.Hash, accounts []common.Hash, bOrigin, bLimit []byte, max uint64) (hashes [][]common.Hash, slots [][][]byte, proofs [][]byte) {
- var size uint64
- max = max * 3 / 4
-
- var origin common.Hash
- if len(bOrigin) > 0 {
- origin = common.BytesToHash(bOrigin)
- }
- var exit bool
- for i, account := range accounts {
- var keys []common.Hash
- var vals [][]byte
- for _, entry := range t.storageValues[account] {
- if bytes.Compare(entry.k, origin[:]) < 0 {
- exit = true
- }
- keys = append(keys, common.BytesToHash(entry.k))
- vals = append(vals, entry.v)
- size += uint64(32 + len(entry.v))
- if size > max {
- exit = true
- }
- }
- if i == len(accounts)-1 {
- exit = true
- }
- hashes = append(hashes, keys)
- slots = append(slots, vals)
-
- if exit {
- // If we're aborting, we need to prove the first and last item
- // This terminates the response (and thus the loop)
- proof := trienode.NewProofSet()
- stTrie := t.storageTries[account]
-
- // Here's a potential gotcha: when constructing the proof, we cannot
- // use the 'origin' slice directly, but must use the full 32-byte
- // hash form.
- if err := stTrie.Prove(origin[:], proof); err != nil {
- t.logger.Error("Could not prove inexistence of origin", "origin", origin,
- "error", err)
- }
- if len(keys) > 0 {
- lastK := (keys[len(keys)-1])[:]
- if err := stTrie.Prove(lastK, proof); err != nil {
- t.logger.Error("Could not prove last item", "error", err)
- }
- }
- for _, blob := range proof.List() {
- proofs = append(proofs, blob)
- }
- break
- }
- }
- return hashes, slots, proofs
-}
-
-// emptyRequestAccountRangeFn is a rejects AccountRangeRequests
-func emptyRequestAccountRangeFn(t *testPeer, requestId uint64, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) error {
- t.remote.OnAccounts(t, requestId, nil, nil, nil)
- return nil
-}
-
-func nonResponsiveRequestAccountRangeFn(t *testPeer, requestId uint64, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) error {
- return nil
-}
-
-func emptyTrieRequestHandler(t *testPeer, requestId uint64, root common.Hash, paths []TrieNodePathSet, cap uint64) error {
- t.remote.OnTrieNodes(t, requestId, nil)
- return nil
-}
-
-func nonResponsiveTrieRequestHandler(t *testPeer, requestId uint64, root common.Hash, paths []TrieNodePathSet, cap uint64) error {
- return nil
-}
-
-func emptyStorageRequestHandler(t *testPeer, requestId uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) error {
- t.remote.OnStorage(t, requestId, nil, nil, nil)
- return nil
-}
-
-func nonResponsiveStorageRequestHandler(t *testPeer, requestId uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) error {
- return nil
-}
-
-func proofHappyStorageRequestHandler(t *testPeer, requestId uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) error {
- hashes, slots, proofs := createStorageRequestResponseAlwaysProve(t, root, accounts, origin, limit, max)
- if err := t.remote.OnStorage(t, requestId, hashes, slots, proofs); err != nil {
- t.test.Errorf("Remote side rejected our delivery: %v", err)
- t.term()
- }
- return nil
-}
-
-//func emptyCodeRequestHandler(t *testPeer, id uint64, hashes []common.Hash, max uint64) error {
-// var bytecodes [][]byte
-// t.remote.OnByteCodes(t, id, bytecodes)
-// return nil
-//}
-
-func corruptCodeRequestHandler(t *testPeer, id uint64, hashes []common.Hash, max uint64) error {
- var bytecodes [][]byte
- for _, h := range hashes {
- // Send back the hashes
- bytecodes = append(bytecodes, h[:])
- }
- if err := t.remote.OnByteCodes(t, id, bytecodes); err != nil {
- t.logger.Info("remote error on delivery (as expected)", "error", err)
- // Mimic the real-life handler, which drops a peer on errors
- t.remote.Unregister(t.id)
- }
- return nil
-}
-
-func cappedCodeRequestHandler(t *testPeer, id uint64, hashes []common.Hash, max uint64) error {
- var bytecodes [][]byte
- for _, h := range hashes[:1] {
- bytecodes = append(bytecodes, getCodeByHash(h))
- }
- // Missing bytecode can be retrieved again, no error expected
- if err := t.remote.OnByteCodes(t, id, bytecodes); err != nil {
- t.test.Errorf("Remote side rejected our delivery: %v", err)
- t.term()
- }
- return nil
-}
-
-// starvingStorageRequestHandler is somewhat well-behaving storage handler, but it caps the returned results to be very small
-func starvingStorageRequestHandler(t *testPeer, requestId uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) error {
- return defaultStorageRequestHandler(t, requestId, root, accounts, origin, limit, 500)
-}
-
-func starvingAccountRequestHandler(t *testPeer, requestId uint64, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) error {
- return defaultAccountRequestHandler(t, requestId, root, origin, limit, 500)
-}
-
-//func misdeliveringAccountRequestHandler(t *testPeer, requestId uint64, root common.Hash, origin common.Hash, cap uint64) error {
-// return defaultAccountRequestHandler(t, requestId-1, root, origin, 500)
-//}
-
-func corruptAccountRequestHandler(t *testPeer, requestId uint64, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) error {
- hashes, accounts, proofs := createAccountRequestResponse(t, root, origin, limit, cap)
- if len(proofs) > 0 {
- proofs = proofs[1:]
- }
- if err := t.remote.OnAccounts(t, requestId, hashes, accounts, proofs); err != nil {
- t.logger.Info("remote error on delivery (as expected)", "error", err)
- // Mimic the real-life handler, which drops a peer on errors
- t.remote.Unregister(t.id)
- }
- return nil
-}
-
-// corruptStorageRequestHandler doesn't provide good proofs
-func corruptStorageRequestHandler(t *testPeer, requestId uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) error {
- hashes, slots, proofs := createStorageRequestResponse(t, root, accounts, origin, limit, max)
- if len(proofs) > 0 {
- proofs = proofs[1:]
- }
- if err := t.remote.OnStorage(t, requestId, hashes, slots, proofs); err != nil {
- t.logger.Info("remote error on delivery (as expected)", "error", err)
- // Mimic the real-life handler, which drops a peer on errors
- t.remote.Unregister(t.id)
- }
- return nil
-}
-
-func noProofStorageRequestHandler(t *testPeer, requestId uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) error {
- hashes, slots, _ := createStorageRequestResponse(t, root, accounts, origin, limit, max)
- if err := t.remote.OnStorage(t, requestId, hashes, slots, nil); err != nil {
- t.logger.Info("remote error on delivery (as expected)", "error", err)
- // Mimic the real-life handler, which drops a peer on errors
- t.remote.Unregister(t.id)
- }
- return nil
-}
-
-// TestSyncBloatedProof tests a scenario where we provide only _one_ value, but
-// also ship the entire trie inside the proof. If the attack is successful,
-// the remote side does not do any follow-up requests
-func TestSyncBloatedProof(t *testing.T) {
- t.Parallel()
-
- testSyncBloatedProof(t, rawdb.HashScheme)
- testSyncBloatedProof(t, rawdb.PathScheme)
-}
-
-func testSyncBloatedProof(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(100, scheme)
- source := newTestPeer("source", t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
-
- source.accountRequestHandler = func(t *testPeer, requestId uint64, root common.Hash, origin common.Hash, limit common.Hash, cap uint64) error {
- var (
- proofs [][]byte
- keys []common.Hash
- vals [][]byte
- )
- // The values
- for _, entry := range t.accountValues {
- if bytes.Compare(entry.k, origin[:]) < 0 {
- continue
- }
- if bytes.Compare(entry.k, limit[:]) > 0 {
- continue
- }
- keys = append(keys, common.BytesToHash(entry.k))
- vals = append(vals, entry.v)
- }
- // The proofs
- proof := trienode.NewProofSet()
- if err := t.accountTrie.Prove(origin[:], proof); err != nil {
- t.logger.Error("Could not prove origin", "origin", origin, "error", err)
- t.logger.Error("Could not prove origin", "origin", origin, "error", err)
- }
- // The bloat: add proof of every single element
- for _, entry := range t.accountValues {
- if err := t.accountTrie.Prove(entry.k, proof); err != nil {
- t.logger.Error("Could not prove item", "error", err)
- }
- }
- // And remove one item from the elements
- if len(keys) > 2 {
- keys = append(keys[:1], keys[2:]...)
- vals = append(vals[:1], vals[2:]...)
- }
- for _, blob := range proof.List() {
- proofs = append(proofs, blob)
- }
- if err := t.remote.OnAccounts(t, requestId, keys, vals, proofs); err != nil {
- t.logger.Info("remote error on delivery (as expected)", "error", err)
- t.term()
- // This is actually correct, signal to exit the test successfully
- }
- return nil
- }
- syncer := setupSyncer(nodeScheme, source)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err == nil {
- t.Fatal("No error returned from incomplete/cancelled sync")
- }
-}
-
-func setupSyncer(scheme string, peers ...*testPeer) *Syncer {
- stateDb := rawdb.NewMemoryDatabase()
- syncer := NewSyncer(stateDb, scheme)
- for _, peer := range peers {
- syncer.Register(peer)
- peer.remote = syncer
- }
- return syncer
-}
-
-// TestSync tests a basic sync with one peer
-func TestSync(t *testing.T) {
- t.Parallel()
-
- testSync(t, rawdb.HashScheme)
- testSync(t, rawdb.PathScheme)
-}
-
-func testSync(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(100, scheme)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- return source
- }
- syncer := setupSyncer(nodeScheme, mkSource("source"))
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncTinyTriePanic tests a basic sync with one peer, and a tiny trie. This caused a
-// panic within the prover
-func TestSyncTinyTriePanic(t *testing.T) {
- t.Parallel()
-
- testSyncTinyTriePanic(t, rawdb.HashScheme)
- testSyncTinyTriePanic(t, rawdb.PathScheme)
-}
-
-func testSyncTinyTriePanic(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(1, scheme)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- return source
- }
- syncer := setupSyncer(nodeScheme, mkSource("source"))
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestMultiSync tests a basic sync with multiple peers
-func TestMultiSync(t *testing.T) {
- t.Parallel()
-
- testMultiSync(t, rawdb.HashScheme)
- testMultiSync(t, rawdb.PathScheme)
-}
-
-func testMultiSync(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(100, scheme)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- return source
- }
- syncer := setupSyncer(nodeScheme, mkSource("sourceA"), mkSource("sourceB"))
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncWithStorage tests basic sync using accounts + storage + code
-func TestSyncWithStorage(t *testing.T) {
- t.Parallel()
-
- testSyncWithStorage(t, rawdb.HashScheme)
- testSyncWithStorage(t, rawdb.PathScheme)
-}
-
-func testSyncWithStorage(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 3, 3000, true, false, false)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
- return source
- }
- syncer := setupSyncer(scheme, mkSource("sourceA"))
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestMultiSyncManyUseless contains one good peer, and many which doesn't return anything valuable at all
-func TestMultiSyncManyUseless(t *testing.T) {
- t.Parallel()
-
- testMultiSyncManyUseless(t, rawdb.HashScheme)
- testMultiSyncManyUseless(t, rawdb.PathScheme)
-}
-
-func testMultiSyncManyUseless(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 100, 3000, true, false, false)
-
- mkSource := func(name string, noAccount, noStorage, noTrieNode bool) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
-
- if !noAccount {
- source.accountRequestHandler = emptyRequestAccountRangeFn
- }
- if !noStorage {
- source.storageRequestHandler = emptyStorageRequestHandler
- }
- if !noTrieNode {
- source.trieRequestHandler = emptyTrieRequestHandler
- }
- return source
- }
-
- syncer := setupSyncer(
- scheme,
- mkSource("full", true, true, true),
- mkSource("noAccounts", false, true, true),
- mkSource("noStorage", true, false, true),
- mkSource("noTrie", true, true, false),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestMultiSyncManyUseless contains one good peer, and many which doesn't return anything valuable at all
-func TestMultiSyncManyUselessWithLowTimeout(t *testing.T) {
- t.Parallel()
-
- testMultiSyncManyUselessWithLowTimeout(t, rawdb.HashScheme)
- testMultiSyncManyUselessWithLowTimeout(t, rawdb.PathScheme)
-}
-
-func testMultiSyncManyUselessWithLowTimeout(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 100, 3000, true, false, false)
-
- mkSource := func(name string, noAccount, noStorage, noTrieNode bool) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
-
- if !noAccount {
- source.accountRequestHandler = emptyRequestAccountRangeFn
- }
- if !noStorage {
- source.storageRequestHandler = emptyStorageRequestHandler
- }
- if !noTrieNode {
- source.trieRequestHandler = emptyTrieRequestHandler
- }
- return source
- }
-
- syncer := setupSyncer(
- scheme,
- mkSource("full", true, true, true),
- mkSource("noAccounts", false, true, true),
- mkSource("noStorage", true, false, true),
- mkSource("noTrie", true, true, false),
- )
- // We're setting the timeout to very low, to increase the chance of the timeout
- // being triggered. This was previously a cause of panic, when a response
- // arrived simultaneously as a timeout was triggered.
- syncer.rates.OverrideTTLLimit = time.Millisecond
-
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestMultiSyncManyUnresponsive contains one good peer, and many which doesn't respond at all
-func TestMultiSyncManyUnresponsive(t *testing.T) {
- t.Parallel()
-
- testMultiSyncManyUnresponsive(t, rawdb.HashScheme)
- testMultiSyncManyUnresponsive(t, rawdb.PathScheme)
-}
-
-func testMultiSyncManyUnresponsive(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 100, 3000, true, false, false)
-
- mkSource := func(name string, noAccount, noStorage, noTrieNode bool) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
-
- if !noAccount {
- source.accountRequestHandler = nonResponsiveRequestAccountRangeFn
- }
- if !noStorage {
- source.storageRequestHandler = nonResponsiveStorageRequestHandler
- }
- if !noTrieNode {
- source.trieRequestHandler = nonResponsiveTrieRequestHandler
- }
- return source
- }
-
- syncer := setupSyncer(
- scheme,
- mkSource("full", true, true, true),
- mkSource("noAccounts", false, true, true),
- mkSource("noStorage", true, false, true),
- mkSource("noTrie", true, true, false),
- )
- // We're setting the timeout to very low, to make the test run a bit faster
- syncer.rates.OverrideTTLLimit = time.Millisecond
-
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-func checkStall(t *testing.T, term func()) chan struct{} {
- testDone := make(chan struct{})
- go func() {
- select {
- case <-time.After(time.Minute): // TODO(karalabe): Make tests smaller, this is too much
- t.Log("Sync stalled")
- term()
- case <-testDone:
- return
- }
- }()
- return testDone
-}
-
-// TestSyncBoundaryAccountTrie tests sync against a few normal peers, but the
-// account trie has a few boundary elements.
-func TestSyncBoundaryAccountTrie(t *testing.T) {
- t.Parallel()
-
- testSyncBoundaryAccountTrie(t, rawdb.HashScheme)
- testSyncBoundaryAccountTrie(t, rawdb.PathScheme)
-}
-
-func testSyncBoundaryAccountTrie(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeBoundaryAccountTrie(scheme, 3000)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- return source
- }
- syncer := setupSyncer(
- nodeScheme,
- mkSource("peer-a"),
- mkSource("peer-b"),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncNoStorageAndOneCappedPeer tests sync using accounts and no storage, where one peer is
-// consistently returning very small results
-func TestSyncNoStorageAndOneCappedPeer(t *testing.T) {
- t.Parallel()
-
- testSyncNoStorageAndOneCappedPeer(t, rawdb.HashScheme)
- testSyncNoStorageAndOneCappedPeer(t, rawdb.PathScheme)
-}
-
-func testSyncNoStorageAndOneCappedPeer(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(3000, scheme)
-
- mkSource := func(name string, slow bool) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
-
- if slow {
- source.accountRequestHandler = starvingAccountRequestHandler
- }
- return source
- }
-
- syncer := setupSyncer(
- nodeScheme,
- mkSource("nice-a", false),
- mkSource("nice-b", false),
- mkSource("nice-c", false),
- mkSource("capped", true),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncNoStorageAndOneCodeCorruptPeer has one peer which doesn't deliver
-// code requests properly.
-func TestSyncNoStorageAndOneCodeCorruptPeer(t *testing.T) {
- t.Parallel()
-
- testSyncNoStorageAndOneCodeCorruptPeer(t, rawdb.HashScheme)
- testSyncNoStorageAndOneCodeCorruptPeer(t, rawdb.PathScheme)
-}
-
-func testSyncNoStorageAndOneCodeCorruptPeer(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(3000, scheme)
-
- mkSource := func(name string, codeFn codeHandlerFunc) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.codeRequestHandler = codeFn
- return source
- }
- // One is capped, one is corrupt. If we don't use a capped one, there's a 50%
- // chance that the full set of codes requested are sent only to the
- // non-corrupt peer, which delivers everything in one go, and makes the
- // test moot
- syncer := setupSyncer(
- nodeScheme,
- mkSource("capped", cappedCodeRequestHandler),
- mkSource("corrupt", corruptCodeRequestHandler),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-func TestSyncNoStorageAndOneAccountCorruptPeer(t *testing.T) {
- t.Parallel()
-
- testSyncNoStorageAndOneAccountCorruptPeer(t, rawdb.HashScheme)
- testSyncNoStorageAndOneAccountCorruptPeer(t, rawdb.PathScheme)
-}
-
-func testSyncNoStorageAndOneAccountCorruptPeer(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(3000, scheme)
-
- mkSource := func(name string, accFn accountHandlerFunc) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.accountRequestHandler = accFn
- return source
- }
- // One is capped, one is corrupt. If we don't use a capped one, there's a 50%
- // chance that the full set of codes requested are sent only to the
- // non-corrupt peer, which delivers everything in one go, and makes the
- // test moot
- syncer := setupSyncer(
- nodeScheme,
- mkSource("capped", defaultAccountRequestHandler),
- mkSource("corrupt", corruptAccountRequestHandler),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncNoStorageAndOneCodeCappedPeer has one peer which delivers code hashes
-// one by one
-func TestSyncNoStorageAndOneCodeCappedPeer(t *testing.T) {
- t.Parallel()
-
- testSyncNoStorageAndOneCodeCappedPeer(t, rawdb.HashScheme)
- testSyncNoStorageAndOneCodeCappedPeer(t, rawdb.PathScheme)
-}
-
-func testSyncNoStorageAndOneCodeCappedPeer(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(3000, scheme)
-
- mkSource := func(name string, codeFn codeHandlerFunc) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.codeRequestHandler = codeFn
- return source
- }
- // Count how many times it's invoked. Remember, there are only 8 unique hashes,
- // so it shouldn't be more than that
- var counter int
- syncer := setupSyncer(
- nodeScheme,
- mkSource("capped", func(t *testPeer, id uint64, hashes []common.Hash, max uint64) error {
- counter++
- return cappedCodeRequestHandler(t, id, hashes, max)
- }),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
-
- // There are only 8 unique hashes, and 3K accounts. However, the code
- // deduplication is per request batch. If it were a perfect global dedup,
- // we would expect only 8 requests. If there were no dedup, there would be
- // 3k requests.
- // We expect somewhere below 100 requests for these 8 unique hashes. But
- // the number can be flaky, so don't limit it so strictly.
- if threshold := 100; counter > threshold {
- t.Logf("Error, expected < %d invocations, got %d", threshold, counter)
- }
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncBoundaryStorageTrie tests sync against a few normal peers, but the
-// storage trie has a few boundary elements.
-func TestSyncBoundaryStorageTrie(t *testing.T) {
- t.Parallel()
-
- testSyncBoundaryStorageTrie(t, rawdb.HashScheme)
- testSyncBoundaryStorageTrie(t, rawdb.PathScheme)
-}
-
-func testSyncBoundaryStorageTrie(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 10, 1000, false, true, false)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
- return source
- }
- syncer := setupSyncer(
- scheme,
- mkSource("peer-a"),
- mkSource("peer-b"),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncWithStorageAndOneCappedPeer tests sync using accounts + storage, where one peer is
-// consistently returning very small results
-func TestSyncWithStorageAndOneCappedPeer(t *testing.T) {
- t.Parallel()
-
- testSyncWithStorageAndOneCappedPeer(t, rawdb.HashScheme)
- testSyncWithStorageAndOneCappedPeer(t, rawdb.PathScheme)
-}
-
-func testSyncWithStorageAndOneCappedPeer(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 300, 1000, false, false, false)
-
- mkSource := func(name string, slow bool) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
-
- if slow {
- source.storageRequestHandler = starvingStorageRequestHandler
- }
- return source
- }
-
- syncer := setupSyncer(
- scheme,
- mkSource("nice-a", false),
- mkSource("slow", true),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncWithStorageAndCorruptPeer tests sync using accounts + storage, where one peer is
-// sometimes sending bad proofs
-func TestSyncWithStorageAndCorruptPeer(t *testing.T) {
- t.Parallel()
-
- testSyncWithStorageAndCorruptPeer(t, rawdb.HashScheme)
- testSyncWithStorageAndCorruptPeer(t, rawdb.PathScheme)
-}
-
-func testSyncWithStorageAndCorruptPeer(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 100, 3000, true, false, false)
-
- mkSource := func(name string, handler storageHandlerFunc) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
- source.storageRequestHandler = handler
- return source
- }
-
- syncer := setupSyncer(
- scheme,
- mkSource("nice-a", defaultStorageRequestHandler),
- mkSource("nice-b", defaultStorageRequestHandler),
- mkSource("nice-c", defaultStorageRequestHandler),
- mkSource("corrupt", corruptStorageRequestHandler),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-func TestSyncWithStorageAndNonProvingPeer(t *testing.T) {
- t.Parallel()
-
- testSyncWithStorageAndNonProvingPeer(t, rawdb.HashScheme)
- testSyncWithStorageAndNonProvingPeer(t, rawdb.PathScheme)
-}
-
-func testSyncWithStorageAndNonProvingPeer(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 100, 3000, true, false, false)
-
- mkSource := func(name string, handler storageHandlerFunc) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
- source.storageRequestHandler = handler
- return source
- }
- syncer := setupSyncer(
- scheme,
- mkSource("nice-a", defaultStorageRequestHandler),
- mkSource("nice-b", defaultStorageRequestHandler),
- mkSource("nice-c", defaultStorageRequestHandler),
- mkSource("corrupt", noProofStorageRequestHandler),
- )
- done := checkStall(t, term)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- close(done)
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncWithStorage tests basic sync using accounts + storage + code, against
-// a peer who insists on delivering full storage sets _and_ proofs. This triggered
-// an error, where the recipient erroneously clipped the boundary nodes, but
-// did not mark the account for healing.
-func TestSyncWithStorageMisbehavingProve(t *testing.T) {
- t.Parallel()
-
- testSyncWithStorageMisbehavingProve(t, rawdb.HashScheme)
- testSyncWithStorageMisbehavingProve(t, rawdb.PathScheme)
-}
-
-func testSyncWithStorageMisbehavingProve(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems, storageTries, storageElems := makeAccountTrieWithStorageWithUniqueStorage(scheme, 10, 30, false)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
- source.storageRequestHandler = proofHappyStorageRequestHandler
- return source
- }
- syncer := setupSyncer(nodeScheme, mkSource("sourceA"))
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
-}
-
-// TestSyncWithUnevenStorage tests sync where the storage trie is not even
-// and with a few empty ranges.
-func TestSyncWithUnevenStorage(t *testing.T) {
- t.Parallel()
-
- testSyncWithUnevenStorage(t, rawdb.HashScheme)
- testSyncWithUnevenStorage(t, rawdb.PathScheme)
-}
-
-func testSyncWithUnevenStorage(t *testing.T, scheme string) {
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- accountTrie, accounts, storageTries, storageElems := makeAccountTrieWithStorage(scheme, 3, 256, false, false, true)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = accountTrie.Copy()
- source.accountValues = accounts
- source.setStorageTries(storageTries)
- source.storageValues = storageElems
- source.storageRequestHandler = func(t *testPeer, reqId uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, max uint64) error {
- return defaultStorageRequestHandler(t, reqId, root, accounts, origin, limit, 128) // retrieve storage in large mode
- }
- return source
- }
- syncer := setupSyncer(scheme, mkSource("source"))
- if err := syncer.Sync(accountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- verifyTrie(scheme, syncer.db, accountTrie.Hash(), t)
-}
-
-type kv struct {
- k, v []byte
-}
-
-func (k *kv) cmp(other *kv) int {
- return bytes.Compare(k.k, other.k)
-}
-
-func key32(i uint64) []byte {
- key := make([]byte, 32)
- binary.LittleEndian.PutUint64(key, i)
- return key
-}
-
-var (
- codehashes = []common.Hash{
- crypto.Keccak256Hash([]byte{0}),
- crypto.Keccak256Hash([]byte{1}),
- crypto.Keccak256Hash([]byte{2}),
- crypto.Keccak256Hash([]byte{3}),
- crypto.Keccak256Hash([]byte{4}),
- crypto.Keccak256Hash([]byte{5}),
- crypto.Keccak256Hash([]byte{6}),
- crypto.Keccak256Hash([]byte{7}),
- }
-)
-
-// getCodeHash returns a pseudo-random code hash
-func getCodeHash(i uint64) []byte {
- h := codehashes[int(i)%len(codehashes)]
- return common.CopyBytes(h[:])
-}
-
-// getCodeByHash convenience function to lookup the code from the code hash
-func getCodeByHash(hash common.Hash) []byte {
- if hash == types.EmptyCodeHash {
- return nil
- }
- for i, h := range codehashes {
- if h == hash {
- return []byte{byte(i)}
- }
- }
- return nil
-}
-
-// makeAccountTrieNoStorage spits out a trie, along with the leafs
-func makeAccountTrieNoStorage(n int, scheme string) (string, *trie.Trie, []*kv) {
- var (
- db = trie.NewDatabase(rawdb.NewMemoryDatabase(), newDbConfig(scheme))
- accTrie = trie.NewEmpty(db)
- entries []*kv
- )
- for i := uint64(1); i <= uint64(n); i++ {
- value, _ := rlp.EncodeToBytes(&types.StateAccount{
- Nonce: i,
- Balance: big.NewInt(int64(i)),
- Root: types.EmptyRootHash,
- CodeHash: getCodeHash(i),
- })
- key := key32(i)
- elem := &kv{key, value}
- accTrie.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
- }
- slices.SortFunc(entries, (*kv).cmp)
-
- // Commit the state changes into db and re-create the trie
- // for accessing later.
- root, nodes, _ := accTrie.Commit(false)
- db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
-
- accTrie, _ = trie.New(trie.StateTrieID(root), db)
- return db.Scheme(), accTrie, entries
-}
-
-// makeBoundaryAccountTrie constructs an account trie. Instead of filling
-// accounts normally, this function will fill a few accounts which have
-// boundary hash.
-func makeBoundaryAccountTrie(scheme string, n int) (string, *trie.Trie, []*kv) {
- var (
- entries []*kv
- boundaries []common.Hash
-
- db = trie.NewDatabase(rawdb.NewMemoryDatabase(), newDbConfig(scheme))
- accTrie = trie.NewEmpty(db)
- )
- // Initialize boundaries
- var next common.Hash
- step := new(big.Int).Sub(
- new(big.Int).Div(
- new(big.Int).Exp(common.Big2, common.Big256, nil),
- big.NewInt(int64(accountConcurrency)),
- ), common.Big1,
- )
- for i := 0; i < accountConcurrency; i++ {
- last := common.BigToHash(new(big.Int).Add(next.Big(), step))
- if i == accountConcurrency-1 {
- last = common.MaxHash
- }
- boundaries = append(boundaries, last)
- next = common.BigToHash(new(big.Int).Add(last.Big(), common.Big1))
- }
- // Fill boundary accounts
- for i := 0; i < len(boundaries); i++ {
- value, _ := rlp.EncodeToBytes(&types.StateAccount{
- Nonce: uint64(0),
- Balance: big.NewInt(int64(i)),
- Root: types.EmptyRootHash,
- CodeHash: getCodeHash(uint64(i)),
- })
- elem := &kv{boundaries[i].Bytes(), value}
- accTrie.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
- }
- // Fill other accounts if required
- for i := uint64(1); i <= uint64(n); i++ {
- value, _ := rlp.EncodeToBytes(&types.StateAccount{
- Nonce: i,
- Balance: big.NewInt(int64(i)),
- Root: types.EmptyRootHash,
- CodeHash: getCodeHash(i),
- })
- elem := &kv{key32(i), value}
- accTrie.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
- }
- slices.SortFunc(entries, (*kv).cmp)
-
- // Commit the state changes into db and re-create the trie
- // for accessing later.
- root, nodes, _ := accTrie.Commit(false)
- db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
-
- accTrie, _ = trie.New(trie.StateTrieID(root), db)
- return db.Scheme(), accTrie, entries
-}
-
-// makeAccountTrieWithStorageWithUniqueStorage creates an account trie where each accounts
-// has a unique storage set.
-func makeAccountTrieWithStorageWithUniqueStorage(scheme string, accounts, slots int, code bool) (string, *trie.Trie, []*kv, map[common.Hash]*trie.Trie, map[common.Hash][]*kv) {
- var (
- db = trie.NewDatabase(rawdb.NewMemoryDatabase(), newDbConfig(scheme))
- accTrie = trie.NewEmpty(db)
- entries []*kv
- storageRoots = make(map[common.Hash]common.Hash)
- storageTries = make(map[common.Hash]*trie.Trie)
- storageEntries = make(map[common.Hash][]*kv)
- nodes = trienode.NewMergedNodeSet()
- )
- // Create n accounts in the trie
- for i := uint64(1); i <= uint64(accounts); i++ {
- key := key32(i)
- codehash := types.EmptyCodeHash.Bytes()
- if code {
- codehash = getCodeHash(i)
- }
- // Create a storage trie
- stRoot, stNodes, stEntries := makeStorageTrieWithSeed(common.BytesToHash(key), uint64(slots), i, db)
- nodes.Merge(stNodes)
-
- value, _ := rlp.EncodeToBytes(&types.StateAccount{
- Nonce: i,
- Balance: big.NewInt(int64(i)),
- Root: stRoot,
- CodeHash: codehash,
- })
- elem := &kv{key, value}
- accTrie.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
-
- storageRoots[common.BytesToHash(key)] = stRoot
- storageEntries[common.BytesToHash(key)] = stEntries
- }
- slices.SortFunc(entries, (*kv).cmp)
-
- // Commit account trie
- root, set, _ := accTrie.Commit(true)
- nodes.Merge(set)
-
- // Commit gathered dirty nodes into database
- db.Update(root, types.EmptyRootHash, 0, nodes, nil)
-
- // Re-create tries with new root
- accTrie, _ = trie.New(trie.StateTrieID(root), db)
- for i := uint64(1); i <= uint64(accounts); i++ {
- key := key32(i)
- id := trie.StorageTrieID(root, common.BytesToHash(key), storageRoots[common.BytesToHash(key)])
- trie, _ := trie.New(id, db)
- storageTries[common.BytesToHash(key)] = trie
- }
- return db.Scheme(), accTrie, entries, storageTries, storageEntries
-}
-
-// makeAccountTrieWithStorage spits out a trie, along with the leafs
-func makeAccountTrieWithStorage(scheme string, accounts, slots int, code, boundary bool, uneven bool) (*trie.Trie, []*kv, map[common.Hash]*trie.Trie, map[common.Hash][]*kv) {
- var (
- db = trie.NewDatabase(rawdb.NewMemoryDatabase(), newDbConfig(scheme))
- accTrie = trie.NewEmpty(db)
- entries []*kv
- storageRoots = make(map[common.Hash]common.Hash)
- storageTries = make(map[common.Hash]*trie.Trie)
- storageEntries = make(map[common.Hash][]*kv)
- nodes = trienode.NewMergedNodeSet()
- )
- // Create n accounts in the trie
- for i := uint64(1); i <= uint64(accounts); i++ {
- key := key32(i)
- codehash := types.EmptyCodeHash.Bytes()
- if code {
- codehash = getCodeHash(i)
- }
- // Make a storage trie
- var (
- stRoot common.Hash
- stNodes *trienode.NodeSet
- stEntries []*kv
- )
- if boundary {
- stRoot, stNodes, stEntries = makeBoundaryStorageTrie(common.BytesToHash(key), slots, db)
- } else if uneven {
- stRoot, stNodes, stEntries = makeUnevenStorageTrie(common.BytesToHash(key), slots, db)
- } else {
- stRoot, stNodes, stEntries = makeStorageTrieWithSeed(common.BytesToHash(key), uint64(slots), 0, db)
- }
- nodes.Merge(stNodes)
-
- value, _ := rlp.EncodeToBytes(&types.StateAccount{
- Nonce: i,
- Balance: big.NewInt(int64(i)),
- Root: stRoot,
- CodeHash: codehash,
- })
- elem := &kv{key, value}
- accTrie.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
-
- // we reuse the same one for all accounts
- storageRoots[common.BytesToHash(key)] = stRoot
- storageEntries[common.BytesToHash(key)] = stEntries
- }
- slices.SortFunc(entries, (*kv).cmp)
-
- // Commit account trie
- root, set, _ := accTrie.Commit(true)
- nodes.Merge(set)
-
- // Commit gathered dirty nodes into database
- db.Update(root, types.EmptyRootHash, 0, nodes, nil)
-
- // Re-create tries with new root
- accTrie, err := trie.New(trie.StateTrieID(root), db)
- if err != nil {
- panic(err)
- }
- for i := uint64(1); i <= uint64(accounts); i++ {
- key := key32(i)
- id := trie.StorageTrieID(root, common.BytesToHash(key), storageRoots[common.BytesToHash(key)])
- trie, err := trie.New(id, db)
- if err != nil {
- panic(err)
- }
- storageTries[common.BytesToHash(key)] = trie
- }
- return accTrie, entries, storageTries, storageEntries
-}
-
-// makeStorageTrieWithSeed fills a storage trie with n items, returning the
-// not-yet-committed trie and the sorted entries. The seeds can be used to ensure
-// that tries are unique.
-func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *trie.Database) (common.Hash, *trienode.NodeSet, []*kv) {
- trie, _ := trie.New(trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash), db)
- var entries []*kv
- for i := uint64(1); i <= n; i++ {
- // store 'x' at slot 'x'
- slotValue := key32(i + seed)
- rlpSlotValue, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(slotValue[:]))
-
- slotKey := key32(i)
- key := crypto.Keccak256Hash(slotKey[:])
-
- elem := &kv{key[:], rlpSlotValue}
- trie.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
- }
- slices.SortFunc(entries, (*kv).cmp)
- root, nodes, _ := trie.Commit(false)
- return root, nodes, entries
-}
-
-// makeBoundaryStorageTrie constructs a storage trie. Instead of filling
-// storage slots normally, this function will fill a few slots which have
-// boundary hash.
-func makeBoundaryStorageTrie(owner common.Hash, n int, db *trie.Database) (common.Hash, *trienode.NodeSet, []*kv) {
- var (
- entries []*kv
- boundaries []common.Hash
- trie, _ = trie.New(trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash), db)
- )
- // Initialize boundaries
- var next common.Hash
- step := new(big.Int).Sub(
- new(big.Int).Div(
- new(big.Int).Exp(common.Big2, common.Big256, nil),
- big.NewInt(int64(accountConcurrency)),
- ), common.Big1,
- )
- for i := 0; i < accountConcurrency; i++ {
- last := common.BigToHash(new(big.Int).Add(next.Big(), step))
- if i == accountConcurrency-1 {
- last = common.MaxHash
- }
- boundaries = append(boundaries, last)
- next = common.BigToHash(new(big.Int).Add(last.Big(), common.Big1))
- }
- // Fill boundary slots
- for i := 0; i < len(boundaries); i++ {
- key := boundaries[i]
- val := []byte{0xde, 0xad, 0xbe, 0xef}
-
- elem := &kv{key[:], val}
- trie.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
- }
- // Fill other slots if required
- for i := uint64(1); i <= uint64(n); i++ {
- slotKey := key32(i)
- key := crypto.Keccak256Hash(slotKey[:])
-
- slotValue := key32(i)
- rlpSlotValue, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(slotValue[:]))
-
- elem := &kv{key[:], rlpSlotValue}
- trie.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
- }
- slices.SortFunc(entries, (*kv).cmp)
- root, nodes, _ := trie.Commit(false)
- return root, nodes, entries
-}
-
-// makeUnevenStorageTrie constructs a storage tries will states distributed in
-// different range unevenly.
-func makeUnevenStorageTrie(owner common.Hash, slots int, db *trie.Database) (common.Hash, *trienode.NodeSet, []*kv) {
- var (
- entries []*kv
- tr, _ = trie.New(trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash), db)
- chosen = make(map[byte]struct{})
- )
- for i := 0; i < 3; i++ {
- var n int
- for {
- n = mrand.Intn(15) // the last range is set empty deliberately
- if _, ok := chosen[byte(n)]; ok {
- continue
- }
- chosen[byte(n)] = struct{}{}
- break
- }
- for j := 0; j < slots/3; j++ {
- key := append([]byte{byte(n)}, testutil.RandBytes(31)...)
- val, _ := rlp.EncodeToBytes(testutil.RandBytes(32))
-
- elem := &kv{key, val}
- tr.MustUpdate(elem.k, elem.v)
- entries = append(entries, elem)
- }
- }
- slices.SortFunc(entries, (*kv).cmp)
- root, nodes, _ := tr.Commit(false)
- return root, nodes, entries
-}
-
-func verifyTrie(scheme string, db ethdb.KeyValueStore, root common.Hash, t *testing.T) {
- t.Helper()
- triedb := trie.NewDatabase(rawdb.NewDatabase(db), newDbConfig(scheme))
- accTrie, err := trie.New(trie.StateTrieID(root), triedb)
- if err != nil {
- t.Fatal(err)
- }
- accounts, slots := 0, 0
- accIt := trie.NewIterator(accTrie.MustNodeIterator(nil))
- for accIt.Next() {
- var acc struct {
- Nonce uint64
- Balance *big.Int
- Root common.Hash
- CodeHash []byte
- }
- if err := rlp.DecodeBytes(accIt.Value, &acc); err != nil {
- log.Crit("Invalid account encountered during snapshot creation", "err", err)
- }
- accounts++
- if acc.Root != types.EmptyRootHash {
- id := trie.StorageTrieID(root, common.BytesToHash(accIt.Key), acc.Root)
- storeTrie, err := trie.NewStateTrie(id, triedb)
- if err != nil {
- t.Fatal(err)
- }
- storeIt := trie.NewIterator(storeTrie.MustNodeIterator(nil))
- for storeIt.Next() {
- slots++
- }
- if err := storeIt.Err; err != nil {
- t.Fatal(err)
- }
- }
- }
- if err := accIt.Err; err != nil {
- t.Fatal(err)
- }
- t.Logf("accounts: %d, slots: %d", accounts, slots)
-}
-
-// TestSyncAccountPerformance tests how efficient the snap algo is at minimizing
-// state healing
-func TestSyncAccountPerformance(t *testing.T) {
- t.Parallel()
-
- testSyncAccountPerformance(t, rawdb.HashScheme)
- testSyncAccountPerformance(t, rawdb.PathScheme)
-}
-
-func testSyncAccountPerformance(t *testing.T, scheme string) {
- // Set the account concurrency to 1. This _should_ result in the
- // range root to become correct, and there should be no healing needed
- defer func(old int) { accountConcurrency = old }(accountConcurrency)
- accountConcurrency = 1
-
- var (
- once sync.Once
- cancel = make(chan struct{})
- term = func() {
- once.Do(func() {
- close(cancel)
- })
- }
- )
- nodeScheme, sourceAccountTrie, elems := makeAccountTrieNoStorage(100, scheme)
-
- mkSource := func(name string) *testPeer {
- source := newTestPeer(name, t, term)
- source.accountTrie = sourceAccountTrie.Copy()
- source.accountValues = elems
- return source
- }
- src := mkSource("source")
- syncer := setupSyncer(nodeScheme, src)
- if err := syncer.Sync(sourceAccountTrie.Hash(), cancel); err != nil {
- t.Fatalf("sync failed: %v", err)
- }
- verifyTrie(scheme, syncer.db, sourceAccountTrie.Hash(), t)
- // The trie root will always be requested, since it is added when the snap
- // sync cycle starts. When popping the queue, we do not look it up again.
- // Doing so would bring this number down to zero in this artificial testcase,
- // but only add extra IO for no reason in practice.
- if have, want := src.nTrienodeRequests, 1; have != want {
- fmt.Print(src.Stats())
- t.Errorf("trie node heal requests wrong, want %d, have %d", want, have)
- }
-}
-
-func TestSlotEstimation(t *testing.T) {
- for i, tc := range []struct {
- last common.Hash
- count int
- want uint64
- }{
- {
- // Half the space
- common.HexToHash("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
- 100,
- 100,
- },
- {
- // 1 / 16th
- common.HexToHash("0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
- 100,
- 1500,
- },
- {
- // Bit more than 1 / 16th
- common.HexToHash("0x1000000000000000000000000000000000000000000000000000000000000000"),
- 100,
- 1499,
- },
- {
- // Almost everything
- common.HexToHash("0xF000000000000000000000000000000000000000000000000000000000000000"),
- 100,
- 6,
- },
- {
- // Almost nothing -- should lead to error
- common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000001"),
- 1,
- 0,
- },
- {
- // Nothing -- should lead to error
- common.Hash{},
- 100,
- 0,
- },
- } {
- have, _ := estimateRemainingSlots(tc.count, tc.last)
- if want := tc.want; have != want {
- t.Errorf("test %d: have %d want %d", i, have, want)
- }
- }
-}
-
-func newDbConfig(scheme string) *trie.Config {
- if scheme == rawdb.HashScheme {
- return &trie.Config{}
- }
- return &trie.Config{PathDB: pathdb.Defaults}
-}
diff --git a/eth/protocols/snap/tracker.go b/eth/protocols/snap/tracker.go
deleted file mode 100644
index 2cf59cc23a..0000000000
--- a/eth/protocols/snap/tracker.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 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 snap
-
-import (
- "time"
-
- "github.com/ethereum/go-ethereum/p2p/tracker"
-)
-
-// requestTracker is a singleton tracker for request times.
-var requestTracker = tracker.New(ProtocolName, time.Minute)
diff --git a/eth/state_accessor.go b/eth/state_accessor.go
deleted file mode 100644
index 24694df66c..0000000000
--- a/eth/state_accessor.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2021 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 eth
-
-import (
- "context"
- "errors"
- "fmt"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "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/eth/tracers"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/trie"
-)
-
-// noopReleaser is returned in case there is no operation expected
-// for releasing state.
-var noopReleaser = tracers.StateReleaseFunc(func() {})
-
-func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error) {
- var (
- current *types.Block
- database state.Database
- triedb *trie.Database
- report = true
- origin = block.NumberU64()
- )
- // The state is only for reading purposes, check the state presence in
- // live database.
- if readOnly {
- // The state is available in live database, create a reference
- // on top to prevent garbage collection and return a release
- // function to deref it.
- if statedb, err = eth.blockchain.StateAt(block.Root()); err == nil {
- eth.blockchain.TrieDB().Reference(block.Root(), common.Hash{})
- return statedb, func() {
- eth.blockchain.TrieDB().Dereference(block.Root())
- }, nil
- }
- }
- // The state is both for reading and writing, or it's unavailable in disk,
- // try to construct/recover the state over an ephemeral trie.Database for
- // isolating the live one.
- if base != nil {
- if preferDisk {
- // Create an ephemeral trie.Database for isolating the live one. Otherwise
- // the internal junks created by tracing will be persisted into the disk.
- // TODO(rjl493456442), clean cache is disabled to prevent memory leak,
- // please re-enable it for better performance.
- database = state.NewDatabaseWithConfig(eth.chainDb, trie.HashDefaults)
- if statedb, err = state.New(block.Root(), database, nil); err == nil {
- log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number())
- return statedb, noopReleaser, nil
- }
- }
- // The optional base statedb is given, mark the start point as parent block
- statedb, database, triedb, report = base, base.Database(), base.Database().TrieDB(), false
- current = eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
- } else {
- // Otherwise, try to reexec blocks until we find a state or reach our limit
- current = block
-
- // Create an ephemeral trie.Database for isolating the live one. Otherwise
- // the internal junks created by tracing will be persisted into the disk.
- // TODO(rjl493456442), clean cache is disabled to prevent memory leak,
- // please re-enable it for better performance.
- triedb = trie.NewDatabase(eth.chainDb, trie.HashDefaults)
- database = state.NewDatabaseWithNodeDB(eth.chainDb, triedb)
-
- // If we didn't check the live database, do check state over ephemeral database,
- // otherwise we would rewind past a persisted block (specific corner case is
- // chain tracing from the genesis).
- if !readOnly {
- statedb, err = state.New(current.Root(), database, nil)
- if err == nil {
- return statedb, noopReleaser, nil
- }
- }
- // Database does not have the state for the given block, try to regenerate
- for i := uint64(0); i < reexec; i++ {
- if err := ctx.Err(); err != nil {
- return nil, nil, err
- }
- if current.NumberU64() == 0 {
- return nil, nil, errors.New("genesis state is missing")
- }
- parent := eth.blockchain.GetBlock(current.ParentHash(), current.NumberU64()-1)
- if parent == nil {
- return nil, nil, fmt.Errorf("missing block %v %d", current.ParentHash(), current.NumberU64()-1)
- }
- current = parent
-
- statedb, err = state.New(current.Root(), database, nil)
- if err == nil {
- break
- }
- }
- if err != nil {
- switch err.(type) {
- case *trie.MissingNodeError:
- return nil, nil, fmt.Errorf("required historical state unavailable (reexec=%d)", reexec)
- default:
- return nil, nil, err
- }
- }
- }
- // State is available at historical point, re-execute the blocks on top for
- // the desired state.
- var (
- start = time.Now()
- logged time.Time
- parent common.Hash
- )
- for current.NumberU64() < origin {
- if err := ctx.Err(); err != nil {
- return nil, nil, err
- }
- // Print progress logs if long enough time elapsed
- if time.Since(logged) > 8*time.Second && report {
- log.Info("Regenerating historical state", "block", current.NumberU64()+1, "target", origin, "remaining", origin-current.NumberU64()-1, "elapsed", time.Since(start))
- logged = time.Now()
- }
- // Retrieve the next block to regenerate and process it
- next := current.NumberU64() + 1
- if current = eth.blockchain.GetBlockByNumber(next); current == nil {
- return nil, nil, fmt.Errorf("block #%d not found", next)
- }
- _, _, _, err := eth.blockchain.Processor().Process(current, statedb, vm.Config{})
- if err != nil {
- return nil, nil, fmt.Errorf("processing block %d failed: %v", current.NumberU64(), err)
- }
- // Finalize the state so any modifications are written to the trie
- root, err := statedb.Commit(current.NumberU64(), eth.blockchain.Config().IsEIP158(current.Number()))
- if err != nil {
- return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w",
- current.NumberU64(), current.Root().Hex(), err)
- }
- statedb, err = state.New(root, database, nil)
- if err != nil {
- return nil, nil, fmt.Errorf("state reset after block %d failed: %v", current.NumberU64(), err)
- }
- // Hold the state reference and also drop the parent state
- // to prevent accumulating too many nodes in memory.
- triedb.Reference(root, common.Hash{})
- if parent != (common.Hash{}) {
- triedb.Dereference(parent)
- }
- parent = root
- }
- if report {
- _, nodes, imgs := triedb.Size() // all memory is contained within the nodes return in hashdb
- log.Info("Historical state regenerated", "block", current.NumberU64(), "elapsed", time.Since(start), "nodes", nodes, "preimages", imgs)
- }
- return statedb, func() { triedb.Dereference(block.Root()) }, nil
-}
-
-func (eth *Ethereum) pathState(block *types.Block) (*state.StateDB, func(), error) {
- // Check if the requested state is available in the live chain.
- statedb, err := eth.blockchain.StateAt(block.Root())
- if err == nil {
- return statedb, noopReleaser, nil
- }
- // TODO historic state is not supported in path-based scheme.
- // Fully archive node in pbss will be implemented by relying
- // on state history, but needs more work on top.
- return nil, nil, errors.New("historical state not available in path scheme yet")
-}
-
-// stateAtBlock retrieves the state database associated with a certain block.
-// If no state is locally available for the given block, a number of blocks
-// are attempted to be reexecuted to generate the desired state. The optional
-// base layer statedb can be provided which is regarded as the statedb of the
-// parent block.
-//
-// An additional release function will be returned if the requested state is
-// available. Release is expected to be invoked when the returned state is no
-// longer needed. Its purpose is to prevent resource leaking. Though it can be
-// noop in some cases.
-//
-// Parameters:
-// - block: The block for which we want the state(state = block.Root)
-// - reexec: The maximum number of blocks to reprocess trying to obtain the desired state
-// - base: If the caller is tracing multiple blocks, the caller can provide the parent
-// state continuously from the callsite.
-// - readOnly: If true, then the live 'blockchain' state database is used. No mutation should
-// be made from caller, e.g. perform Commit or other 'save-to-disk' changes.
-// Otherwise, the trash generated by caller may be persisted permanently.
-// - preferDisk: This arg can be used by the caller to signal that even though the 'base' is
-// provided, it would be preferable to start from a fresh state, if we have it
-// on disk.
-func (eth *Ethereum) stateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error) {
- if eth.blockchain.TrieDB().Scheme() == rawdb.HashScheme {
- return eth.hashState(ctx, block, reexec, base, readOnly, preferDisk)
- }
- return eth.pathState(block)
-}
-
-// stateAtTransaction returns the execution environment of a certain transaction.
-func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) {
- // Short circuit if it's genesis block.
- if block.NumberU64() == 0 {
- return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis")
- }
- // Create the parent state database
- parent := eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
- if parent == nil {
- return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("parent %#x not found", block.ParentHash())
- }
- // Lookup the statedb of parent block from the live database,
- // otherwise regenerate it on the flight.
- statedb, release, err := eth.stateAtBlock(ctx, parent, reexec, nil, true, false)
- if err != nil {
- return nil, vm.BlockContext{}, nil, nil, err
- }
- if txIndex == 0 && len(block.Transactions()) == 0 {
- return nil, vm.BlockContext{}, statedb, release, nil
- }
- // Recompute transactions up to the target index.
- signer := types.MakeSigner(eth.blockchain.Config(), block.Number(), block.Time())
- for idx, tx := range block.Transactions() {
- // Assemble the transaction call message and return if the requested offset
- msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
- txContext := core.NewEVMTxContext(msg)
- context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
- if idx == txIndex {
- return msg, context, statedb, release, nil
- }
- // Not yet the searched for transaction, execute on top of the current state
- vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{})
- statedb.SetTxContext(tx.Hash(), idx)
- if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
- return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
- }
- // Ensure any modifications are committed to the state
- // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
- statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
- }
- return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
-}
diff --git a/eth/sync.go b/eth/sync.go
deleted file mode 100644
index c7ba7c93d6..0000000000
--- a/eth/sync.go
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2015 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 eth
-
-import (
- "errors"
- "math/big"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/log"
-)
-
-const (
- forceSyncCycle = 10 * time.Second // Time interval to force syncs, even if few peers are available
- defaultMinSyncPeers = 5 // Amount of peers desired to start syncing
-)
-
-// syncTransactions starts sending all currently pending transactions to the given peer.
-func (h *handler) syncTransactions(p *eth.Peer) {
- var hashes []common.Hash
- for _, batch := range h.txpool.Pending(false) {
- for _, tx := range batch {
- hashes = append(hashes, tx.Hash)
- }
- }
- if len(hashes) == 0 {
- return
- }
- p.AsyncSendPooledTransactionHashes(hashes)
-}
-
-// chainSyncer coordinates blockchain sync components.
-type chainSyncer struct {
- handler *handler
- force *time.Timer
- forced bool // true when force timer fired
- warned time.Time
- peerEventCh chan struct{}
- doneCh chan error // non-nil when sync is running
-}
-
-// chainSyncOp is a scheduled sync operation.
-type chainSyncOp struct {
- mode downloader.SyncMode
- peer *eth.Peer
- td *big.Int
- head common.Hash
-}
-
-// newChainSyncer creates a chainSyncer.
-func newChainSyncer(handler *handler) *chainSyncer {
- return &chainSyncer{
- handler: handler,
- peerEventCh: make(chan struct{}),
- }
-}
-
-// handlePeerEvent notifies the syncer about a change in the peer set.
-// This is called for new peers and every time a peer announces a new
-// chain head.
-func (cs *chainSyncer) handlePeerEvent() bool {
- select {
- case cs.peerEventCh <- struct{}{}:
- return true
- case <-cs.handler.quitSync:
- return false
- }
-}
-
-// loop runs in its own goroutine and launches the sync when necessary.
-func (cs *chainSyncer) loop() {
- defer cs.handler.wg.Done()
-
- cs.handler.blockFetcher.Start()
- cs.handler.txFetcher.Start()
- defer cs.handler.blockFetcher.Stop()
- defer cs.handler.txFetcher.Stop()
- defer cs.handler.downloader.Terminate()
-
- // The force timer lowers the peer count threshold down to one when it fires.
- // This ensures we'll always start sync even if there aren't enough peers.
- cs.force = time.NewTimer(forceSyncCycle)
- defer cs.force.Stop()
-
- for {
- if op := cs.nextSyncOp(); op != nil {
- cs.startSync(op)
- }
- select {
- case <-cs.peerEventCh:
- // Peer information changed, recheck.
- case err := <-cs.doneCh:
- cs.doneCh = nil
- cs.force.Reset(forceSyncCycle)
- cs.forced = false
-
- // If we've reached the merge transition but no beacon client is available, or
- // it has not yet switched us over, keep warning the user that their infra is
- // potentially flaky.
- if errors.Is(err, downloader.ErrMergeTransition) && time.Since(cs.warned) > 10*time.Second {
- log.Warn("Local chain is post-merge, waiting for beacon client sync switch-over...")
- cs.warned = time.Now()
- }
- case <-cs.force.C:
- cs.forced = true
-
- case <-cs.handler.quitSync:
- // Disable all insertion on the blockchain. This needs to happen before
- // terminating the downloader because the downloader waits for blockchain
- // inserts, and these can take a long time to finish.
- cs.handler.chain.StopInsert()
- cs.handler.downloader.Terminate()
- if cs.doneCh != nil {
- <-cs.doneCh
- }
- return
- }
- }
-}
-
-// nextSyncOp determines whether sync is required at this time.
-func (cs *chainSyncer) nextSyncOp() *chainSyncOp {
- if cs.doneCh != nil {
- return nil // Sync already running
- }
- // If a beacon client once took over control, disable the entire legacy sync
- // path from here on end. Note, there is a slight "race" between reaching TTD
- // and the beacon client taking over. The downloader will enforce that nothing
- // above the first TTD will be delivered to the chain for import.
- //
- // An alternative would be to check the local chain for exceeding the TTD and
- // avoid triggering a sync in that case, but that could also miss sibling or
- // other family TTD block being accepted.
- if cs.handler.chain.Config().TerminalTotalDifficultyPassed || cs.handler.merger.TDDReached() {
- return nil
- }
- // Ensure we're at minimum peer count.
- minPeers := defaultMinSyncPeers
- if cs.forced {
- minPeers = 1
- } else if minPeers > cs.handler.maxPeers {
- minPeers = cs.handler.maxPeers
- }
- if cs.handler.peers.len() < minPeers {
- return nil
- }
- // We have enough peers, pick the one with the highest TD, but avoid going
- // over the terminal total difficulty. Above that we expect the consensus
- // clients to direct the chain head to sync to.
- peer := cs.handler.peers.peerWithHighestTD()
- if peer == nil {
- return nil
- }
- mode, ourTD := cs.modeAndLocalHead()
- op := peerToSyncOp(mode, peer)
- if op.td.Cmp(ourTD) <= 0 {
- // We seem to be in sync according to the legacy rules. In the merge
- // world, it can also mean we're stuck on the merge block, waiting for
- // a beacon client. In the latter case, notify the user.
- if ttd := cs.handler.chain.Config().TerminalTotalDifficulty; ttd != nil && ourTD.Cmp(ttd) >= 0 && time.Since(cs.warned) > 10*time.Second {
- log.Warn("Local chain is post-merge, waiting for beacon client sync switch-over...")
- cs.warned = time.Now()
- }
- return nil // We're in sync
- }
- return op
-}
-
-func peerToSyncOp(mode downloader.SyncMode, p *eth.Peer) *chainSyncOp {
- peerHead, peerTD := p.Head()
- return &chainSyncOp{mode: mode, peer: p, td: peerTD, head: peerHead}
-}
-
-func (cs *chainSyncer) modeAndLocalHead() (downloader.SyncMode, *big.Int) {
- // If we're in snap sync mode, return that directly
- if cs.handler.snapSync.Load() {
- block := cs.handler.chain.CurrentSnapBlock()
- td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
- return downloader.SnapSync, td
- }
- // We are probably in full sync, but we might have rewound to before the
- // snap sync pivot, check if we should re-enable snap sync.
- head := cs.handler.chain.CurrentBlock()
- if pivot := rawdb.ReadLastPivotNumber(cs.handler.database); pivot != nil {
- if head.Number.Uint64() < *pivot {
- block := cs.handler.chain.CurrentSnapBlock()
- td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
- return downloader.SnapSync, td
- }
- }
- // We are in a full sync, but the associated head state is missing. To complete
- // the head state, forcefully rerun the snap sync. Note it doesn't mean the
- // persistent state is corrupted, just mismatch with the head block.
- if !cs.handler.chain.HasState(head.Root) {
- block := cs.handler.chain.CurrentSnapBlock()
- td := cs.handler.chain.GetTd(block.Hash(), block.Number.Uint64())
- log.Info("Reenabled snap sync as chain is stateless")
- return downloader.SnapSync, td
- }
- // Nope, we're really full syncing
- td := cs.handler.chain.GetTd(head.Hash(), head.Number.Uint64())
- return downloader.FullSync, td
-}
-
-// startSync launches doSync in a new goroutine.
-func (cs *chainSyncer) startSync(op *chainSyncOp) {
- cs.doneCh = make(chan error, 1)
- go func() { cs.doneCh <- cs.handler.doSync(op) }()
-}
-
-// doSync synchronizes the local blockchain with a remote peer.
-func (h *handler) doSync(op *chainSyncOp) error {
- if op.mode == downloader.SnapSync {
- // Before launch the snap sync, we have to ensure user uses the same
- // txlookup limit.
- // The main concern here is: during the snap sync Geth won't index the
- // block(generate tx indices) before the HEAD-limit. But if user changes
- // the limit in the next snap sync(e.g. user kill Geth manually and
- // restart) then it will be hard for Geth to figure out the oldest block
- // has been indexed. So here for the user-experience wise, it's non-optimal
- // that user can't change limit during the snap sync. If changed, Geth
- // will just blindly use the original one.
- limit := h.chain.TxLookupLimit()
- if stored := rawdb.ReadFastTxLookupLimit(h.database); stored == nil {
- rawdb.WriteFastTxLookupLimit(h.database, limit)
- } else if *stored != limit {
- h.chain.SetTxLookupLimit(*stored)
- log.Warn("Update txLookup limit", "provided", limit, "updated", *stored)
- }
- }
- // Run the sync cycle, and disable snap sync if we're past the pivot block
- err := h.downloader.LegacySync(op.peer.ID(), op.head, op.td, h.chain.Config().TerminalTotalDifficulty, op.mode)
- if err != nil {
- return err
- }
- h.enableSyncedFeatures()
-
- head := h.chain.CurrentBlock()
- if head.Number.Uint64() > 0 {
- // We've completed a sync cycle, notify all peers of new state. This path is
- // essential in star-topology networks where a gateway node needs to notify
- // all its out-of-date peers of the availability of a new block. This failure
- // scenario will most often crop up in private and hackathon networks with
- // degenerate connectivity, but it should be healthy for the mainnet too to
- // more reliably update peers or the local TD state.
- if block := h.chain.GetBlock(head.Hash(), head.Number.Uint64()); block != nil {
- h.BroadcastBlock(block, false)
- }
- }
- return nil
-}
diff --git a/eth/sync_test.go b/eth/sync_test.go
deleted file mode 100644
index d26cbb66ea..0000000000
--- a/eth/sync_test.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2015 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 eth
-
-import (
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/protocols/eth"
- "github.com/ethereum/go-ethereum/eth/protocols/snap"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/enode"
-)
-
-// Tests that snap sync is disabled after a successful sync cycle.
-func TestSnapSyncDisabling67(t *testing.T) { testSnapSyncDisabling(t, eth.ETH67, snap.SNAP1) }
-func TestSnapSyncDisabling68(t *testing.T) { testSnapSyncDisabling(t, eth.ETH68, snap.SNAP1) }
-
-// Tests that snap sync gets disabled as soon as a real block is successfully
-// imported into the blockchain.
-func testSnapSyncDisabling(t *testing.T, ethVer uint, snapVer uint) {
- t.Parallel()
-
- // Create an empty handler and ensure it's in snap sync mode
- empty := newTestHandler()
- if !empty.handler.snapSync.Load() {
- t.Fatalf("snap sync disabled on pristine blockchain")
- }
- defer empty.close()
-
- // Create a full handler and ensure snap sync ends up disabled
- full := newTestHandlerWithBlocks(1024)
- if full.handler.snapSync.Load() {
- t.Fatalf("snap sync not disabled on non-empty blockchain")
- }
- defer full.close()
-
- // Sync up the two handlers via both `eth` and `snap`
- caps := []p2p.Cap{{Name: "eth", Version: ethVer}, {Name: "snap", Version: snapVer}}
-
- emptyPipeEth, fullPipeEth := p2p.MsgPipe()
- defer emptyPipeEth.Close()
- defer fullPipeEth.Close()
-
- emptyPeerEth := eth.NewPeer(ethVer, p2p.NewPeer(enode.ID{1}, "", caps), emptyPipeEth, empty.txpool)
- fullPeerEth := eth.NewPeer(ethVer, p2p.NewPeer(enode.ID{2}, "", caps), fullPipeEth, full.txpool)
- defer emptyPeerEth.Close()
- defer fullPeerEth.Close()
-
- go empty.handler.runEthPeer(emptyPeerEth, func(peer *eth.Peer) error {
- return eth.Handle((*ethHandler)(empty.handler), peer)
- })
- go full.handler.runEthPeer(fullPeerEth, func(peer *eth.Peer) error {
- return eth.Handle((*ethHandler)(full.handler), peer)
- })
-
- emptyPipeSnap, fullPipeSnap := p2p.MsgPipe()
- defer emptyPipeSnap.Close()
- defer fullPipeSnap.Close()
-
- emptyPeerSnap := snap.NewPeer(snapVer, p2p.NewPeer(enode.ID{1}, "", caps), emptyPipeSnap)
- fullPeerSnap := snap.NewPeer(snapVer, p2p.NewPeer(enode.ID{2}, "", caps), fullPipeSnap)
-
- go empty.handler.runSnapExtension(emptyPeerSnap, func(peer *snap.Peer) error {
- return snap.Handle((*snapHandler)(empty.handler), peer)
- })
- go full.handler.runSnapExtension(fullPeerSnap, func(peer *snap.Peer) error {
- return snap.Handle((*snapHandler)(full.handler), peer)
- })
- // Wait a bit for the above handlers to start
- time.Sleep(250 * time.Millisecond)
-
- // Check that snap sync was disabled
- op := peerToSyncOp(downloader.SnapSync, empty.handler.peers.peerWithHighestTD())
- if err := empty.handler.doSync(op); err != nil {
- t.Fatal("sync failed:", err)
- }
- if empty.handler.snapSync.Load() {
- t.Fatalf("snap sync not disabled after successful synchronisation")
- }
-}
diff --git a/eth/tracers/api.go b/eth/tracers/api.go
deleted file mode 100644
index 7c0028601d..0000000000
--- a/eth/tracers/api.go
+++ /dev/null
@@ -1,1040 +0,0 @@
-// Copyright 2021 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 tracers
-
-import (
- "bufio"
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "os"
- "runtime"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/rawdb"
- "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/eth/tracers/logger"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-const (
- // defaultTraceTimeout is the amount of time a single transaction can execute
- // by default before being forcefully aborted.
- defaultTraceTimeout = 5 * time.Second
-
- // defaultTraceReexec is the number of blocks the tracer is willing to go back
- // and reexecute to produce missing historical state necessary to run a specific
- // trace.
- defaultTraceReexec = uint64(128)
-
- // defaultTracechainMemLimit is the size of the triedb, at which traceChain
- // switches over and tries to use a disk-backed database instead of building
- // on top of memory.
- // For non-archive nodes, this limit _will_ be overblown, as disk-backed tries
- // will only be found every ~15K blocks or so.
- defaultTracechainMemLimit = common.StorageSize(500 * 1024 * 1024)
-
- // maximumPendingTraceStates is the maximum number of states allowed waiting
- // for tracing. The creation of trace state will be paused if the unused
- // trace states exceed this limit.
- maximumPendingTraceStates = 128
-)
-
-var errTxNotFound = errors.New("transaction not found")
-
-// StateReleaseFunc is used to deallocate resources held by constructing a
-// historical state for tracing purposes.
-type StateReleaseFunc func()
-
-// Backend interface provides the common API services (that are provided by
-// both full and light clients) with access to necessary functions.
-type Backend interface {
- HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error)
- HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error)
- BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
- BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error)
- GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
- RPCGasCap() uint64
- ChainConfig() *params.ChainConfig
- Engine() consensus.Engine
- ChainDb() ethdb.Database
- StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error)
- StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error)
-}
-
-// API is the collection of tracing APIs exposed over the private debugging endpoint.
-type API struct {
- backend Backend
-}
-
-// NewAPI creates a new API definition for the tracing methods of the Ethereum service.
-func NewAPI(backend Backend) *API {
- return &API{backend: backend}
-}
-
-// chainContext constructs the context reader which is used by the evm for reading
-// the necessary chain context.
-func (api *API) chainContext(ctx context.Context) core.ChainContext {
- return ethapi.NewChainContext(ctx, api.backend)
-}
-
-// blockByNumber is the wrapper of the chain access function offered by the backend.
-// It will return an error if the block is not found.
-func (api *API) blockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
- block, err := api.backend.BlockByNumber(ctx, number)
- if err != nil {
- return nil, err
- }
- if block == nil {
- return nil, fmt.Errorf("block #%d not found", number)
- }
- return block, nil
-}
-
-// blockByHash is the wrapper of the chain access function offered by the backend.
-// It will return an error if the block is not found.
-func (api *API) blockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
- block, err := api.backend.BlockByHash(ctx, hash)
- if err != nil {
- return nil, err
- }
- if block == nil {
- return nil, fmt.Errorf("block %s not found", hash.Hex())
- }
- return block, nil
-}
-
-// blockByNumberAndHash is the wrapper of the chain access function offered by
-// the backend. It will return an error if the block is not found.
-//
-// Note this function is friendly for the light client which can only retrieve the
-// historical(before the CHT) header/block by number.
-func (api *API) blockByNumberAndHash(ctx context.Context, number rpc.BlockNumber, hash common.Hash) (*types.Block, error) {
- block, err := api.blockByNumber(ctx, number)
- if err != nil {
- return nil, err
- }
- if block.Hash() == hash {
- return block, nil
- }
- return api.blockByHash(ctx, hash)
-}
-
-// TraceConfig holds extra parameters to trace functions.
-type TraceConfig struct {
- *logger.Config
- Tracer *string
- Timeout *string
- Reexec *uint64
- // Config specific to given tracer. Note struct logger
- // config are historically embedded in main object.
- TracerConfig json.RawMessage
-}
-
-// TraceCallConfig is the config for traceCall API. It holds one more
-// field to override the state for tracing.
-type TraceCallConfig struct {
- TraceConfig
- StateOverrides *ethapi.StateOverride
- BlockOverrides *ethapi.BlockOverrides
- TxIndex *hexutil.Uint
-}
-
-// StdTraceConfig holds extra parameters to standard-json trace functions.
-type StdTraceConfig struct {
- logger.Config
- Reexec *uint64
- TxHash common.Hash
-}
-
-// txTraceResult is the result of a single transaction trace.
-type txTraceResult struct {
- TxHash common.Hash `json:"txHash"` // transaction hash
- Result interface{} `json:"result,omitempty"` // Trace results produced by the tracer
- Error string `json:"error,omitempty"` // Trace failure produced by the tracer
-}
-
-// blockTraceTask represents a single block trace task when an entire chain is
-// being traced.
-type blockTraceTask struct {
- statedb *state.StateDB // Intermediate state prepped for tracing
- block *types.Block // Block to trace the transactions from
- release StateReleaseFunc // The function to release the held resource for this task
- results []*txTraceResult // Trace results produced by the task
-}
-
-// blockTraceResult represents the results of tracing a single block when an entire
-// chain is being traced.
-type blockTraceResult struct {
- Block hexutil.Uint64 `json:"block"` // Block number corresponding to this trace
- Hash common.Hash `json:"hash"` // Block hash corresponding to this trace
- Traces []*txTraceResult `json:"traces"` // Trace results produced by the task
-}
-
-// txTraceTask represents a single transaction trace task when an entire block
-// is being traced.
-type txTraceTask struct {
- statedb *state.StateDB // Intermediate state prepped for tracing
- index int // Transaction offset in the block
-}
-
-// TraceChain returns the structured logs created during the execution of EVM
-// between two blocks (excluding start) and returns them as a JSON object.
-func (api *API) TraceChain(ctx context.Context, start, end rpc.BlockNumber, config *TraceConfig) (*rpc.Subscription, error) { // Fetch the block interval that we want to trace
- from, err := api.blockByNumber(ctx, start)
- if err != nil {
- return nil, err
- }
- to, err := api.blockByNumber(ctx, end)
- if err != nil {
- return nil, err
- }
- if from.Number().Cmp(to.Number()) >= 0 {
- return nil, fmt.Errorf("end block (#%d) needs to come after start block (#%d)", end, start)
- }
- // Tracing a chain is a **long** operation, only do with subscriptions
- notifier, supported := rpc.NotifierFromContext(ctx)
- if !supported {
- return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
- }
- sub := notifier.CreateSubscription()
-
- resCh := api.traceChain(from, to, config, notifier.Closed())
- go func() {
- for result := range resCh {
- notifier.Notify(sub.ID, result)
- }
- }()
- return sub, nil
-}
-
-// traceChain configures a new tracer according to the provided configuration, and
-// executes all the transactions contained within. The tracing chain range includes
-// the end block but excludes the start one. The return value will be one item per
-// transaction, dependent on the requested tracer.
-// The tracing procedure should be aborted in case the closed signal is received.
-func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed <-chan interface{}) chan *blockTraceResult {
- reexec := defaultTraceReexec
- if config != nil && config.Reexec != nil {
- reexec = *config.Reexec
- }
- blocks := int(end.NumberU64() - start.NumberU64())
- threads := runtime.NumCPU()
- if threads > blocks {
- threads = blocks
- }
- var (
- pend = new(sync.WaitGroup)
- ctx = context.Background()
- taskCh = make(chan *blockTraceTask, threads)
- resCh = make(chan *blockTraceTask, threads)
- tracker = newStateTracker(maximumPendingTraceStates, start.NumberU64())
- )
- for th := 0; th < threads; th++ {
- pend.Add(1)
- go func() {
- defer pend.Done()
-
- // Fetch and execute the block trace taskCh
- for task := range taskCh {
- var (
- signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time())
- blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil)
- )
- // Trace all the transactions contained within
- for i, tx := range task.block.Transactions() {
- msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee())
- txctx := &Context{
- BlockHash: task.block.Hash(),
- BlockNumber: task.block.Number(),
- TxIndex: i,
- TxHash: tx.Hash(),
- }
- res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config)
- if err != nil {
- task.results[i] = &txTraceResult{TxHash: tx.Hash(), Error: err.Error()}
- log.Warn("Tracing failed", "hash", tx.Hash(), "block", task.block.NumberU64(), "err", err)
- break
- }
- // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
- task.statedb.Finalise(api.backend.ChainConfig().IsEIP158(task.block.Number()))
- task.results[i] = &txTraceResult{TxHash: tx.Hash(), Result: res}
- }
- // Tracing state is used up, queue it for de-referencing. Note the
- // state is the parent state of trace block, use block.number-1 as
- // the state number.
- tracker.releaseState(task.block.NumberU64()-1, task.release)
-
- // Stream the result back to the result catcher or abort on teardown
- select {
- case resCh <- task:
- case <-closed:
- return
- }
- }
- }()
- }
- // Start a goroutine to feed all the blocks into the tracers
- go func() {
- var (
- logged time.Time
- begin = time.Now()
- number uint64
- traced uint64
- failed error
- statedb *state.StateDB
- release StateReleaseFunc
- )
- // Ensure everything is properly cleaned up on any exit path
- defer func() {
- close(taskCh)
- pend.Wait()
-
- // Clean out any pending release functions of trace states.
- tracker.callReleases()
-
- // Log the chain result
- switch {
- case failed != nil:
- log.Warn("Chain tracing failed", "start", start.NumberU64(), "end", end.NumberU64(), "transactions", traced, "elapsed", time.Since(begin), "err", failed)
- case number < end.NumberU64():
- log.Warn("Chain tracing aborted", "start", start.NumberU64(), "end", end.NumberU64(), "abort", number, "transactions", traced, "elapsed", time.Since(begin))
- default:
- log.Info("Chain tracing finished", "start", start.NumberU64(), "end", end.NumberU64(), "transactions", traced, "elapsed", time.Since(begin))
- }
- close(resCh)
- }()
- // Feed all the blocks both into the tracer, as well as fast process concurrently
- for number = start.NumberU64(); number < end.NumberU64(); number++ {
- // Stop tracing if interruption was requested
- select {
- case <-closed:
- return
- default:
- }
- // Print progress logs if long enough time elapsed
- if time.Since(logged) > 8*time.Second {
- logged = time.Now()
- log.Info("Tracing chain segment", "start", start.NumberU64(), "end", end.NumberU64(), "current", number, "transactions", traced, "elapsed", time.Since(begin))
- }
- // Retrieve the parent block and target block for tracing.
- block, err := api.blockByNumber(ctx, rpc.BlockNumber(number))
- if err != nil {
- failed = err
- break
- }
- next, err := api.blockByNumber(ctx, rpc.BlockNumber(number+1))
- if err != nil {
- failed = err
- break
- }
- // Make sure the state creator doesn't go too far. Too many unprocessed
- // trace state may cause the oldest state to become stale(e.g. in
- // path-based scheme).
- if err = tracker.wait(number); err != nil {
- failed = err
- break
- }
- // Prepare the statedb for tracing. Don't use the live database for
- // tracing to avoid persisting state junks into the database. Switch
- // over to `preferDisk` mode only if the memory usage exceeds the
- // limit, the trie database will be reconstructed from scratch only
- // if the relevant state is available in disk.
- var preferDisk bool
- if statedb != nil {
- s1, s2, s3 := statedb.Database().TrieDB().Size()
- preferDisk = s1+s2+s3 > defaultTracechainMemLimit
- }
- statedb, release, err = api.backend.StateAtBlock(ctx, block, reexec, statedb, false, preferDisk)
- if err != nil {
- failed = err
- break
- }
- // Clean out any pending release functions of trace state. Note this
- // step must be done after constructing tracing state, because the
- // tracing state of block next depends on the parent state and construction
- // may fail if we release too early.
- tracker.callReleases()
-
- // Send the block over to the concurrent tracers (if not in the fast-forward phase)
- txs := next.Transactions()
- select {
- case taskCh <- &blockTraceTask{statedb: statedb.Copy(), block: next, release: release, results: make([]*txTraceResult, len(txs))}:
- case <-closed:
- tracker.releaseState(number, release)
- return
- }
- traced += uint64(len(txs))
- }
- }()
-
- // Keep reading the trace results and stream them to result channel.
- retCh := make(chan *blockTraceResult)
- go func() {
- defer close(retCh)
- var (
- next = start.NumberU64() + 1
- done = make(map[uint64]*blockTraceResult)
- )
- for res := range resCh {
- // Queue up next received result
- result := &blockTraceResult{
- Block: hexutil.Uint64(res.block.NumberU64()),
- Hash: res.block.Hash(),
- Traces: res.results,
- }
- done[uint64(result.Block)] = result
-
- // Stream completed traces to the result channel
- for result, ok := done[next]; ok; result, ok = done[next] {
- if len(result.Traces) > 0 || next == end.NumberU64() {
- // It will be blocked in case the channel consumer doesn't take the
- // tracing result in time(e.g. the websocket connect is not stable)
- // which will eventually block the entire chain tracer. It's the
- // expected behavior to not waste node resources for a non-active user.
- retCh <- result
- }
- delete(done, next)
- next++
- }
- }
- }()
- return retCh
-}
-
-// TraceBlockByNumber returns the structured logs created during the execution of
-// EVM and returns them as a JSON object.
-func (api *API) TraceBlockByNumber(ctx context.Context, number rpc.BlockNumber, config *TraceConfig) ([]*txTraceResult, error) {
- block, err := api.blockByNumber(ctx, number)
- if err != nil {
- return nil, err
- }
- return api.traceBlock(ctx, block, config)
-}
-
-// TraceBlockByHash returns the structured logs created during the execution of
-// EVM and returns them as a JSON object.
-func (api *API) TraceBlockByHash(ctx context.Context, hash common.Hash, config *TraceConfig) ([]*txTraceResult, error) {
- block, err := api.blockByHash(ctx, hash)
- if err != nil {
- return nil, err
- }
- return api.traceBlock(ctx, block, config)
-}
-
-// TraceBlock returns the structured logs created during the execution of EVM
-// and returns them as a JSON object.
-func (api *API) TraceBlock(ctx context.Context, blob hexutil.Bytes, config *TraceConfig) ([]*txTraceResult, error) {
- block := new(types.Block)
- if err := rlp.DecodeBytes(blob, block); err != nil {
- return nil, fmt.Errorf("could not decode block: %v", err)
- }
- return api.traceBlock(ctx, block, config)
-}
-
-// TraceBlockFromFile returns the structured logs created during the execution of
-// EVM and returns them as a JSON object.
-func (api *API) TraceBlockFromFile(ctx context.Context, file string, config *TraceConfig) ([]*txTraceResult, error) {
- blob, err := os.ReadFile(file)
- if err != nil {
- return nil, fmt.Errorf("could not read file: %v", err)
- }
- return api.TraceBlock(ctx, blob, config)
-}
-
-// TraceBadBlock returns the structured logs created during the execution of
-// EVM against a block pulled from the pool of bad ones and returns them as a JSON
-// object.
-func (api *API) TraceBadBlock(ctx context.Context, hash common.Hash, config *TraceConfig) ([]*txTraceResult, error) {
- block := rawdb.ReadBadBlock(api.backend.ChainDb(), hash)
- if block == nil {
- return nil, fmt.Errorf("bad block %#x not found", hash)
- }
- return api.traceBlock(ctx, block, config)
-}
-
-// StandardTraceBlockToFile dumps the structured logs created during the
-// execution of EVM to the local file system and returns a list of files
-// to the caller.
-func (api *API) StandardTraceBlockToFile(ctx context.Context, hash common.Hash, config *StdTraceConfig) ([]string, error) {
- block, err := api.blockByHash(ctx, hash)
- if err != nil {
- return nil, err
- }
- return api.standardTraceBlockToFile(ctx, block, config)
-}
-
-// IntermediateRoots executes a block (bad- or canon- or side-), and returns a list
-// of intermediate roots: the stateroot after each transaction.
-func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config *TraceConfig) ([]common.Hash, error) {
- block, _ := api.blockByHash(ctx, hash)
- if block == nil {
- // Check in the bad blocks
- block = rawdb.ReadBadBlock(api.backend.ChainDb(), hash)
- }
- if block == nil {
- return nil, fmt.Errorf("block %#x not found", hash)
- }
- if block.NumberU64() == 0 {
- return nil, errors.New("genesis is not traceable")
- }
- parent, err := api.blockByNumberAndHash(ctx, rpc.BlockNumber(block.NumberU64()-1), block.ParentHash())
- if err != nil {
- return nil, err
- }
- reexec := defaultTraceReexec
- if config != nil && config.Reexec != nil {
- reexec = *config.Reexec
- }
- statedb, release, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false)
- if err != nil {
- return nil, err
- }
- defer release()
-
- var (
- roots []common.Hash
- signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
- chainConfig = api.backend.ChainConfig()
- vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
- deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
- )
- for i, tx := range block.Transactions() {
- if err := ctx.Err(); err != nil {
- return nil, err
- }
- var (
- msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee())
- txContext = core.NewEVMTxContext(msg)
- vmenv = vm.NewEVM(vmctx, txContext, statedb, chainConfig, vm.Config{})
- )
- statedb.SetTxContext(tx.Hash(), i)
- if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
- log.Warn("Tracing intermediate roots did not complete", "txindex", i, "txhash", tx.Hash(), "err", err)
- // We intentionally don't return the error here: if we do, then the RPC server will not
- // return the roots. Most likely, the caller already knows that a certain transaction fails to
- // be included, but still want the intermediate roots that led to that point.
- // It may happen the tx_N causes an erroneous state, which in turn causes tx_N+M to not be
- // executable.
- // N.B: This should never happen while tracing canon blocks, only when tracing bad blocks.
- return roots, nil
- }
- // calling IntermediateRoot will internally call Finalize on the state
- // so any modifications are written to the trie
- roots = append(roots, statedb.IntermediateRoot(deleteEmptyObjects))
- }
- return roots, nil
-}
-
-// StandardTraceBadBlockToFile dumps the structured logs created during the
-// execution of EVM against a block pulled from the pool of bad ones to the
-// local file system and returns a list of files to the caller.
-func (api *API) StandardTraceBadBlockToFile(ctx context.Context, hash common.Hash, config *StdTraceConfig) ([]string, error) {
- block := rawdb.ReadBadBlock(api.backend.ChainDb(), hash)
- if block == nil {
- return nil, fmt.Errorf("bad block %#x not found", hash)
- }
- return api.standardTraceBlockToFile(ctx, block, config)
-}
-
-// traceBlock configures a new tracer according to the provided configuration, and
-// executes all the transactions contained within. The return value will be one item
-// per transaction, dependent on the requested tracer.
-func (api *API) traceBlock(ctx context.Context, block *types.Block, config *TraceConfig) ([]*txTraceResult, error) {
- if block.NumberU64() == 0 {
- return nil, errors.New("genesis is not traceable")
- }
- // Prepare base state
- parent, err := api.blockByNumberAndHash(ctx, rpc.BlockNumber(block.NumberU64()-1), block.ParentHash())
- if err != nil {
- return nil, err
- }
- reexec := defaultTraceReexec
- if config != nil && config.Reexec != nil {
- reexec = *config.Reexec
- }
- statedb, release, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false)
- if err != nil {
- return nil, err
- }
- defer release()
-
- // JS tracers have high overhead. In this case run a parallel
- // process that generates states in one thread and traces txes
- // in separate worker threads.
- if config != nil && config.Tracer != nil && *config.Tracer != "" {
- if isJS := DefaultDirectory.IsJS(*config.Tracer); isJS {
- return api.traceBlockParallel(ctx, block, statedb, config)
- }
- }
- // Native tracers have low overhead
- var (
- txs = block.Transactions()
- blockHash = block.Hash()
- is158 = api.backend.ChainConfig().IsEIP158(block.Number())
- blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
- signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
- results = make([]*txTraceResult, len(txs))
- )
- for i, tx := range txs {
- // Generate the next state snapshot fast without tracing
- msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
- txctx := &Context{
- BlockHash: blockHash,
- BlockNumber: block.Number(),
- TxIndex: i,
- TxHash: tx.Hash(),
- }
- res, err := api.traceTx(ctx, msg, txctx, blockCtx, statedb, config)
- if err != nil {
- return nil, err
- }
- results[i] = &txTraceResult{TxHash: tx.Hash(), Result: res}
- // Finalize the state so any modifications are written to the trie
- // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
- statedb.Finalise(is158)
- }
- return results, nil
-}
-
-// traceBlockParallel is for tracers that have a high overhead (read JS tracers). One thread
-// runs along and executes txes without tracing enabled to generate their prestate.
-// Worker threads take the tasks and the prestate and trace them.
-func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, statedb *state.StateDB, config *TraceConfig) ([]*txTraceResult, error) {
- // Execute all the transaction contained within the block concurrently
- var (
- txs = block.Transactions()
- blockHash = block.Hash()
- blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
- signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
- results = make([]*txTraceResult, len(txs))
- pend sync.WaitGroup
- )
- threads := runtime.NumCPU()
- if threads > len(txs) {
- threads = len(txs)
- }
- jobs := make(chan *txTraceTask, threads)
- for th := 0; th < threads; th++ {
- pend.Add(1)
- go func() {
- defer pend.Done()
- // Fetch and execute the next transaction trace tasks
- for task := range jobs {
- msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee())
- txctx := &Context{
- BlockHash: blockHash,
- BlockNumber: block.Number(),
- TxIndex: task.index,
- TxHash: txs[task.index].Hash(),
- }
- res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config)
- if err != nil {
- results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Error: err.Error()}
- continue
- }
- results[task.index] = &txTraceResult{TxHash: txs[task.index].Hash(), Result: res}
- }
- }()
- }
-
- // Feed the transactions into the tracers and return
- var failed error
-txloop:
- for i, tx := range txs {
- // Send the trace task over for execution
- task := &txTraceTask{statedb: statedb.Copy(), index: i}
- select {
- case <-ctx.Done():
- failed = ctx.Err()
- break txloop
- case jobs <- task:
- }
-
- // Generate the next state snapshot fast without tracing
- msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
- statedb.SetTxContext(tx.Hash(), i)
- vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{})
- if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
- failed = err
- break txloop
- }
- // Finalize the state so any modifications are written to the trie
- // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
- statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
- }
-
- close(jobs)
- pend.Wait()
-
- // If execution failed in between, abort
- if failed != nil {
- return nil, failed
- }
- return results, nil
-}
-
-// standardTraceBlockToFile configures a new tracer which uses standard JSON output,
-// and traces either a full block or an individual transaction. The return value will
-// be one filename per transaction traced.
-func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block, config *StdTraceConfig) ([]string, error) {
- // If we're tracing a single transaction, make sure it's present
- if config != nil && config.TxHash != (common.Hash{}) {
- if !containsTx(block, config.TxHash) {
- return nil, fmt.Errorf("transaction %#x not found in block", config.TxHash)
- }
- }
- if block.NumberU64() == 0 {
- return nil, errors.New("genesis is not traceable")
- }
- parent, err := api.blockByNumberAndHash(ctx, rpc.BlockNumber(block.NumberU64()-1), block.ParentHash())
- if err != nil {
- return nil, err
- }
- reexec := defaultTraceReexec
- if config != nil && config.Reexec != nil {
- reexec = *config.Reexec
- }
- statedb, release, err := api.backend.StateAtBlock(ctx, parent, reexec, nil, true, false)
- if err != nil {
- return nil, err
- }
- defer release()
-
- // Retrieve the tracing configurations, or use default values
- var (
- logConfig logger.Config
- txHash common.Hash
- )
- if config != nil {
- logConfig = config.Config
- txHash = config.TxHash
- }
- logConfig.Debug = true
-
- // Execute transaction, either tracing all or just the requested one
- var (
- dumps []string
- signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
- chainConfig = api.backend.ChainConfig()
- vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
- canon = true
- )
- // Check if there are any overrides: the caller may wish to enable a future
- // fork when executing this block. Note, such overrides are only applicable to the
- // actual specified block, not any preceding blocks that we have to go through
- // in order to obtain the state.
- // Therefore, it's perfectly valid to specify `"futureForkBlock": 0`, to enable `futureFork`
- if config != nil && config.Overrides != nil {
- // Note: This copies the config, to not screw up the main config
- chainConfig, canon = overrideConfig(chainConfig, config.Overrides)
- }
- for i, tx := range block.Transactions() {
- // Prepare the transaction for un-traced execution
- var (
- msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee())
- txContext = core.NewEVMTxContext(msg)
- vmConf vm.Config
- dump *os.File
- writer *bufio.Writer
- err error
- )
- // If the transaction needs tracing, swap out the configs
- if tx.Hash() == txHash || txHash == (common.Hash{}) {
- // Generate a unique temporary file to dump it into
- prefix := fmt.Sprintf("block_%#x-%d-%#x-", block.Hash().Bytes()[:4], i, tx.Hash().Bytes()[:4])
- if !canon {
- prefix = fmt.Sprintf("%valt-", prefix)
- }
- dump, err = os.CreateTemp(os.TempDir(), prefix)
- if err != nil {
- return nil, err
- }
- dumps = append(dumps, dump.Name())
-
- // Swap out the noop logger to the standard tracer
- writer = bufio.NewWriter(dump)
- vmConf = vm.Config{
- Tracer: logger.NewJSONLogger(&logConfig, writer),
- EnablePreimageRecording: true,
- }
- }
- // Execute the transaction and flush any traces to disk
- vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf)
- statedb.SetTxContext(tx.Hash(), i)
- _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.GasLimit))
- if writer != nil {
- writer.Flush()
- }
- if dump != nil {
- dump.Close()
- log.Info("Wrote standard trace", "file", dump.Name())
- }
- if err != nil {
- return dumps, err
- }
- // Finalize the state so any modifications are written to the trie
- // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
- statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
-
- // If we've traced the transaction we were looking for, abort
- if tx.Hash() == txHash {
- break
- }
- }
- return dumps, nil
-}
-
-// containsTx reports whether the transaction with a certain hash
-// is contained within the specified block.
-func containsTx(block *types.Block, hash common.Hash) bool {
- for _, tx := range block.Transactions() {
- if tx.Hash() == hash {
- return true
- }
- }
- return false
-}
-
-// TraceTransaction returns the structured logs created during the execution of EVM
-// and returns them as a JSON object.
-func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
- tx, blockHash, blockNumber, index, err := api.backend.GetTransaction(ctx, hash)
- if err != nil {
- return nil, err
- }
- // Only mined txes are supported
- if tx == nil {
- return nil, errTxNotFound
- }
- // It shouldn't happen in practice.
- if blockNumber == 0 {
- return nil, errors.New("genesis is not traceable")
- }
- reexec := defaultTraceReexec
- if config != nil && config.Reexec != nil {
- reexec = *config.Reexec
- }
- block, err := api.blockByNumberAndHash(ctx, rpc.BlockNumber(blockNumber), blockHash)
- if err != nil {
- return nil, err
- }
- msg, vmctx, statedb, release, err := api.backend.StateAtTransaction(ctx, block, int(index), reexec)
- if err != nil {
- return nil, err
- }
- defer release()
-
- txctx := &Context{
- BlockHash: blockHash,
- BlockNumber: block.Number(),
- TxIndex: int(index),
- TxHash: hash,
- }
- return api.traceTx(ctx, msg, txctx, vmctx, statedb, config)
-}
-
-// TraceCall lets you trace a given eth_call. It collects the structured logs
-// created during the execution of EVM if the given transaction was added on
-// top of the provided block and returns them as a JSON object.
-// If no transaction index is specified, the trace will be conducted on the state
-// after executing the specified block. However, if a transaction index is provided,
-// the trace will be conducted on the state after executing the specified transaction
-// within the specified block.
-func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, config *TraceCallConfig) (interface{}, error) {
- // Try to retrieve the specified block
- var (
- err error
- block *types.Block
- statedb *state.StateDB
- release StateReleaseFunc
- )
- if hash, ok := blockNrOrHash.Hash(); ok {
- block, err = api.blockByHash(ctx, hash)
- } else if number, ok := blockNrOrHash.Number(); ok {
- if number == rpc.PendingBlockNumber {
- // We don't have access to the miner here. For tracing 'future' transactions,
- // it can be done with block- and state-overrides instead, which offers
- // more flexibility and stability than trying to trace on 'pending', since
- // the contents of 'pending' is unstable and probably not a true representation
- // of what the next actual block is likely to contain.
- return nil, errors.New("tracing on top of pending is not supported")
- }
- block, err = api.blockByNumber(ctx, number)
- } else {
- return nil, errors.New("invalid arguments; neither block nor hash specified")
- }
- if err != nil {
- return nil, err
- }
- // try to recompute the state
- reexec := defaultTraceReexec
- if config != nil && config.Reexec != nil {
- reexec = *config.Reexec
- }
-
- if config != nil && config.TxIndex != nil {
- _, _, statedb, release, err = api.backend.StateAtTransaction(ctx, block, int(*config.TxIndex), reexec)
- } else {
- statedb, release, err = api.backend.StateAtBlock(ctx, block, reexec, nil, true, false)
- }
- if err != nil {
- return nil, err
- }
- defer release()
-
- vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
- // Apply the customization rules if required.
- if config != nil {
- if err := config.StateOverrides.Apply(statedb); err != nil {
- return nil, err
- }
- config.BlockOverrides.Apply(&vmctx)
- }
- // Execute the trace
- msg, err := args.ToMessage(api.backend.RPCGasCap(), block.BaseFee())
- if err != nil {
- return nil, err
- }
-
- var traceConfig *TraceConfig
- if config != nil {
- traceConfig = &config.TraceConfig
- }
- return api.traceTx(ctx, msg, new(Context), vmctx, statedb, traceConfig)
-}
-
-// traceTx configures a new tracer according to the provided configuration, and
-// executes the given message in the provided environment. The return value will
-// be tracer dependent.
-func (api *API) traceTx(ctx context.Context, message *core.Message, txctx *Context, vmctx vm.BlockContext, statedb *state.StateDB, config *TraceConfig) (interface{}, error) {
- var (
- tracer Tracer
- err error
- timeout = defaultTraceTimeout
- txContext = core.NewEVMTxContext(message)
- )
- if config == nil {
- config = &TraceConfig{}
- }
- // Default tracer is the struct logger
- tracer = logger.NewStructLogger(config.Config)
- if config.Tracer != nil {
- tracer, err = DefaultDirectory.New(*config.Tracer, txctx, config.TracerConfig)
- if err != nil {
- return nil, err
- }
- }
- vmenv := vm.NewEVM(vmctx, txContext, statedb, api.backend.ChainConfig(), vm.Config{Tracer: tracer, NoBaseFee: true})
-
- // Define a meaningful timeout of a single transaction trace
- if config.Timeout != nil {
- if timeout, err = time.ParseDuration(*config.Timeout); err != nil {
- return nil, err
- }
- }
- deadlineCtx, cancel := context.WithTimeout(ctx, timeout)
- go func() {
- <-deadlineCtx.Done()
- if errors.Is(deadlineCtx.Err(), context.DeadlineExceeded) {
- tracer.Stop(errors.New("execution timeout"))
- // Stop evm execution. Note cancellation is not necessarily immediate.
- vmenv.Cancel()
- }
- }()
- defer cancel()
-
- // Call Prepare to clear out the statedb access list
- statedb.SetTxContext(txctx.TxHash, txctx.TxIndex)
- if _, err = core.ApplyMessage(vmenv, message, new(core.GasPool).AddGas(message.GasLimit)); err != nil {
- return nil, fmt.Errorf("tracing failed: %w", err)
- }
- return tracer.GetResult()
-}
-
-// APIs return the collection of RPC services the tracer package offers.
-func APIs(backend Backend) []rpc.API {
- // Append all the local APIs and return
- return []rpc.API{
- {
- Namespace: "debug",
- Service: NewAPI(backend),
- },
- }
-}
-
-// overrideConfig returns a copy of original with forks enabled by override enabled,
-// along with a boolean that indicates whether the copy is canonical (equivalent to the original).
-// Note: the Clique-part is _not_ deep copied
-func overrideConfig(original *params.ChainConfig, override *params.ChainConfig) (*params.ChainConfig, bool) {
- copy := new(params.ChainConfig)
- *copy = *original
- canon := true
-
- // Apply forks (after Berlin) to the copy.
- if block := override.BerlinBlock; block != nil {
- copy.BerlinBlock = block
- canon = false
- }
- if block := override.LondonBlock; block != nil {
- copy.LondonBlock = block
- canon = false
- }
- if block := override.ArrowGlacierBlock; block != nil {
- copy.ArrowGlacierBlock = block
- canon = false
- }
- if block := override.GrayGlacierBlock; block != nil {
- copy.GrayGlacierBlock = block
- canon = false
- }
- if block := override.MergeNetsplitBlock; block != nil {
- copy.MergeNetsplitBlock = block
- canon = false
- }
- if timestamp := override.ShanghaiTime; timestamp != nil {
- copy.ShanghaiTime = timestamp
- canon = false
- }
- if timestamp := override.CancunTime; timestamp != nil {
- copy.CancunTime = timestamp
- canon = false
- }
- if timestamp := override.PragueTime; timestamp != nil {
- copy.PragueTime = timestamp
- canon = false
- }
- if timestamp := override.VerkleTime; timestamp != nil {
- copy.VerkleTime = timestamp
- canon = false
- }
-
- return copy, canon
-}
diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go
deleted file mode 100644
index 49c3ebb67d..0000000000
--- a/eth/tracers/api_test.go
+++ /dev/null
@@ -1,997 +0,0 @@
-// Copyright 2021 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 tracers
-
-import (
- "context"
- "crypto/ecdsa"
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
- "reflect"
- "sync/atomic"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "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/state"
- "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/eth/tracers/logger"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
- "golang.org/x/exp/slices"
-)
-
-var (
- errStateNotFound = errors.New("state not found")
- errBlockNotFound = errors.New("block not found")
-)
-
-type testBackend struct {
- chainConfig *params.ChainConfig
- engine consensus.Engine
- chaindb ethdb.Database
- chain *core.BlockChain
-
- refHook func() // Hook is invoked when the requested state is referenced
- relHook func() // Hook is invoked when the requested state is released
-}
-
-// testBackend creates a new test backend. OBS: After test is done, teardown must be
-// invoked in order to release associated resources.
-func newTestBackend(t *testing.T, n int, gspec *core.Genesis, generator func(i int, b *core.BlockGen)) *testBackend {
- backend := &testBackend{
- chainConfig: gspec.Config,
- engine: ethash.NewFaker(),
- chaindb: rawdb.NewMemoryDatabase(),
- }
- // Generate blocks for testing
- _, blocks, _ := core.GenerateChainWithGenesis(gspec, backend.engine, n, generator)
-
- // Import the canonical chain
- cacheConfig := &core.CacheConfig{
- TrieCleanLimit: 256,
- TrieDirtyLimit: 256,
- TrieTimeLimit: 5 * time.Minute,
- SnapshotLimit: 0,
- TrieDirtyDisabled: true, // Archive mode
- }
- chain, err := core.NewBlockChain(backend.chaindb, cacheConfig, gspec, nil, backend.engine, vm.Config{}, nil, nil)
- if err != nil {
- t.Fatalf("failed to create tester chain: %v", err)
- }
- if n, err := chain.InsertChain(blocks); err != nil {
- t.Fatalf("block %d: failed to insert into chain: %v", n, err)
- }
- backend.chain = chain
- return backend
-}
-
-func (b *testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
- return b.chain.GetHeaderByHash(hash), nil
-}
-
-func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
- if number == rpc.PendingBlockNumber || number == rpc.LatestBlockNumber {
- return b.chain.CurrentHeader(), nil
- }
- return b.chain.GetHeaderByNumber(uint64(number)), nil
-}
-
-func (b *testBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
- return b.chain.GetBlockByHash(hash), nil
-}
-
-func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) {
- if number == rpc.PendingBlockNumber || number == rpc.LatestBlockNumber {
- return b.chain.GetBlockByNumber(b.chain.CurrentBlock().Number.Uint64()), nil
- }
- return b.chain.GetBlockByNumber(uint64(number)), nil
-}
-
-func (b *testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
- tx, hash, blockNumber, index := rawdb.ReadTransaction(b.chaindb, txHash)
- return tx, hash, blockNumber, index, nil
-}
-
-func (b *testBackend) RPCGasCap() uint64 {
- return 25000000
-}
-
-func (b *testBackend) ChainConfig() *params.ChainConfig {
- return b.chainConfig
-}
-
-func (b *testBackend) Engine() consensus.Engine {
- return b.engine
-}
-
-func (b *testBackend) ChainDb() ethdb.Database {
- return b.chaindb
-}
-
-// teardown releases the associated resources.
-func (b *testBackend) teardown() {
- b.chain.Stop()
-}
-
-func (b *testBackend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (*state.StateDB, StateReleaseFunc, error) {
- statedb, err := b.chain.StateAt(block.Root())
- if err != nil {
- return nil, nil, errStateNotFound
- }
- if b.refHook != nil {
- b.refHook()
- }
- release := func() {
- if b.relHook != nil {
- b.relHook()
- }
- }
- return statedb, release, nil
-}
-
-func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, StateReleaseFunc, error) {
- parent := b.chain.GetBlock(block.ParentHash(), block.NumberU64()-1)
- if parent == nil {
- return nil, vm.BlockContext{}, nil, nil, errBlockNotFound
- }
- statedb, release, err := b.StateAtBlock(ctx, parent, reexec, nil, true, false)
- if err != nil {
- return nil, vm.BlockContext{}, nil, nil, errStateNotFound
- }
- if txIndex == 0 && len(block.Transactions()) == 0 {
- return nil, vm.BlockContext{}, statedb, release, nil
- }
- // Recompute transactions up to the target index.
- signer := types.MakeSigner(b.chainConfig, block.Number(), block.Time())
- for idx, tx := range block.Transactions() {
- msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
- txContext := core.NewEVMTxContext(msg)
- context := core.NewEVMBlockContext(block.Header(), b.chain, nil)
- if idx == txIndex {
- return msg, context, statedb, release, nil
- }
- vmenv := vm.NewEVM(context, txContext, statedb, b.chainConfig, vm.Config{})
- if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
- return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
- }
- statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
- }
- return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %#x", txIndex, block.Hash())
-}
-
-func TestTraceCall(t *testing.T) {
- t.Parallel()
-
- // Initialize test accounts
- accounts := newAccounts(3)
- genesis := &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{
- accounts[0].addr: {Balance: big.NewInt(params.Ether)},
- accounts[1].addr: {Balance: big.NewInt(params.Ether)},
- accounts[2].addr: {Balance: big.NewInt(params.Ether)},
- },
- }
- genBlocks := 10
- signer := types.HomesteadSigner{}
- nonce := uint64(0)
- backend := newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
- // Transfer from account[0] to account[1]
- // value: 1000 wei
- // fee: 0 wei
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: nonce,
- To: &accounts[1].addr,
- Value: big.NewInt(1000),
- Gas: params.TxGas,
- GasPrice: b.BaseFee(),
- Data: nil}),
- signer, accounts[0].key)
- b.AddTx(tx)
- nonce++
-
- if i == genBlocks-2 {
- // Transfer from account[0] to account[2]
- tx, _ = types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: nonce,
- To: &accounts[2].addr,
- Value: big.NewInt(1000),
- Gas: params.TxGas,
- GasPrice: b.BaseFee(),
- Data: nil}),
- signer, accounts[0].key)
- b.AddTx(tx)
- nonce++
-
- // Transfer from account[0] to account[1] again
- tx, _ = types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: nonce,
- To: &accounts[1].addr,
- Value: big.NewInt(1000),
- Gas: params.TxGas,
- GasPrice: b.BaseFee(),
- Data: nil}),
- signer, accounts[0].key)
- b.AddTx(tx)
- nonce++
- }
- })
-
- uintPtr := func(i int) *hexutil.Uint { x := hexutil.Uint(i); return &x }
-
- defer backend.teardown()
- api := NewAPI(backend)
- var testSuite = []struct {
- blockNumber rpc.BlockNumber
- call ethapi.TransactionArgs
- config *TraceCallConfig
- expectErr error
- expect string
- }{
- // Standard JSON trace upon the genesis, plain transfer.
- {
- blockNumber: rpc.BlockNumber(0),
- call: ethapi.TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- config: nil,
- expectErr: nil,
- expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
- },
- // Standard JSON trace upon the head, plain transfer.
- {
- blockNumber: rpc.BlockNumber(genBlocks),
- call: ethapi.TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- config: nil,
- expectErr: nil,
- expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
- },
- // Upon the last state, default to the post block's state
- {
- blockNumber: rpc.BlockNumber(genBlocks - 1),
- call: ethapi.TransactionArgs{
- From: &accounts[2].addr,
- To: &accounts[0].addr,
- Value: (*hexutil.Big)(new(big.Int).Add(big.NewInt(params.Ether), big.NewInt(100))),
- },
- config: nil,
- expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
- },
- // Before the first transaction, should be failed
- {
- blockNumber: rpc.BlockNumber(genBlocks - 1),
- call: ethapi.TransactionArgs{
- From: &accounts[2].addr,
- To: &accounts[0].addr,
- Value: (*hexutil.Big)(new(big.Int).Add(big.NewInt(params.Ether), big.NewInt(100))),
- },
- config: &TraceCallConfig{TxIndex: uintPtr(0)},
- expectErr: fmt.Errorf("tracing failed: insufficient funds for gas * price + value: address %s have 1000000000000000000 want 1000000000000000100", accounts[2].addr),
- },
- // Before the target transaction, should be failed
- {
- blockNumber: rpc.BlockNumber(genBlocks - 1),
- call: ethapi.TransactionArgs{
- From: &accounts[2].addr,
- To: &accounts[0].addr,
- Value: (*hexutil.Big)(new(big.Int).Add(big.NewInt(params.Ether), big.NewInt(100))),
- },
- config: &TraceCallConfig{TxIndex: uintPtr(1)},
- expectErr: fmt.Errorf("tracing failed: insufficient funds for gas * price + value: address %s have 1000000000000000000 want 1000000000000000100", accounts[2].addr),
- },
- // After the target transaction, should be succeed
- {
- blockNumber: rpc.BlockNumber(genBlocks - 1),
- call: ethapi.TransactionArgs{
- From: &accounts[2].addr,
- To: &accounts[0].addr,
- Value: (*hexutil.Big)(new(big.Int).Add(big.NewInt(params.Ether), big.NewInt(100))),
- },
- config: &TraceCallConfig{TxIndex: uintPtr(2)},
- expectErr: nil,
- expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
- },
- // Standard JSON trace upon the non-existent block, error expects
- {
- blockNumber: rpc.BlockNumber(genBlocks + 1),
- call: ethapi.TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- config: nil,
- expectErr: fmt.Errorf("block #%d not found", genBlocks+1),
- //expect: nil,
- },
- // Standard JSON trace upon the latest block
- {
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- config: nil,
- expectErr: nil,
- expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
- },
- // Tracing on 'pending' should fail:
- {
- blockNumber: rpc.PendingBlockNumber,
- call: ethapi.TransactionArgs{
- From: &accounts[0].addr,
- To: &accounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- config: nil,
- expectErr: errors.New("tracing on top of pending is not supported"),
- },
- {
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &accounts[0].addr,
- Input: &hexutil.Bytes{0x43}, // blocknumber
- },
- config: &TraceCallConfig{
- BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
- },
- expectErr: nil,
- expect: ` {"gas":53018,"failed":false,"returnValue":"","structLogs":[
- {"pc":0,"op":"NUMBER","gas":24946984,"gasCost":2,"depth":1,"stack":[]},
- {"pc":1,"op":"STOP","gas":24946982,"gasCost":0,"depth":1,"stack":["0x1337"]}]}`,
- },
- }
- for i, testspec := range testSuite {
- result, err := api.TraceCall(context.Background(), testspec.call, rpc.BlockNumberOrHash{BlockNumber: &testspec.blockNumber}, testspec.config)
- if testspec.expectErr != nil {
- if err == nil {
- t.Errorf("test %d: expect error %v, got nothing", i, testspec.expectErr)
- continue
- }
- if !reflect.DeepEqual(err.Error(), testspec.expectErr.Error()) {
- t.Errorf("test %d: error mismatch, want '%v', got '%v'", i, testspec.expectErr, err)
- }
- } else {
- if err != nil {
- t.Errorf("test %d: expect no error, got %v", i, err)
- continue
- }
- var have *logger.ExecutionResult
- if err := json.Unmarshal(result.(json.RawMessage), &have); err != nil {
- t.Errorf("test %d: failed to unmarshal result %v", i, err)
- }
- var want *logger.ExecutionResult
- if err := json.Unmarshal([]byte(testspec.expect), &want); err != nil {
- t.Errorf("test %d: failed to unmarshal result %v", i, err)
- }
- if !reflect.DeepEqual(have, want) {
- t.Errorf("test %d: result mismatch, want %v, got %v", i, testspec.expect, string(result.(json.RawMessage)))
- }
- }
- }
-}
-
-func TestTraceTransaction(t *testing.T) {
- t.Parallel()
-
- // Initialize test accounts
- accounts := newAccounts(2)
- genesis := &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{
- accounts[0].addr: {Balance: big.NewInt(params.Ether)},
- accounts[1].addr: {Balance: big.NewInt(params.Ether)},
- },
- }
- target := common.Hash{}
- signer := types.HomesteadSigner{}
- backend := newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) {
- // Transfer from account[0] to account[1]
- // value: 1000 wei
- // fee: 0 wei
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: uint64(i),
- To: &accounts[1].addr,
- Value: big.NewInt(1000),
- Gas: params.TxGas,
- GasPrice: b.BaseFee(),
- Data: nil}),
- signer, accounts[0].key)
- b.AddTx(tx)
- target = tx.Hash()
- })
- defer backend.chain.Stop()
- api := NewAPI(backend)
- result, err := api.TraceTransaction(context.Background(), target, nil)
- if err != nil {
- t.Errorf("Failed to trace transaction %v", err)
- }
- var have *logger.ExecutionResult
- if err := json.Unmarshal(result.(json.RawMessage), &have); err != nil {
- t.Errorf("failed to unmarshal result %v", err)
- }
- if !reflect.DeepEqual(have, &logger.ExecutionResult{
- Gas: params.TxGas,
- Failed: false,
- ReturnValue: "",
- StructLogs: []logger.StructLogRes{},
- }) {
- t.Error("Transaction tracing result is different")
- }
-
- // Test non-existent transaction
- _, err = api.TraceTransaction(context.Background(), common.Hash{42}, nil)
- if !errors.Is(err, errTxNotFound) {
- t.Fatalf("want %v, have %v", errTxNotFound, err)
- }
-}
-
-func TestTraceBlock(t *testing.T) {
- t.Parallel()
-
- // Initialize test accounts
- accounts := newAccounts(3)
- genesis := &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{
- accounts[0].addr: {Balance: big.NewInt(params.Ether)},
- accounts[1].addr: {Balance: big.NewInt(params.Ether)},
- accounts[2].addr: {Balance: big.NewInt(params.Ether)},
- },
- }
- genBlocks := 10
- signer := types.HomesteadSigner{}
- var txHash common.Hash
- backend := newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
- // Transfer from account[0] to account[1]
- // value: 1000 wei
- // fee: 0 wei
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: uint64(i),
- To: &accounts[1].addr,
- Value: big.NewInt(1000),
- Gas: params.TxGas,
- GasPrice: b.BaseFee(),
- Data: nil}),
- signer, accounts[0].key)
- b.AddTx(tx)
- txHash = tx.Hash()
- })
- defer backend.chain.Stop()
- api := NewAPI(backend)
-
- var testSuite = []struct {
- blockNumber rpc.BlockNumber
- config *TraceConfig
- want string
- expectErr error
- }{
- // Trace genesis block, expect error
- {
- blockNumber: rpc.BlockNumber(0),
- expectErr: errors.New("genesis is not traceable"),
- },
- // Trace head block
- {
- blockNumber: rpc.BlockNumber(genBlocks),
- want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash),
- },
- // Trace non-existent block
- {
- blockNumber: rpc.BlockNumber(genBlocks + 1),
- expectErr: fmt.Errorf("block #%d not found", genBlocks+1),
- },
- // Trace latest block
- {
- blockNumber: rpc.LatestBlockNumber,
- want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash),
- },
- // Trace pending block
- {
- blockNumber: rpc.PendingBlockNumber,
- want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash),
- },
- }
- for i, tc := range testSuite {
- result, err := api.TraceBlockByNumber(context.Background(), tc.blockNumber, tc.config)
- if tc.expectErr != nil {
- if err == nil {
- t.Errorf("test %d, want error %v", i, tc.expectErr)
- continue
- }
- if !reflect.DeepEqual(err, tc.expectErr) {
- t.Errorf("test %d: error mismatch, want %v, get %v", i, tc.expectErr, err)
- }
- continue
- }
- if err != nil {
- t.Errorf("test %d, want no error, have %v", i, err)
- continue
- }
- have, _ := json.Marshal(result)
- want := tc.want
- if string(have) != want {
- t.Errorf("test %d, result mismatch, have\n%v\n, want\n%v\n", i, string(have), want)
- }
- }
-}
-
-func TestTracingWithOverrides(t *testing.T) {
- t.Parallel()
- // Initialize test accounts
- accounts := newAccounts(3)
- storageAccount := common.Address{0x13, 37}
- genesis := &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{
- accounts[0].addr: {Balance: big.NewInt(params.Ether)},
- accounts[1].addr: {Balance: big.NewInt(params.Ether)},
- accounts[2].addr: {Balance: big.NewInt(params.Ether)},
- // An account with existing storage
- storageAccount: {
- Balance: new(big.Int),
- Storage: map[common.Hash]common.Hash{
- common.HexToHash("0x03"): common.HexToHash("0x33"),
- common.HexToHash("0x04"): common.HexToHash("0x44"),
- },
- },
- },
- }
- genBlocks := 10
- signer := types.HomesteadSigner{}
- backend := newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
- // Transfer from account[0] to account[1]
- // value: 1000 wei
- // fee: 0 wei
- tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
- Nonce: uint64(i),
- To: &accounts[1].addr,
- Value: big.NewInt(1000),
- Gas: params.TxGas,
- GasPrice: b.BaseFee(),
- Data: nil}),
- signer, accounts[0].key)
- b.AddTx(tx)
- })
- defer backend.chain.Stop()
- api := NewAPI(backend)
- randomAccounts := newAccounts(3)
- type res struct {
- Gas int
- Failed bool
- ReturnValue string
- }
- var testSuite = []struct {
- blockNumber rpc.BlockNumber
- call ethapi.TransactionArgs
- config *TraceCallConfig
- expectErr error
- want string
- }{
- // Call which can only succeed if state is state overridden
- {
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- config: &TraceCallConfig{
- StateOverrides: ðapi.StateOverride{
- randomAccounts[0].addr: ethapi.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
- },
- },
- want: `{"gas":21000,"failed":false,"returnValue":""}`,
- },
- // Invalid call without state overriding
- {
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[1].addr,
- Value: (*hexutil.Big)(big.NewInt(1000)),
- },
- config: &TraceCallConfig{},
- expectErr: core.ErrInsufficientFunds,
- },
- // Successful simple contract call
- //
- // // SPDX-License-Identifier: GPL-3.0
- //
- // pragma solidity >=0.7.0 <0.8.0;
- //
- // /**
- // * @title Storage
- // * @dev Store & retrieve value in a variable
- // */
- // contract Storage {
- // uint256 public number;
- // constructor() {
- // number = block.number;
- // }
- // }
- {
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[2].addr,
- Data: newRPCBytes(common.Hex2Bytes("8381f58a")), // call number()
- },
- config: &TraceCallConfig{
- //Tracer: &tracer,
- StateOverrides: ðapi.StateOverride{
- randomAccounts[2].addr: ethapi.OverrideAccount{
- Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060285760003560e01c80638381f58a14602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000548156fea2646970667358221220eab35ffa6ab2adfe380772a48b8ba78e82a1b820a18fcb6f59aa4efb20a5f60064736f6c63430007040033")),
- StateDiff: newStates([]common.Hash{{}}, []common.Hash{common.BigToHash(big.NewInt(123))}),
- },
- },
- },
- want: `{"gas":23347,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000007b"}`,
- },
- { // Override blocknumber
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &accounts[0].addr,
- // BLOCKNUMBER PUSH1 MSTORE
- Input: newRPCBytes(common.Hex2Bytes("4360005260206000f3")),
- //&hexutil.Bytes{0x43}, // blocknumber
- },
- config: &TraceCallConfig{
- BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
- },
- want: `{"gas":59537,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000001337"}`,
- },
- { // Override blocknumber, and query a blockhash
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &accounts[0].addr,
- Input: &hexutil.Bytes{
- 0x60, 0x00, 0x40, // BLOCKHASH(0)
- 0x60, 0x00, 0x52, // STORE memory offset 0
- 0x61, 0x13, 0x36, 0x40, // BLOCKHASH(0x1336)
- 0x60, 0x20, 0x52, // STORE memory offset 32
- 0x61, 0x13, 0x37, 0x40, // BLOCKHASH(0x1337)
- 0x60, 0x40, 0x52, // STORE memory offset 64
- 0x60, 0x60, 0x60, 0x00, 0xf3, // RETURN (0-96)
-
- }, // blocknumber
- },
- config: &TraceCallConfig{
- BlockOverrides: ðapi.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
- },
- want: `{"gas":72666,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}`,
- },
- /*
- pragma solidity =0.8.12;
-
- contract Test {
- uint private x;
-
- function test2() external {
- x = 1337;
- revert();
- }
-
- function test() external returns (uint) {
- x = 1;
- try this.test2() {} catch (bytes memory) {}
- return x;
- }
- }
- */
- { // First with only code override, not storage override
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[2].addr,
- Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
- },
- config: &TraceCallConfig{
- StateOverrides: ðapi.StateOverride{
- randomAccounts[2].addr: ethapi.OverrideAccount{
- Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060325760003560e01c806366e41cb7146037578063f8a8fd6d14603f575b600080fd5b603d6057565b005b60456062565b60405190815260200160405180910390f35b610539600090815580fd5b60006001600081905550306001600160a01b03166366e41cb76040518163ffffffff1660e01b8152600401600060405180830381600087803b15801560a657600080fd5b505af192505050801560b6575060015b60e9573d80801560e1576040519150601f19603f3d011682016040523d82523d6000602084013e60e6565b606091505b50505b506000549056fea26469706673582212205ce45de745a5308f713cb2f448589177ba5a442d1a2eff945afaa8915961b4d064736f6c634300080c0033")),
- },
- },
- },
- want: `{"gas":44100,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001"}`,
- },
- { // Same again, this time with storage override
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &randomAccounts[2].addr,
- Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
- },
- config: &TraceCallConfig{
- StateOverrides: ðapi.StateOverride{
- randomAccounts[2].addr: ethapi.OverrideAccount{
- Code: newRPCBytes(common.Hex2Bytes("6080604052348015600f57600080fd5b506004361060325760003560e01c806366e41cb7146037578063f8a8fd6d14603f575b600080fd5b603d6057565b005b60456062565b60405190815260200160405180910390f35b610539600090815580fd5b60006001600081905550306001600160a01b03166366e41cb76040518163ffffffff1660e01b8152600401600060405180830381600087803b15801560a657600080fd5b505af192505050801560b6575060015b60e9573d80801560e1576040519150601f19603f3d011682016040523d82523d6000602084013e60e6565b606091505b50505b506000549056fea26469706673582212205ce45de745a5308f713cb2f448589177ba5a442d1a2eff945afaa8915961b4d064736f6c634300080c0033")),
- State: newStates([]common.Hash{{}}, []common.Hash{{}}),
- },
- },
- },
- //want: `{"gas":46900,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000539"}`,
- want: `{"gas":44100,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001"}`,
- },
- { // No state override
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &storageAccount,
- Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
- },
- config: &TraceCallConfig{
- StateOverrides: ðapi.StateOverride{
- storageAccount: ethapi.OverrideAccount{
- Code: newRPCBytes([]byte{
- // SLOAD(3) + SLOAD(4) (which is 0x77)
- byte(vm.PUSH1), 0x04,
- byte(vm.SLOAD),
- byte(vm.PUSH1), 0x03,
- byte(vm.SLOAD),
- byte(vm.ADD),
- // 0x77 -> MSTORE(0)
- byte(vm.PUSH1), 0x00,
- byte(vm.MSTORE),
- // RETURN (0, 32)
- byte(vm.PUSH1), 32,
- byte(vm.PUSH1), 00,
- byte(vm.RETURN),
- }),
- },
- },
- },
- want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000077"}`,
- },
- { // Full state override
- // The original storage is
- // 3: 0x33
- // 4: 0x44
- // With a full override, where we set 3:0x11, the slot 4 should be
- // removed. So SLOT(3)+SLOT(4) should be 0x11.
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &storageAccount,
- Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
- },
- config: &TraceCallConfig{
- StateOverrides: ðapi.StateOverride{
- storageAccount: ethapi.OverrideAccount{
- Code: newRPCBytes([]byte{
- // SLOAD(3) + SLOAD(4) (which is now 0x11 + 0x00)
- byte(vm.PUSH1), 0x04,
- byte(vm.SLOAD),
- byte(vm.PUSH1), 0x03,
- byte(vm.SLOAD),
- byte(vm.ADD),
- // 0x11 -> MSTORE(0)
- byte(vm.PUSH1), 0x00,
- byte(vm.MSTORE),
- // RETURN (0, 32)
- byte(vm.PUSH1), 32,
- byte(vm.PUSH1), 00,
- byte(vm.RETURN),
- }),
- State: newStates(
- []common.Hash{common.HexToHash("0x03")},
- []common.Hash{common.HexToHash("0x11")}),
- },
- },
- },
- want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000011"}`,
- },
- { // Partial state override
- // The original storage is
- // 3: 0x33
- // 4: 0x44
- // With a partial override, where we set 3:0x11, the slot 4 as before.
- // So SLOT(3)+SLOT(4) should be 0x55.
- blockNumber: rpc.LatestBlockNumber,
- call: ethapi.TransactionArgs{
- From: &randomAccounts[0].addr,
- To: &storageAccount,
- Data: newRPCBytes(common.Hex2Bytes("f8a8fd6d")), //
- },
- config: &TraceCallConfig{
- StateOverrides: ðapi.StateOverride{
- storageAccount: ethapi.OverrideAccount{
- Code: newRPCBytes([]byte{
- // SLOAD(3) + SLOAD(4) (which is now 0x11 + 0x44)
- byte(vm.PUSH1), 0x04,
- byte(vm.SLOAD),
- byte(vm.PUSH1), 0x03,
- byte(vm.SLOAD),
- byte(vm.ADD),
- // 0x55 -> MSTORE(0)
- byte(vm.PUSH1), 0x00,
- byte(vm.MSTORE),
- // RETURN (0, 32)
- byte(vm.PUSH1), 32,
- byte(vm.PUSH1), 00,
- byte(vm.RETURN),
- }),
- StateDiff: &map[common.Hash]common.Hash{
- common.HexToHash("0x03"): common.HexToHash("0x11"),
- },
- },
- },
- },
- want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000055"}`,
- },
- }
- for i, tc := range testSuite {
- result, err := api.TraceCall(context.Background(), tc.call, rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, tc.config)
- if tc.expectErr != nil {
- if err == nil {
- t.Errorf("test %d: want error %v, have nothing", i, tc.expectErr)
- continue
- }
- if !errors.Is(err, tc.expectErr) {
- t.Errorf("test %d: error mismatch, want %v, have %v", i, tc.expectErr, err)
- }
- continue
- }
- if err != nil {
- t.Errorf("test %d: want no error, have %v", i, err)
- continue
- }
- // Turn result into res-struct
- var (
- have res
- want res
- )
- resBytes, _ := json.Marshal(result)
- json.Unmarshal(resBytes, &have)
- json.Unmarshal([]byte(tc.want), &want)
- if !reflect.DeepEqual(have, want) {
- t.Logf("result: %v\n", string(resBytes))
- t.Errorf("test %d, result mismatch, have\n%v\n, want\n%v\n", i, have, want)
- }
- }
-}
-
-type Account struct {
- key *ecdsa.PrivateKey
- addr common.Address
-}
-
-func newAccounts(n int) (accounts []Account) {
- for i := 0; i < n; i++ {
- key, _ := crypto.GenerateKey()
- addr := crypto.PubkeyToAddress(key.PublicKey)
- accounts = append(accounts, Account{key: key, addr: addr})
- }
- slices.SortFunc(accounts, func(a, b Account) int { return a.addr.Cmp(b.addr) })
- return accounts
-}
-
-func newRPCBalance(balance *big.Int) **hexutil.Big {
- rpcBalance := (*hexutil.Big)(balance)
- return &rpcBalance
-}
-
-func newRPCBytes(bytes []byte) *hexutil.Bytes {
- rpcBytes := hexutil.Bytes(bytes)
- return &rpcBytes
-}
-
-func newStates(keys []common.Hash, vals []common.Hash) *map[common.Hash]common.Hash {
- if len(keys) != len(vals) {
- panic("invalid input")
- }
- m := make(map[common.Hash]common.Hash)
- for i := 0; i < len(keys); i++ {
- m[keys[i]] = vals[i]
- }
- return &m
-}
-
-func TestTraceChain(t *testing.T) {
- // Initialize test accounts
- accounts := newAccounts(3)
- genesis := &core.Genesis{
- Config: params.TestChainConfig,
- Alloc: core.GenesisAlloc{
- accounts[0].addr: {Balance: big.NewInt(params.Ether)},
- accounts[1].addr: {Balance: big.NewInt(params.Ether)},
- accounts[2].addr: {Balance: big.NewInt(params.Ether)},
- },
- }
- genBlocks := 50
- signer := types.HomesteadSigner{}
-
- var (
- ref atomic.Uint32 // total refs has made
- rel atomic.Uint32 // total rels has made
- nonce uint64
- )
- backend := newTestBackend(t, genBlocks, genesis, func(i int, b *core.BlockGen) {
- // Transfer from account[0] to account[1]
- // value: 1000 wei
- // fee: 0 wei
- for j := 0; j < i+1; j++ {
- tx, _ := types.SignTx(types.NewTransaction(nonce, accounts[1].addr, big.NewInt(1000), params.TxGas, b.BaseFee(), nil), signer, accounts[0].key)
- b.AddTx(tx)
- nonce += 1
- }
- })
- backend.refHook = func() { ref.Add(1) }
- backend.relHook = func() { rel.Add(1) }
- api := NewAPI(backend)
-
- single := `{"txHash":"0x0000000000000000000000000000000000000000000000000000000000000000","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}`
- var cases = []struct {
- start uint64
- end uint64
- config *TraceConfig
- }{
- {0, 50, nil}, // the entire chain range, blocks [1, 50]
- {10, 20, nil}, // the middle chain range, blocks [11, 20]
- }
- for _, c := range cases {
- ref.Store(0)
- rel.Store(0)
-
- from, _ := api.blockByNumber(context.Background(), rpc.BlockNumber(c.start))
- to, _ := api.blockByNumber(context.Background(), rpc.BlockNumber(c.end))
- resCh := api.traceChain(from, to, c.config, nil)
-
- next := c.start + 1
- for result := range resCh {
- if have, want := uint64(result.Block), next; have != want {
- t.Fatalf("unexpected tracing block, have %d want %d", have, want)
- }
- if have, want := len(result.Traces), int(next); have != want {
- t.Fatalf("unexpected result length, have %d want %d", have, want)
- }
- for _, trace := range result.Traces {
- trace.TxHash = common.Hash{}
- blob, _ := json.Marshal(trace)
- if have, want := string(blob), single; have != want {
- t.Fatalf("unexpected tracing result, have\n%v\nwant:\n%v", have, want)
- }
- }
- next += 1
- }
- if next != c.end+1 {
- t.Error("Missing tracing block")
- }
-
- if nref, nrel := ref.Load(), rel.Load(); nref != nrel {
- t.Errorf("Ref and deref actions are not equal, ref %d rel %d", nref, nrel)
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go
deleted file mode 100644
index 5c74baacd1..0000000000
--- a/eth/tracers/internal/tracetest/calltrace_test.go
+++ /dev/null
@@ -1,406 +0,0 @@
-// Copyright 2021 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 tracetest
-
-import (
- "encoding/json"
- "math/big"
- "os"
- "path/filepath"
- "strings"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "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/eth/tracers"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/tests"
-)
-
-type callContext struct {
- Number math.HexOrDecimal64 `json:"number"`
- Difficulty *math.HexOrDecimal256 `json:"difficulty"`
- Time math.HexOrDecimal64 `json:"timestamp"`
- GasLimit math.HexOrDecimal64 `json:"gasLimit"`
- Miner common.Address `json:"miner"`
-}
-
-// callLog is the result of LOG opCode
-type callLog struct {
- Address common.Address `json:"address"`
- Topics []common.Hash `json:"topics"`
- Data hexutil.Bytes `json:"data"`
- Position hexutil.Uint `json:"position"`
-}
-
-// callTrace is the result of a callTracer run.
-type callTrace struct {
- From common.Address `json:"from"`
- Gas *hexutil.Uint64 `json:"gas"`
- GasUsed *hexutil.Uint64 `json:"gasUsed"`
- To *common.Address `json:"to,omitempty"`
- Input hexutil.Bytes `json:"input"`
- Output hexutil.Bytes `json:"output,omitempty"`
- Error string `json:"error,omitempty"`
- RevertReason string `json:"revertReason,omitempty"`
- Calls []callTrace `json:"calls,omitempty"`
- Logs []callLog `json:"logs,omitempty"`
- Value *hexutil.Big `json:"value,omitempty"`
- // Gencodec adds overridden fields at the end
- Type string `json:"type"`
-}
-
-// callTracerTest defines a single test to check the call tracer against.
-type callTracerTest struct {
- Genesis *core.Genesis `json:"genesis"`
- Context *callContext `json:"context"`
- Input string `json:"input"`
- TracerConfig json.RawMessage `json:"tracerConfig"`
- Result *callTrace `json:"result"`
-}
-
-// Iterates over all the input-output datasets in the tracer test harness and
-// runs the JavaScript tracers against them.
-func TestCallTracerLegacy(t *testing.T) {
- testCallTracer("callTracerLegacy", "call_tracer_legacy", t)
-}
-
-func TestCallTracerNative(t *testing.T) {
- testCallTracer("callTracer", "call_tracer", t)
-}
-
-func TestCallTracerNativeWithLog(t *testing.T) {
- testCallTracer("callTracer", "call_tracer_withLog", t)
-}
-
-func testCallTracer(tracerName string, dirPath string, t *testing.T) {
- isLegacy := strings.HasSuffix(dirPath, "_legacy")
- files, err := os.ReadDir(filepath.Join("testdata", dirPath))
- if err != nil {
- t.Fatalf("failed to retrieve tracer test suite: %v", err)
- }
- for _, file := range files {
- if !strings.HasSuffix(file.Name(), ".json") {
- continue
- }
- file := file // capture range variable
- t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) {
- t.Parallel()
-
- var (
- test = new(callTracerTest)
- tx = new(types.Transaction)
- )
- // Call tracer test found, read if from disk
- if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil {
- t.Fatalf("failed to read testcase: %v", err)
- } else if err := json.Unmarshal(blob, test); err != nil {
- t.Fatalf("failed to parse testcase: %v", err)
- }
- if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil {
- t.Fatalf("failed to parse testcase input: %v", err)
- }
- // Configure a blockchain with the given prestate
- var (
- signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
- origin, _ = signer.Sender(tx)
- txContext = vm.TxContext{
- Origin: origin,
- GasPrice: tx.GasPrice(),
- }
- context = vm.BlockContext{
- CanTransfer: core.CanTransfer,
- Transfer: core.Transfer,
- Coinbase: test.Context.Miner,
- BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
- Time: uint64(test.Context.Time),
- Difficulty: (*big.Int)(test.Context.Difficulty),
- GasLimit: uint64(test.Context.GasLimit),
- BaseFee: test.Genesis.BaseFee,
- }
- triedb, _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
- )
- triedb.Close()
-
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
- if err != nil {
- t.Fatalf("failed to create call tracer: %v", err)
- }
- evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer})
- msg, err := core.TransactionToMessage(tx, signer, nil)
- if err != nil {
- t.Fatalf("failed to prepare transaction for tracing: %v", err)
- }
- vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
- if err != nil {
- t.Fatalf("failed to execute transaction: %v", err)
- }
- // Retrieve the trace result and compare against the expected.
- res, err := tracer.GetResult()
- if err != nil {
- t.Fatalf("failed to retrieve trace result: %v", err)
- }
- // The legacy javascript calltracer marshals json in js, which
- // is not deterministic (as opposed to the golang json encoder).
- if isLegacy {
- // This is a tweak to make it deterministic. Can be removed when
- // we remove the legacy tracer.
- var x callTrace
- json.Unmarshal(res, &x)
- res, _ = json.Marshal(x)
- }
- want, err := json.Marshal(test.Result)
- if err != nil {
- t.Fatalf("failed to marshal test: %v", err)
- }
- if string(want) != string(res) {
- t.Fatalf("trace mismatch\n have: %v\n want: %v\n", string(res), string(want))
- }
- // Sanity check: compare top call's gas used against vm result
- type simpleResult struct {
- GasUsed hexutil.Uint64
- }
- var topCall simpleResult
- if err := json.Unmarshal(res, &topCall); err != nil {
- t.Fatalf("failed to unmarshal top calls gasUsed: %v", err)
- }
- if uint64(topCall.GasUsed) != vmRet.UsedGas {
- t.Fatalf("top call has invalid gasUsed. have: %d want: %d", topCall.GasUsed, vmRet.UsedGas)
- }
- })
- }
-}
-
-func BenchmarkTracers(b *testing.B) {
- files, err := os.ReadDir(filepath.Join("testdata", "call_tracer"))
- if err != nil {
- b.Fatalf("failed to retrieve tracer test suite: %v", err)
- }
- for _, file := range files {
- if !strings.HasSuffix(file.Name(), ".json") {
- continue
- }
- file := file // capture range variable
- b.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(b *testing.B) {
- blob, err := os.ReadFile(filepath.Join("testdata", "call_tracer", file.Name()))
- if err != nil {
- b.Fatalf("failed to read testcase: %v", err)
- }
- test := new(callTracerTest)
- if err := json.Unmarshal(blob, test); err != nil {
- b.Fatalf("failed to parse testcase: %v", err)
- }
- benchTracer("callTracer", test, b)
- })
- }
-}
-
-func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
- // Configure a blockchain with the given prestate
- tx := new(types.Transaction)
- if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil {
- b.Fatalf("failed to parse testcase input: %v", err)
- }
- signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
- msg, err := core.TransactionToMessage(tx, signer, nil)
- if err != nil {
- b.Fatalf("failed to prepare transaction for tracing: %v", err)
- }
- origin, _ := signer.Sender(tx)
- txContext := vm.TxContext{
- Origin: origin,
- GasPrice: tx.GasPrice(),
- }
- context := vm.BlockContext{
- CanTransfer: core.CanTransfer,
- Transfer: core.Transfer,
- Coinbase: test.Context.Miner,
- BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
- Time: uint64(test.Context.Time),
- Difficulty: (*big.Int)(test.Context.Difficulty),
- GasLimit: uint64(test.Context.GasLimit),
- }
- triedb, _, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
- defer triedb.Close()
-
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil)
- if err != nil {
- b.Fatalf("failed to create call tracer: %v", err)
- }
- evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer})
- snap := statedb.Snapshot()
- st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
- if _, err = st.TransitionDb(); err != nil {
- b.Fatalf("failed to execute transaction: %v", err)
- }
- if _, err = tracer.GetResult(); err != nil {
- b.Fatal(err)
- }
- statedb.RevertToSnapshot(snap)
- }
-}
-
-func TestInternals(t *testing.T) {
- var (
- to = common.HexToAddress("0x00000000000000000000000000000000deadbeef")
- origin = common.HexToAddress("0x00000000000000000000000000000000feed")
- txContext = vm.TxContext{
- Origin: origin,
- GasPrice: big.NewInt(1),
- }
- context = vm.BlockContext{
- CanTransfer: core.CanTransfer,
- Transfer: core.Transfer,
- Coinbase: common.Address{},
- BlockNumber: new(big.Int).SetUint64(8000000),
- Time: 5,
- Difficulty: big.NewInt(0x30000),
- GasLimit: uint64(6000000),
- }
- )
- mkTracer := func(name string, cfg json.RawMessage) tracers.Tracer {
- tr, err := tracers.DefaultDirectory.New(name, nil, cfg)
- if err != nil {
- t.Fatalf("failed to create call tracer: %v", err)
- }
- return tr
- }
-
- for _, tc := range []struct {
- name string
- code []byte
- tracer tracers.Tracer
- want string
- }{
- {
- // TestZeroValueToNotExitCall tests the calltracer(s) on the following:
- // Tx to A, A calls B with zero value. B does not already exist.
- // Expected: that enter/exit is invoked and the inner call is shown in the result
- name: "ZeroValueToNotExitCall",
- code: []byte{
- byte(vm.PUSH1), 0x0, byte(vm.DUP1), byte(vm.DUP1), byte(vm.DUP1), // in and outs zero
- byte(vm.DUP1), byte(vm.PUSH1), 0xff, byte(vm.GAS), // value=0,address=0xff, gas=GAS
- byte(vm.CALL),
- },
- tracer: mkTracer("callTracer", nil),
- want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x54d8","to":"0x00000000000000000000000000000000deadbeef","input":"0x","calls":[{"from":"0x00000000000000000000000000000000deadbeef","gas":"0xe01a","gasUsed":"0x0","to":"0x00000000000000000000000000000000000000ff","input":"0x","value":"0x0","type":"CALL"}],"value":"0x0","type":"CALL"}`,
- },
- {
- name: "Stack depletion in LOG0",
- code: []byte{byte(vm.LOG3)},
- tracer: mkTracer("callTracer", json.RawMessage(`{ "withLog": true }`)),
- want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x13880","to":"0x00000000000000000000000000000000deadbeef","input":"0x","error":"stack underflow (0 \u003c=\u003e 5)","value":"0x0","type":"CALL"}`,
- },
- {
- name: "Mem expansion in LOG0",
- code: []byte{
- byte(vm.PUSH1), 0x1,
- byte(vm.PUSH1), 0x0,
- byte(vm.MSTORE),
- byte(vm.PUSH1), 0xff,
- byte(vm.PUSH1), 0x0,
- byte(vm.LOG0),
- },
- tracer: mkTracer("callTracer", json.RawMessage(`{ "withLog": true }`)),
- want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x5b9e","to":"0x00000000000000000000000000000000deadbeef","input":"0x","logs":[{"address":"0x00000000000000000000000000000000deadbeef","topics":[],"data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","position":"0x0"}],"value":"0x0","type":"CALL"}`,
- },
- {
- // Leads to OOM on the prestate tracer
- name: "Prestate-tracer - CREATE2 OOM",
- code: []byte{
- byte(vm.PUSH1), 0x1,
- byte(vm.PUSH1), 0x0,
- byte(vm.MSTORE),
- byte(vm.PUSH1), 0x1,
- byte(vm.PUSH5), 0xff, 0xff, 0xff, 0xff, 0xff,
- byte(vm.PUSH1), 0x1,
- byte(vm.PUSH1), 0x0,
- byte(vm.CREATE2),
- byte(vm.PUSH1), 0xff,
- byte(vm.PUSH1), 0x0,
- byte(vm.LOG0),
- },
- tracer: mkTracer("prestateTracer", nil),
- want: `{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x000000000000000000000000000000000000feed":{"balance":"0x1c6bf52647880"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0"}}`,
- },
- {
- // CREATE2 which requires padding memory by prestate tracer
- name: "Prestate-tracer - CREATE2 Memory padding",
- code: []byte{
- byte(vm.PUSH1), 0x1,
- byte(vm.PUSH1), 0x0,
- byte(vm.MSTORE),
- byte(vm.PUSH1), 0x1,
- byte(vm.PUSH1), 0xff,
- byte(vm.PUSH1), 0x1,
- byte(vm.PUSH1), 0x0,
- byte(vm.CREATE2),
- byte(vm.PUSH1), 0xff,
- byte(vm.PUSH1), 0x0,
- byte(vm.LOG0),
- },
- tracer: mkTracer("prestateTracer", nil),
- want: `{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x000000000000000000000000000000000000feed":{"balance":"0x1c6bf52647880"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600160ff60016000f560ff6000a0"},"0x91ff9a805d36f54e3e272e230f3e3f5c1b330804":{"balance":"0x0"}}`,
- },
- } {
- t.Run(tc.name, func(t *testing.T) {
- triedb, _, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(),
- core.GenesisAlloc{
- to: core.GenesisAccount{
- Code: tc.code,
- },
- origin: core.GenesisAccount{
- Balance: big.NewInt(500000000000000),
- },
- }, false, rawdb.HashScheme)
- defer triedb.Close()
-
- evm := vm.NewEVM(context, txContext, statedb, params.MainnetChainConfig, vm.Config{Tracer: tc.tracer})
- msg := &core.Message{
- To: &to,
- From: origin,
- Value: big.NewInt(0),
- GasLimit: 80000,
- GasPrice: big.NewInt(0),
- GasFeeCap: big.NewInt(0),
- GasTipCap: big.NewInt(0),
- SkipAccountChecks: false,
- }
- st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(msg.GasLimit))
- if _, err := st.TransitionDb(); err != nil {
- t.Fatalf("test %v: failed to execute transaction: %v", tc.name, err)
- }
- // Retrieve the trace result and compare against the expected
- res, err := tc.tracer.GetResult()
- if err != nil {
- t.Fatalf("test %v: failed to retrieve trace result: %v", tc.name, err)
- }
- if string(res) != tc.want {
- t.Errorf("test %v: trace mismatch\n have: %v\n want: %v\n", tc.name, string(res), tc.want)
- }
- })
- }
-}
diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go
deleted file mode 100644
index 423167b13c..0000000000
--- a/eth/tracers/internal/tracetest/flat_calltrace_test.go
+++ /dev/null
@@ -1,214 +0,0 @@
-package tracetest
-
-import (
- "encoding/json"
- "fmt"
- "math/big"
- "os"
- "path/filepath"
- "reflect"
- "strings"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "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/rlp"
- "github.com/ethereum/go-ethereum/tests"
-
- // Force-load the native, to trigger registration
- "github.com/ethereum/go-ethereum/eth/tracers"
-)
-
-// flatCallTrace is the result of a callTracerParity run.
-type flatCallTrace struct {
- Action flatCallTraceAction `json:"action"`
- BlockHash common.Hash `json:"-"`
- BlockNumber uint64 `json:"-"`
- Error string `json:"error,omitempty"`
- Result flatCallTraceResult `json:"result,omitempty"`
- Subtraces int `json:"subtraces"`
- TraceAddress []int `json:"traceAddress"`
- TransactionHash common.Hash `json:"-"`
- TransactionPosition uint64 `json:"-"`
- Type string `json:"type"`
- Time string `json:"-"`
-}
-
-type flatCallTraceAction struct {
- Author common.Address `json:"author,omitempty"`
- RewardType string `json:"rewardType,omitempty"`
- SelfDestructed common.Address `json:"address,omitempty"`
- Balance hexutil.Big `json:"balance,omitempty"`
- CallType string `json:"callType,omitempty"`
- CreationMethod string `json:"creationMethod,omitempty"`
- From common.Address `json:"from,omitempty"`
- Gas hexutil.Uint64 `json:"gas,omitempty"`
- Init hexutil.Bytes `json:"init,omitempty"`
- Input hexutil.Bytes `json:"input,omitempty"`
- RefundAddress common.Address `json:"refundAddress,omitempty"`
- To common.Address `json:"to,omitempty"`
- Value hexutil.Big `json:"value,omitempty"`
-}
-
-type flatCallTraceResult struct {
- Address common.Address `json:"address,omitempty"`
- Code hexutil.Bytes `json:"code,omitempty"`
- GasUsed hexutil.Uint64 `json:"gasUsed,omitempty"`
- Output hexutil.Bytes `json:"output,omitempty"`
-}
-
-// flatCallTracerTest defines a single test to check the call tracer against.
-type flatCallTracerTest struct {
- Genesis core.Genesis `json:"genesis"`
- Context callContext `json:"context"`
- Input string `json:"input"`
- TracerConfig json.RawMessage `json:"tracerConfig"`
- Result []flatCallTrace `json:"result"`
-}
-
-func flatCallTracerTestRunner(tracerName string, filename string, dirPath string, t testing.TB) error {
- // Call tracer test found, read if from disk
- blob, err := os.ReadFile(filepath.Join("testdata", dirPath, filename))
- if err != nil {
- return fmt.Errorf("failed to read testcase: %v", err)
- }
- test := new(flatCallTracerTest)
- if err := json.Unmarshal(blob, test); err != nil {
- return fmt.Errorf("failed to parse testcase: %v", err)
- }
- // Configure a blockchain with the given prestate
- tx := new(types.Transaction)
- if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil {
- return fmt.Errorf("failed to parse testcase input: %v", err)
- }
- signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
- origin, _ := signer.Sender(tx)
- txContext := vm.TxContext{
- Origin: origin,
- GasPrice: tx.GasPrice(),
- }
- context := vm.BlockContext{
- CanTransfer: core.CanTransfer,
- Transfer: core.Transfer,
- Coinbase: test.Context.Miner,
- BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
- Time: uint64(test.Context.Time),
- Difficulty: (*big.Int)(test.Context.Difficulty),
- GasLimit: uint64(test.Context.GasLimit),
- }
- triedb, _, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
- defer triedb.Close()
-
- // Create the tracer, the EVM environment and run it
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
- if err != nil {
- return fmt.Errorf("failed to create call tracer: %v", err)
- }
- evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer})
-
- msg, err := core.TransactionToMessage(tx, signer, nil)
- if err != nil {
- return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
- }
- st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
-
- if _, err = st.TransitionDb(); err != nil {
- return fmt.Errorf("failed to execute transaction: %v", err)
- }
-
- // Retrieve the trace result and compare against the etalon
- res, err := tracer.GetResult()
- if err != nil {
- return fmt.Errorf("failed to retrieve trace result: %v", err)
- }
- ret := make([]flatCallTrace, 0)
- if err := json.Unmarshal(res, &ret); err != nil {
- return fmt.Errorf("failed to unmarshal trace result: %v", err)
- }
- if !jsonEqualFlat(ret, test.Result) {
- t.Logf("tracer name: %s", tracerName)
-
- // uncomment this for easier debugging
- // have, _ := json.MarshalIndent(ret, "", " ")
- // want, _ := json.MarshalIndent(test.Result, "", " ")
- // t.Logf("trace mismatch: \nhave %+v\nwant %+v", string(have), string(want))
-
- // uncomment this for harder debugging <3 meowsbits
- // lines := deep.Equal(ret, test.Result)
- // for _, l := range lines {
- // t.Logf("%s", l)
- // t.FailNow()
- // }
-
- t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result)
- }
- return nil
-}
-
-// Iterates over all the input-output datasets in the tracer parity test harness and
-// runs the Native tracer against them.
-func TestFlatCallTracerNative(t *testing.T) {
- testFlatCallTracer("flatCallTracer", "call_tracer_flat", t)
-}
-
-func testFlatCallTracer(tracerName string, dirPath string, t *testing.T) {
- files, err := os.ReadDir(filepath.Join("testdata", dirPath))
- if err != nil {
- t.Fatalf("failed to retrieve tracer test suite: %v", err)
- }
- for _, file := range files {
- if !strings.HasSuffix(file.Name(), ".json") {
- continue
- }
- file := file // capture range variable
- t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) {
- t.Parallel()
-
- err := flatCallTracerTestRunner(tracerName, file.Name(), dirPath, t)
- if err != nil {
- t.Fatal(err)
- }
- })
- }
-}
-
-// jsonEqual is similar to reflect.DeepEqual, but does a 'bounce' via json prior to
-// comparison
-func jsonEqualFlat(x, y interface{}) bool {
- xTrace := new([]flatCallTrace)
- yTrace := new([]flatCallTrace)
- if xj, err := json.Marshal(x); err == nil {
- json.Unmarshal(xj, xTrace)
- } else {
- return false
- }
- if yj, err := json.Marshal(y); err == nil {
- json.Unmarshal(yj, yTrace)
- } else {
- return false
- }
- return reflect.DeepEqual(xTrace, yTrace)
-}
-
-func BenchmarkFlatCallTracer(b *testing.B) {
- files, err := filepath.Glob("testdata/call_tracer_flat/*.json")
- if err != nil {
- b.Fatalf("failed to read testdata: %v", err)
- }
-
- for _, file := range files {
- filename := strings.TrimPrefix(file, "testdata/call_tracer_flat/")
- b.Run(camel(strings.TrimSuffix(filename, ".json")), func(b *testing.B) {
- for n := 0; n < b.N; n++ {
- err := flatCallTracerTestRunner("flatCallTracer", filename, "call_tracer_flat", b)
- if err != nil {
- b.Fatal(err)
- }
- }
- })
- }
-}
diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go
deleted file mode 100644
index b4fa5b6272..0000000000
--- a/eth/tracers/internal/tracetest/prestate_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2021 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 tracetest
-
-import (
- "encoding/json"
- "math/big"
- "os"
- "path/filepath"
- "strings"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "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/eth/tracers"
- "github.com/ethereum/go-ethereum/tests"
-)
-
-// prestateTrace is the result of a prestateTrace run.
-type prestateTrace = map[common.Address]*account
-
-type account struct {
- Balance string `json:"balance"`
- Code string `json:"code"`
- Nonce uint64 `json:"nonce"`
- Storage map[common.Hash]common.Hash `json:"storage"`
-}
-
-// testcase defines a single test to check the stateDiff tracer against.
-type testcase struct {
- Genesis *core.Genesis `json:"genesis"`
- Context *callContext `json:"context"`
- Input string `json:"input"`
- TracerConfig json.RawMessage `json:"tracerConfig"`
- Result interface{} `json:"result"`
-}
-
-func TestPrestateTracerLegacy(t *testing.T) {
- testPrestateDiffTracer("prestateTracerLegacy", "prestate_tracer_legacy", t)
-}
-
-func TestPrestateTracer(t *testing.T) {
- testPrestateDiffTracer("prestateTracer", "prestate_tracer", t)
-}
-
-func TestPrestateWithDiffModeTracer(t *testing.T) {
- testPrestateDiffTracer("prestateTracer", "prestate_tracer_with_diff_mode", t)
-}
-
-func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) {
- files, err := os.ReadDir(filepath.Join("testdata", dirPath))
- if err != nil {
- t.Fatalf("failed to retrieve tracer test suite: %v", err)
- }
- for _, file := range files {
- if !strings.HasSuffix(file.Name(), ".json") {
- continue
- }
- file := file // capture range variable
- t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) {
- t.Parallel()
-
- var (
- test = new(testcase)
- tx = new(types.Transaction)
- )
- // Call tracer test found, read if from disk
- if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil {
- t.Fatalf("failed to read testcase: %v", err)
- } else if err := json.Unmarshal(blob, test); err != nil {
- t.Fatalf("failed to parse testcase: %v", err)
- }
- if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil {
- t.Fatalf("failed to parse testcase input: %v", err)
- }
- // Configure a blockchain with the given prestate
- var (
- signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
- origin, _ = signer.Sender(tx)
- txContext = vm.TxContext{
- Origin: origin,
- GasPrice: tx.GasPrice(),
- }
- context = vm.BlockContext{
- CanTransfer: core.CanTransfer,
- Transfer: core.Transfer,
- Coinbase: test.Context.Miner,
- BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)),
- Time: uint64(test.Context.Time),
- Difficulty: (*big.Int)(test.Context.Difficulty),
- GasLimit: uint64(test.Context.GasLimit),
- BaseFee: test.Genesis.BaseFee,
- }
- triedb, _, statedb = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
- )
- defer triedb.Close()
-
- tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig)
- if err != nil {
- t.Fatalf("failed to create call tracer: %v", err)
- }
- evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Tracer: tracer})
- msg, err := core.TransactionToMessage(tx, signer, nil)
- if err != nil {
- t.Fatalf("failed to prepare transaction for tracing: %v", err)
- }
- st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
- if _, err = st.TransitionDb(); err != nil {
- t.Fatalf("failed to execute transaction: %v", err)
- }
- // Retrieve the trace result and compare against the expected
- res, err := tracer.GetResult()
- if err != nil {
- t.Fatalf("failed to retrieve trace result: %v", err)
- }
- // The legacy javascript calltracer marshals json in js, which
- // is not deterministic (as opposed to the golang json encoder).
- if strings.HasSuffix(dirPath, "_legacy") {
- // This is a tweak to make it deterministic. Can be removed when
- // we remove the legacy tracer.
- var x prestateTrace
- json.Unmarshal(res, &x)
- res, _ = json.Marshal(x)
- }
- want, err := json.Marshal(test.Result)
- if err != nil {
- t.Fatalf("failed to marshal test: %v", err)
- }
- if string(want) != string(res) {
- t.Fatalf("trace mismatch\n have: %v\n want: %v\n", string(res), string(want))
- }
- })
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer/create.json
deleted file mode 100644
index df0b2872b4..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/create.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "context": {
- "difficulty": "3755480783",
- "gasLimit": "5401723",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "number": "2294702",
- "timestamp": "1513676146"
- },
- "genesis": {
- "alloc": {
- "0x13e4acefe6a6700604929946e70e6443e4e73447": {
- "balance": "0xcf3e0938579f000",
- "code": "0x",
- "nonce": "9",
- "storage": {}
- },
- "0x7dc9c9730689ff0b0fd506c67db815f12d90a448": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3757315409",
- "extraData": "0x566961425443",
- "gasLimit": "5406414",
- "hash": "0xae107f592eebdd9ff8d6ba00363676096e6afb0e1007a7d3d0af88173077378d",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "mixHash": "0xc927aa05a38bc3de864e95c33b3ae559d3f39c4ccd51cef6f113f9c50ba0caf1",
- "nonce": "0x93363bbd2c95f410",
- "number": "2294701",
- "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c",
- "timestamp": "1513676127",
- "totalDifficulty": "7160808139332585"
- },
- "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f",
- "result": {
- "from": "0x13e4acefe6a6700604929946e70e6443e4e73447",
- "gas": "0x897be",
- "gasUsed": "0x897be",
- "input": "0x606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a11",
- "output": "0x606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029",
- "to": "0x7dc9c9730689ff0b0fd506c67db815f12d90a448",
- "type": "CREATE",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json
deleted file mode 100644
index 975616064a..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json
+++ /dev/null
@@ -1,409 +0,0 @@
-{
- "context": {
- "difficulty": "117066904",
- "gasLimit": "4712384",
- "miner": "0x1977c248e1014cc103929dd7f154199c916e39ec",
- "number": "25001",
- "timestamp": "1479891545"
- },
- "genesis": {
- "alloc": {
- "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38": {
- "balance": "0x0",
- "code": "0x606060405236156100825760e060020a600035046302d05d3f811461008a5780630accce061461009c5780631ab9075a146100c757806331ed274614610102578063645a3b7214610133578063772fdae314610155578063a7f4377914610180578063ae5f80801461019e578063c9bded21146101ea578063f905c15a14610231575b61023a610002565b61023c600054600160a060020a031681565b61023a600435602435604435606435608435600254600160a060020a03166000141561024657610002565b61023a600435600254600160a060020a03166000148015906100f8575060025433600160a060020a03908116911614155b156102f457610002565b61023a60043560243560443560643560843560a43560c435600254600160a060020a03166000141561031657610002565b61023a600435602435600254600160a060020a0316600014156103d057610002565b61023a600435602435604435606435608435600254600160a060020a03166000141561046157610002565b61023a60025433600160a060020a0390811691161461051657610002565b61023a6004356024356044356060828152600160a060020a0382169060ff8516907fa6c2f0913db6f79ff0a4365762c61718973b3413d6e40382e704782a9a5099f690602090a3505050565b61023a600435602435600160a060020a038116606090815260ff8316907fee6348a7ec70f74e3d6cba55a53e9f9110d180d7698e9117fc466ae29a43e34790602090a25050565b61023c60035481565b005b6060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061029d57610002565b60408051858152602081018390528151600160a060020a03858116939087169260ff8a16927f5a690ecd0cb15c1c1fd6b6f8a32df0d4f56cb41a54fea7e94020f013595de796929181900390910190a45050505050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061036d57610002565b6040805186815260208101869052808201859052606081018490529051600160a060020a03831691889160ff8b16917fd65d9ddafbad8824e2bbd6f56cc9f4ac27ba60737035c10a321ea2f681c94d47919081900360800190a450505050505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061042757610002565b60408051828152905183917fa9c6cbc4bd352a6940479f6d802a1001550581858b310d7f68f7bea51218cda6919081900360200190a25050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104b857610002565b80600160a060020a031684600160a060020a03168660ff167f69bdaf789251e1d3a0151259c0c715315496a7404bce9fd0b714674685c2cab78686604051808381526020018281526020019250505060405180910390a45050505050565b600254600160a060020a0316ff",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0x2cccf5e0538493c235d1c5ef6580f77d99e91396": {
- "balance": "0x0",
- "code": "0x606060405236156100775760e060020a600035046302d05d3f811461007f57806313bc6d4b146100915780633688a877146100b95780635188f9961461012f5780637eadc976146101545780638ad79680146101d3578063a43e04d814610238578063a7f437791461025e578063e16c7d981461027c575b61029f610002565b6102a1600054600160a060020a031681565b6102be600435600160a060020a03811660009081526002602052604090205460ff165b919050565b6102d26004356040805160208181018352600080835284815260038252835190849020805460026001821615610100026000190190911604601f8101849004840283018401909552848252929390929183018282801561037d5780601f106103525761010080835404028352916020019161037d565b61029f6004356024356000805433600160a060020a039081169116146104a957610002565b61034060043560008181526001602090815260408083205481517ff905c15a0000000000000000000000000000000000000000000000000000000081529151600160a060020a03909116928392839263f905c15a92600483810193919291829003018189876161da5a03f1156100025750506040515195945050505050565b60408051602060248035600481810135601f810185900485028601850190965285855261029f9581359591946044949293909201918190840183828082843750949650505050505050600054600160a060020a0390811633909116146104f657610002565b61029f6004355b600080548190600160a060020a0390811633909116146105a457610002565b61029f60005433600160a060020a0390811691161461072957610002565b6102a1600435600081815260016020526040902054600160a060020a03166100b4565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103325780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b505050505090506100b4565b506000828152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a038581168086526002909352818520805460ff191690941790935580517f1ab9075a0000000000000000000000000000000000000000000000000000000081523090931660048401525184939192631ab9075a926024828101939192829003018183876161da5a03f11561000257505060408051602081018690528082019290925243606083015260808083526003908301527f414444000000000000000000000000000000000000000000000000000000000060a0830152517f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d39181900360c00190a15b505050565b600083815260016020526040902054600160a060020a03838116911614156104d0576104a4565b600083815260016020526040812054600160a060020a031614610389576103898361023f565b600082815260036020908152604082208054845182855293839020919360026001831615610100026000190190921691909104601f90810184900483019391929186019083901061056a57805160ff19168380011785555b5061059a9291505b808211156105a05760008155600101610556565b8280016001018555821561054e579182015b8281111561054e57825182600050559160200191906001019061057c565b50505050565b5090565b600083815260016020526040812054600160a060020a031614156105c757610002565b50506000818152600160205260408082205481517fa7f437790000000000000000000000000000000000000000000000000000000081529151600160a060020a0391909116928392839263a7f4377992600483810193919291829003018183876161da5a03f11561000257505050600160005060008460001916815260200190815260200160002060006101000a815490600160a060020a0302191690556002600050600083600160a060020a0316815260200190815260200160002060006101000a81549060ff02191690557f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d383834360405180806020018560001916815260200184600160a060020a03168152602001838152602001828103825260038152602001807f44454c000000000000000000000000000000000000000000000000000000000081526020015060200194505050505060405180910390a1505050565b600054600160a060020a0316ff",
- "nonce": "1",
- "storage": {
- "0x0684ac65a9fa32414dda56996f4183597d695987fdb82b145d722743891a6fe8": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "0x1cd76f78169a420d99346e3501dd3e541622c38a226f9b63e01cfebc69879dc7": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "0x8e54a4494fe5da016bfc01363f4f6cdc91013bb5434bd2a4a3359f13a23afa2f": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf",
- "0x94edf7f600ba56655fd65fca1f1424334ce369326c1dc3e53151dcd1ad06bc13": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xbbee47108b275f55f98482c6800f6372165e88b0330d3f5dae6419df4734366c": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "0xd38c0c4e84de118cfdcc775130155d83b8bbaaf23dc7f3c83a626b10473213bd": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xfb3aa5c655c2ec9d40609401f88d505d1da61afaa550e36ef5da0509ada257ba": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113"
- }
- },
- "0x3e9286eafa2db8101246c2131c09b49080d00690": {
- "balance": "0x0",
- "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063056d4470146100e957806316c66cc61461010c5780631ab9075a146101935780633ae1005c146101ce57806358541662146101fe5780635ed61af014610231578063644e3b791461025457806384dbac3b146102db578063949ae479146102fd5780639859387b14610321578063a7f4377914610340578063ab03fc261461035e578063e8161b7814610385578063e964d4e114610395578063f905c15a146103a5578063f92eb774146103ae575b6103be610002565b6103c0600054600160a060020a031681565b6103be6004356002546000908190600160a060020a031681141561040357610002565b6103dd60043560006108365b6040805160025460e360020a631c2d8fb30282527f636f6e747261637464620000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435600254600160a060020a03166000148015906101c4575060025433600160a060020a03908116911614155b1561088d57610002565b6103be600435602435604435606435600254600090819081908190600160a060020a03168114156108af57610002565b6103c0600435602435604435606435608435600254600090819081908190600160a060020a03168114156110e857610002565b6103be6004356002546000908190600160a060020a03168114156115ec57610002565b6103c06004356000611b635b6040805160025460e360020a631c2d8fb30282527f6d61726b6574646200000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435602435600254600160a060020a031660001415611bb557610002565b6103be600435602435600254600090600160a060020a0316811415611d2e57610002565b6103be600435600254600160a060020a031660001415611fc657610002565b6103be60025433600160a060020a0390811691161461207e57610002565b6103be600435602435604435600254600090600160a060020a031681141561208c57610002565b6103dd60043560006124b8610260565b6103c0600435600061250a610118565b6103f160035481565b6103f16004356000612561610260565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061046557610002565b8291506104e55b6040805160025460e360020a631c2d8fb30282527f63706f6f6c00000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f115610002575050604051519150505b90565b600160a060020a031663b2206e6d83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fb2206e6d0000000000000000000000000000000000000000000000000000000082526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f11561000257505060405151915061059b90506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f115610002575050506107355b6040805160025460e360020a631c2d8fb30282527f6c6f676d6772000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b50826120ee5b6040805160025460e360020a631c2d8fb30282527f6163636f756e7463746c0000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316630accce06600684600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150866040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050505050565b600160a060020a03166316c66cc6836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519150505b919050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061091157610002565b87935061091c610260565b600160a060020a031663bdbdb08685600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fbdbdb0860000000000000000000000000000000000000000000000000000000082526004820152602481018a905290516044808301935060209282900301816000876161da5a03f1156100025750506040515193506109ca90506106ba565b600160a060020a03166381982a7a8885876040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610a3661046c565b600160a060020a03166308636bdb85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517f08636bdb000000000000000000000000000000000000000000000000000000008252600482015260248101889052604481019290925251606482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919450600160a060020a03871692506314baa1b6916024828101926000929190829003018183876161da5a03f11561000257505050610b3561046c565b600160a060020a0316630a3b6ede85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038d16602482015290516044808301935060209282900301816000876161da5a03f115610002575050604051519150610bd590506106ba565b600160a060020a031663d5b205ce87838b6040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610c41610118565b600160a060020a031663988db79c888a6040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050610ca5610260565b600160a060020a031663f4f2821b896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610d6f5b6040805160025460e360020a631c2d8fb30282527f747261646564620000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316635f539d69896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610dc2610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928e9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610ec5610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928d9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610fc8610639565b600160a060020a031663645a3b7285600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151905061101e610260565b600160a060020a031663f92eb77488600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f115610002575050505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061114a57610002565b604051600254600160a060020a0316908a908a908a908a908a90611579806125b38339018087600160a060020a0316815260200186600160a060020a03168152602001856000191681526020018481526020018381526020018281526020019650505050505050604051809103906000f092506111c5610118565b600160a060020a031663b9858a288a856040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611229610260565b600160a060020a0316635188f99689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611288610260565b600160a060020a031663bdbdb08689896040518360e060020a0281526004018083600019168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750506040515192506112e590506106ba565b600160a060020a03166346d88e7d8a858a6040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506000604051808303816000876161da5a03f115610002575050506113516106ba565b600160a060020a03166381982a7a8a84866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050506113bd61046c565b600160a060020a0316632b58469689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f1156100025750505061141c61046c565b600160a060020a03166308636bdb8984866040518460e060020a028152600401808460001916815260200183815260200182600160a060020a0316815260200193505050506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919350600160a060020a03861692506314baa1b6916024828101926000929190829003018183876161da5a03f115610002575050506114d3610639565b6040805160e160020a630566670302815260016004820152602481018b9052600160a060020a0386811660448301528c811660648301526000608483018190529251931692630accce069260a480840193919291829003018183876161da5a03f11561000257505050611544610639565b600160a060020a031663645a3b728961155b610260565b600160a060020a031663f92eb7748c6040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448084019360009350829003018183876161da5a03f1156100025750939a9950505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061164e57610002565b82915061165961046c565b600160a060020a0316630a3b6ede83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f1156100025750506040515191506116f990506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f1156100025750505061179b6106ba565b600160a060020a031663d653078983600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517ff1ff78a0000000000000000000000000000000000000000000000000000000008252915191929163f1ff78a09160048181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f1156100025750505061189f610260565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506118f2610118565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050611945610639565b600160a060020a0316630accce06600484600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da44689181870191602091908190038801816000876161da5a03f115610002575050506040518051906020015060006040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050611a48610639565b600160a060020a031663645a3b7283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611a9e610260565b600160a060020a031663f92eb77486600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b600160a060020a03166381738c59836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611c1757610002565b611c1f610260565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060405151159050611c7457610002565b611c7c610260565b600160a060020a0316632243118a836040518260e060020a02815260040180826000191681526020019150506000604051808303816000876161da5a03f11561000257505050611cca610639565b600160a060020a031663ae5f8080600184846040518460e060020a028152600401808481526020018360001916815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611d9057610002565b5081611d9a610260565b600160a060020a031663581d5d6084846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505050611df5610639565b600160a060020a0316630accce06600283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630566670302825260048201949094526024810193909352600160a060020a038816604484015260006064840181905260848401819052905160a4808501949293509091829003018183876161da5a03f11561000257505050611eab610639565b600160a060020a031663645a3b7282600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611f01610260565b600160a060020a031663f92eb77485600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061202857610002565b612030610118565b600160a060020a0316639859387b826040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505050565b600254600160a060020a0316ff5b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f11561000257505060405151151590506106b457610002565b600160a060020a031663d65307898383600160a060020a031663f1ff78a06040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fd6530789000000000000000000000000000000000000000000000000000000008252600160a060020a039485166004830152602482015292891660448401525160648381019360009350829003018183876161da5a03f115610002575050506121a5610118565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506121f8610cf4565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505061224b610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d028252915191928a9290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f1156100025750505080600160a060020a031663ea71b02d6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a031660001490506124b25761239f610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fea71b02d000000000000000000000000000000000000000000000000000000008252915191928a92909163ea71b02d91600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f115610002575050505b50505050565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663213fe2b7836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663f92eb774836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f115610002575050604051519150610888905056606060405260405160c08061157983396101206040819052825160805160a051935160e0516101005160008054600160a060020a03199081163317909155600180546005805484168817905560048a90556006869055600b8590556008849055909116861760a060020a60ff02191690554360038190556002558686526101408390526101608190529396929594919390929091600160a060020a033016917f76885d242fb71c6f74a7e717416e42eff4d96faf54f6de75c6a0a6bbd8890c6b91a230600160a060020a03167fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff600b600050546040518082815260200191505060405180910390a250505050505061145e8061011b6000396000f3606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "16",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0x70c9217d814985faef62b124420f8dfbddd96433": {
- "balance": "0x4ef436dcbda6cd4a",
- "code": "0x",
- "nonce": "1634",
- "storage": {}
- },
- "0x7986bad81f4cbd9317f5a46861437dae58d69113": {
- "balance": "0x0",
- "code": "0x6060604052361561008d5760e060020a600035046302d05d3f811461009557806316c66cc6146100a75780631ab9075a146100d7578063213fe2b7146101125780639859387b1461013f578063988db79c1461015e578063a7f4377914610180578063b9858a281461019e578063c8e40fbf146101c0578063f4f2821b146101e8578063f905c15a14610209575b610212610002565b610214600054600160a060020a031681565b600160a060020a0360043581811660009081526005602052604081205461023193168114610257575060016101e3565b610212600435600254600160a060020a0316600014801590610108575060025433600160a060020a03908116911614155b1561025f57610002565b610214600435600160a060020a03811660009081526004602052604081205460ff16151561027557610002565b610212600435600254600160a060020a03166000141561029b57610002565b610212600435602435600254600160a060020a03166000141561050457610002565b61021260025433600160a060020a0390811691161461056757610002565b610212600435602435600254600160a060020a03166000141561057557610002565b610231600435600160a060020a03811660009081526004602052604090205460ff165b919050565b610212600435600254600090600160a060020a031681141561072057610002565b61024560035481565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060006101e3565b60028054600160a060020a031916821790555b50565b50600160a060020a038181166000908152600460205260409020546101009004166101e3565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506102fe57610002565b600160a060020a03811660009081526004602052604090205460ff161515610272576040516104028061092e833901809050604051809103906000f06004600050600083600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600083600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555050565b600160a060020a03821660009081526004602052604090205460ff1615156104725760405161040280610d30833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a03811660009081526006602052604090208054600160a060020a031916831790555b5050565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506103b957610002565b600254600160a060020a0316ff5b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506105d857610002565b600160a060020a03821660009081526004602052604090205460ff1615156106915760405161040280611132833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a031660009081526005602052604090208054600160a060020a0319169091179055565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f115610002575050604051511515905061078357610002565b50600160a060020a0381811660009081526005602090815260408083205490931680835260049091529190205460ff161561080f576040600081812054825160e260020a632e72bafd028152600160a060020a03868116600483015293516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260056020526040812054909116146108545760406000908120600160a060020a0384169091528054600160a060020a03191690555b50600160a060020a0381811660009081526006602090815260408083205490931680835260049091529190205460ff16156108e657600160a060020a038181166000908152604080518183205460e260020a632e72bafd028252868516600483015291516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260066020526040812054909116146105005760406000908120600160a060020a0384169091528054600160a060020a0319169055505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056",
- "nonce": "7",
- "storage": {
- "0xffc4df2d4f3d2cffad590bed6296406ab7926ca9e74784f74a95191fa069a174": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433"
- }
- },
- "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f": {
- "balance": "0x0",
- "code": "0x606060405236156100ae5760e060020a600035046302d05d3f81146100b65780631ab9075a146100c85780632b68bb2d146101035780634cc927d7146101c557806351a34eb81461028e57806356ccb6f0146103545780635928d37f1461041d578063599efa6b146104e9578063759297bb146105b2578063771d50e11461067e578063a7f4377914610740578063f905c15a1461075e578063f92eb77414610767578063febf661214610836575b610902610002565b610904600054600160a060020a031681565b610902600435600254600160a060020a03166000148015906100f9575060025433600160a060020a03908116911614155b1561092057610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061094257610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610a0d57610002565b61090260043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ae957610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610bbc57610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610c9657610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610de057610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ebb57610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f9e57610002565b61090260025433600160a060020a0390811691161461106957610002565b61090e60035481565b61090e60043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750506040805180517ff92eb774000000000000000000000000000000000000000000000000000000008252600482018790529151919350600160a060020a038416925063f92eb774916024828101926020929190829003018188876161da5a03f11561000257505060405151949350505050565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061107757610002565b005b6060908152602090f35b60408051918252519081900360200190f35b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5ed61af000000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152925190959286169350635ed61af092602483810193919291829003018183876161da5a03f115610002575050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fab03fc2600000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015260248301899052808816604484015292519095928616935063ab03fc2692606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f949ae47900000000000000000000000000000000000000000000000000000000825233600160a060020a0390811660048401526024830188905292519095928616935063949ae47992604483810193919291829003018183876161da5a03f11561000257505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f46d88e7d000000000000000000000000000000000000000000000000000000008252600160a060020a0380891660048401523381166024840152604483018890529251909592861693506346d88e7d92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5315cdde00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a16602484015260448301889052925190959286169350635315cdde92606483810193919291829003018183876161da5a03f115610002575050604080517f5928d37f00000000000000000000000000000000000000000000000000000000815233600160a060020a03908116600483015287166024820152604481018690529051635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fe68e401c00000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015280891660248401526044830188905292519095928616935063e68e401c92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5152f381000000000000000000000000000000000000000000000000000000008252600160a060020a03808a1660048401528089166024840152604483018890523381166064840152925190959286169350635152f38192608483810193919291829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f056d447000000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015292519095928616935063056d447092602483810193919291829003018183876161da5a03f115610002575050505050565b600254600160a060020a0316ff5b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f3ae1005c00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a166024840152808916604484015260648301889052925190959286169350633ae1005c92608483810193919291829003018183876161da5a03f11561000257505050505050505056",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": {
- "balance": "0x0",
- "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000006195",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000008ac7230489e80000",
- "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000"
- }
- },
- "0xcf00ffd997ad14939736f026006498e3f099baaf": {
- "balance": "0x0",
- "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063031e7f5d146100e95780631ab9075a1461010b5780632243118a1461014657806327aad68a1461016557806338a699a4146101da5780635188f996146101f8578063581d5d601461021e57806381738c5914610246578063977da54014610269578063a07421ce14610288578063a7f43779146102be578063bdbdb086146102dc578063e1c7111914610303578063f4f2821b14610325578063f905c15a1461034a578063f92eb77414610353575b610387610002565b610389600054600160a060020a031681565b610387600435602435600254600160a060020a0316600014156103a857610002565b610387600435600254600160a060020a031660001480159061013c575060025433600160a060020a03908116911614155b1561042957610002565b610387600435600254600160a060020a03166000141561044b57610002565b6102ac60043560008181526004602081815260408320547f524d81d3000000000000000000000000000000000000000000000000000000006060908152610100909104600160a060020a031692839263524d81d3926064928188876161da5a03f1156100025750506040515192506103819050565b61039c60043560008181526004602052604090205460ff165b919050565b6103876004356024356002546000908190600160a060020a031681141561079457610002565b61038760043560243560025460009081908190600160a060020a031681141561080457610002565b61038960043560008181526004602052604081205460ff1615156109e357610002565b610387600435600254600160a060020a0316600014156109fb57610002565b600435600090815260096020526040902054670de0b6b3a764000090810360243502045b60408051918252519081900360200190f35b61038760025433600160a060020a03908116911614610a9257610002565b600435600090815260086020526040902054670de0b6b3a7640000602435909102046102ac565b610387600435602435600254600160a060020a031660001415610aa057610002565b61038760043560025460009081908190600160a060020a0316811415610b3657610002565b6102ac60035481565b6102ac600435600081815260076020908152604080832054600690925290912054670de0b6b3a76400000204805b50919050565b005b600160a060020a03166060908152602090f35b15156060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506103fe57610002565b60008281526004602052604090205460ff16151561041b57610002565b600860205260406000205550565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104a157610002565b604080516000838152600460205291909120805460ff1916600117905561040280610de2833901809050604051809103906000f0600460005060008360001916815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555066470de4df8200006008600050600083600019168152602001908152602001600020600050819055506703782dace9d9000060096000506000836000191681526020019081526020016000206000508190555050565b600460005060008560001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151821415905061060057838152600660209081526040808320839055600790915281208190555b81600160a060020a0316630a3b0a4f846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050600160a060020a038316808252600560209081526040808420879055805160e160020a6364a81ff102815290518694670de0b6b3a7640000949363c9503fe29360048181019492939183900301908290876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008660001916815260200190815260200160002060008282825054019250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000866000191681526020019081526020016000206000828282505401925050819055505b50505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f11561000257505060405151151590506107e957610002565b8381526004602052604081205460ff16151561056657610002565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f115610002575050604051511515905061085957610002565b849250670de0b6b3a764000083600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575060408051805160e160020a6364a81ff102825291519189028590049650600481810192602092909190829003018188876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b9391600481810192602092909190829003018189876161da5a03f115610002575050506040518051906020015002049050806006600050600085600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750604080518051855260208681528286208054989098039097557f2e94420f00000000000000000000000000000000000000000000000000000000815290518896600483810193919291829003018187876161da5a03f115610002575050604080515183526020939093525020805490910190555050505050565b60409020546101009004600160a060020a03166101f3565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610a5157610002565b60008181526004602052604090205460ff161515610a6e57610002565b6040600020805474ffffffffffffffffffffffffffffffffffffffffff1916905550565b600254600160a060020a0316ff5b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610af657610002565b60008281526004602052604090205460ff161515610b1357610002565b670de0b6b3a7640000811115610b2857610002565b600960205260406000205550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f1156100025750506040515115159050610b8b57610002565b600160a060020a038416815260056020908152604080832054808452600490925282205490935060ff161515610bc057610002565b600460005060008460001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663b9caebf4856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506005600050600085600160a060020a0316815260200190815260200160002060005060009055839050600082600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519190911115905061078e57670de0b6b3a764000081600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008560001916815260200190815260200160002060008282825054039250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000856000191681526020019081526020016000206000828282505403925050819055505050505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056",
- "nonce": "3",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x3571d73f14f31a1463bd0a2f92f7fde1653d4e1ead7aedf4b0a5df02f16092ab": "0x0000000000000000000000000000000000000000000007d634e4c55188be0000",
- "0x4e64fe2d1b72d95a0a31945cc6e4f4e524ac5ad56d6bd44a85ec7bc9cc0462c0": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000"
- }
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "117124093",
- "extraData": "0xd5830105008650617269747986312e31322e31826d61",
- "gasLimit": "4707788",
- "hash": "0xad325e4c49145fb7a4058a68ac741cc8607a71114e23fc88083c7e881dd653e7",
- "miner": "0x00714b9ac97fd6bd9325a059a70c9b9fa94ce050",
- "mixHash": "0x0af918f65cb4af04b608fc1f14a849707696986a0e7049e97ef3981808bcc65f",
- "nonce": "0x38dee147326a8d40",
- "number": "25000",
- "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b",
- "timestamp": "1479891517",
- "totalDifficulty": "1895410389427"
- },
- "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065",
- "result": {
- "calls": [
- {
- "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "gas": "0x31217",
- "gasUsed": "0x334",
- "input": "0xe16c7d98636f6e7472616374617069000000000000000000000000000000000000000000",
- "output": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x2a68d",
- "gasUsed": "0x334",
- "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x23ac9",
- "gasUsed": "0x334",
- "input": "0xe16c7d98636f6e7472616374646200000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x23366",
- "gasUsed": "0x273",
- "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x7986bad81f4cbd9317f5a46861437dae58d69113",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x29f35",
- "gasUsed": "0xf8d",
- "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x28a9e",
- "gasUsed": "0x334",
- "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x21d79",
- "gasUsed": "0x24d",
- "input": "0x13bc6d4b000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x2165b",
- "gasUsed": "0x334",
- "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000",
- "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1a8e8",
- "gasUsed": "0x24d",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1a2c6",
- "gasUsed": "0x3cb",
- "input": "0xc9503fe2",
- "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x19b72",
- "gasUsed": "0x3cb",
- "input": "0xc9503fe2",
- "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x19428",
- "gasUsed": "0x305",
- "input": "0x6f265b93",
- "output": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x18d45",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1734e",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x20ee1",
- "gasUsed": "0x5374",
- "input": "0x581d5d60000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000",
- "to": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1b6c1",
- "gasUsed": "0x334",
- "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1af69",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "gas": "0x143a5",
- "gasUsed": "0x24d",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1a91d",
- "gasUsed": "0x12fa",
- "input": "0x0accce0600000000000000000000000000000000000000000000000000000000000000025842545553440000000000000000000000000000000000000000000000000000000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x19177",
- "gasUsed": "0x334",
- "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x18a22",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x18341",
- "gasUsed": "0x334",
- "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000",
- "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x17bec",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1764e",
- "gasUsed": "0x45c",
- "input": "0xf92eb7745842545553440000000000000000000000000000000000000000000000000000",
- "output": "0x00000000000000000000000000000000000000000000002816d180e30c390000",
- "to": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "gas": "0x108ba",
- "gasUsed": "0x24d",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x16e62",
- "gasUsed": "0xebb",
- "input": "0x645a3b72584254555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002816d180e30c390000",
- "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x283b9",
- "gasUsed": "0xc51c",
- "input": "0x949ae479000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000",
- "to": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "gas": "0x30b4a",
- "gasUsed": "0xedb7",
- "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000",
- "to": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0x70c9217d814985faef62b124420f8dfbddd96433",
- "gas": "0x3d090",
- "gasUsed": "0x1810b",
- "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json
deleted file mode 100644
index 6a2cda7dc9..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json
+++ /dev/null
@@ -1,97 +0,0 @@
-{
- "context": {
- "difficulty": "31927752",
- "gasLimit": "4707788",
- "miner": "0x5659922ce141eedbc2733678f9806c77b4eebee8",
- "number": "11495",
- "timestamp": "1479735917"
- },
- "genesis": {
- "alloc": {
- "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff": {
- "balance": "0x0",
- "code": "0x606060405236156100825760e060020a60003504630a0313a981146100875780630a3b0a4f146101095780630cd40fea1461021257806329092d0e1461021f5780634cd06a5f146103295780635dbe47e8146103395780637a9e5410146103d9578063825db5f7146103e6578063a820b44d146103f3578063efa52fb31461047a575b610002565b34610002576104fc600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a26333556e849091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f415610002575050604051519150505b919050565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f21ce24d4000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926321ce24d49260448082019391829003018186803b156100025760325a03f415610002575050505b50565b3461000257610512600181565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f89489a87000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926389489a879260448082019391829003018186803b156100025760325a03f4156100025750505061020f565b3461000257610528600435610403565b34610002576104fc600435604080516000602091820181905282517f7d65837a00000000000000000000000000000000000000000000000000000000815260048101829052600160a060020a0385166024820152925190927342b02b5deeb78f34cd5ac896473b63e6c99a71a292637d65837a92604480840193829003018186803b156100025760325a03f4156100025750506040515191506101049050565b3461000257610512600c81565b3461000257610512600081565b3461000257610528600061055660005b600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263685a1f3c9091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b346100025761053a600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263f775b6b59091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b604080519115158252519081900360200190f35b005b6040805160ff9092168252519081900360200190f35b60408051918252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b90509056",
- "nonce": "1",
- "storage": {
- "0x4d140b25abf3c71052885c66f73ce07cff141c1afabffdaf5cba04d625b7ebcc": "0x0000000000000000000000000000000000000000000000000000000000000001"
- }
- },
- "0x269296dddce321a6bcbaa2f0181127593d732cba": {
- "balance": "0x0",
- "code": "0x606060405236156101275760e060020a60003504630cd40fea811461012c578063173825d9146101395780631849cb5a146101c7578063285791371461030f5780632a58b3301461033f5780632cb0d48a146103565780632f54bf6e1461036a578063332b9f061461039d5780633ca8b002146103c55780633df4ddf4146103d557806341c0e1b5146103f457806347799da81461040557806362a51eee1461042457806366907d13146104575780637065cb48146104825780637a9e541014610496578063825db5f7146104a3578063949d225d146104b0578063a51687df146104c7578063b4da4e37146104e6578063b4e6850b146104ff578063bd7474ca14610541578063e75623d814610541578063e9938e1114610555578063f5d241d314610643575b610002565b3461000257610682600181565b34610002576106986004356106ff335b60006001600a9054906101000a9004600160a060020a0316600160a060020a0316635dbe47e8836000604051602001526040518260e060020a0281526004018082600160a060020a03168152602001915050602060405180830381600087803b156100025760325a03f1156100025750506040515191506103989050565b3461000257604080516101008082018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a0360043581168752600586529589902089519788018a528054808816808a52605060020a91829004600160a060020a0316978a01889052600183015463ffffffff8082169d8c018e905264010000000082048116988c01899052604060020a90910416958a018690526002830154948a01859052600390920154808916938a01849052049096169690970186905293969495949293604080516001605060020a03998a16815297891660208901529590971686860152600160a060020a03909316606086015263ffffffff9182166080860152811660a08501521660c083015260e08201929092529051908190036101000190f35b346100025761069a60043560018054600091829160ff60f060020a909104161515141561063d5761072833610376565b34610002576106ae6004546001605060020a031681565b34610002576106986004356108b333610149565b346100025761069a6004355b600160a060020a03811660009081526002602052604090205460ff1615156001145b919050565b34610002576106986001805460ff60f060020a9091041615151415610913576108ed33610376565b346100025761069a600435610149565b34610002576106ae6003546001605060020a03605060020a9091041681565b346100025761069861091533610149565b34610002576106ae6003546001605060020a0360a060020a9091041681565b346100025761069a60043560243560018054600091829160ff60f060020a909104161515141561095e5761092633610376565b34610002576106986004356001805460ff60f060020a909104161515141561072557610a8b33610376565b3461000257610698600435610aa533610149565b3461000257610682600c81565b3461000257610682600081565b34610002576106ae6003546001605060020a031681565b34610002576106ca600154600160a060020a03605060020a9091041681565b346100025761069a60015460ff60f060020a9091041681565b346100025761069a60043560243560443560643560843560a43560c43560018054600091829160ff60f060020a9091041615151415610b5857610ad233610376565b3461000257610698600435610bd633610149565b34610002576106e6600435604080516101008181018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a03808b168752600586529589902089519788018a5280548088168952600160a060020a03605060020a918290041696890196909652600181015463ffffffff8082169b8a019b909b5264010000000081048b1695890195909552604060020a90940490981691860182905260028301549086015260039091015480841696850196909652940416918101919091525b50919050565b346100025761069a60043560243560443560643560843560a43560018054600091829160ff60f060020a9091041615151415610c8e57610bfb33610376565b6040805160ff9092168252519081900360200190f35b005b604080519115158252519081900360200190f35b604080516001605060020a039092168252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b6040805163ffffffff9092168252519081900360200190f35b1561012757600160a060020a0381166000908152600260205260409020805460ff191690555b50565b1561063d57506001605060020a0380831660009081526005602052604090208054909116151561075b576000915061063d565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610817905b8051600354600090819060016001605060020a0390911611610c995760038054605060020a60f060020a0319169055610ddf565b600380546001605060020a031981166000196001605060020a03928316011782558416600090815260056020526040812080547fffff000000000000000000000000000000000000000000000000000000000000168155600181810180546bffffffffffffffffffffffff191690556002820192909255909101805473ffffffffffffffffffffffffffffffffffffffff19169055915061063d565b1561012757600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a8302179055610725565b1561091357600480546001605060020a031981166001605060020a039091166001011790555b565b156101275733600160a060020a0316ff5b1561095e57506001605060020a03808416600090815260056020526040902080549091161515610965576000915061095e565b600191505b5092915050565b60038101546001605060020a0384811691161415610986576001915061095e565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610a12906107e3565b61095983825b80546003546001605060020a0391821691600091161515610de55760038054605060020a60a060020a031916605060020a84021760a060020a69ffffffffffffffffffff02191660a060020a84021781558301805473ffffffffffffffffffffffffffffffffffffffff19169055610ddf565b1561072557600480546001605060020a0319168217905550565b1561012757600160a060020a0381166000908152600260205260409020805460ff19166001179055610725565b15610b5857506001605060020a038088166000908152600560205260409020805490911615610b645760009150610b58565b6004546001605060020a0390811690891610610b3057600480546001605060020a03191660018a011790555b6003805460016001605060020a03821681016001605060020a03199092169190911790915591505b50979650505050505050565b80546001605060020a0319168817605060020a60f060020a031916605060020a880217815560018101805463ffffffff1916871767ffffffff0000000019166401000000008702176bffffffff00000000000000001916604060020a860217905560028101839055610b048982610a18565b156101275760018054605060020a60f060020a031916605060020a8302179055610725565b15610c8e57506001605060020a03808816600090815260056020526040902080549091161515610c2e5760009150610c8e565b8054605060020a60f060020a031916605060020a88021781556001808201805463ffffffff1916881767ffffffff0000000019166401000000008802176bffffffff00000000000000001916604060020a87021790556002820184905591505b509695505050505050565b6003546001605060020a03848116605060020a909204161415610d095760e084015160038054605060020a928302605060020a60a060020a031990911617808255919091046001605060020a031660009081526005602052604090200180546001605060020a0319169055610ddf565b6003546001605060020a0384811660a060020a909204161415610d825760c08401516003805460a060020a92830260a060020a69ffffffffffffffffffff021990911617808255919091046001605060020a03166000908152600560205260409020018054605060020a60a060020a0319169055610ddf565b505060c082015160e08301516001605060020a0380831660009081526005602052604080822060039081018054605060020a60a060020a031916605060020a8702179055928416825290200180546001605060020a031916831790555b50505050565b6001605060020a0384161515610e6457600380546001605060020a03605060020a9182900481166000908152600560205260409020830180546001605060020a0319908116871790915583548785018054918590049093168402605060020a60a060020a03199182161790911690915582549185029116179055610ddf565b506001605060020a038381166000908152600560205260409020600390810180549185018054605060020a60a060020a0319908116605060020a94859004909516808502959095176001605060020a0319168817909155815416918402919091179055801515610ef4576003805460a060020a69ffffffffffffffffffff02191660a060020a8402179055610ddf565b6003808401546001605060020a03605060020a9091041660009081526005602052604090200180546001605060020a031916831790555050505056",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000113204f5d64c28326fd7bd05fd4ea855302d7f2ff00000000000000000000"
- }
- },
- "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2": {
- "balance": "0x0",
- "code": "0x6504032353da7150606060405236156100695760e060020a60003504631bf7509d811461006e57806321ce24d41461008157806333556e84146100ec578063685a1f3c146101035780637d65837a1461011757806389489a8714610140578063f775b6b5146101fc575b610007565b61023460043560006100fd82600061010d565b610246600435602435600160a060020a03811660009081526020839052604081205415156102cb57826001016000508054806001018281815481835581811511610278576000838152602090206102789181019083015b808211156102d057600081556001016100d8565b610248600435602435600182015481105b92915050565b6102346004356024355b60018101906100fd565b610248600435602435600160a060020a03811660009081526020839052604090205415156100fd565b61024660043560243580600160a060020a031632600160a060020a03161415156101f857600160a060020a038116600090815260208390526040902054156101f857600160a060020a038116600090815260208390526040902054600183018054909160001901908110156100075760009182526020808320909101805473ffffffffffffffffffffffffffffffffffffffff19169055600160a060020a038316825283905260408120556002820180546000190190555b5050565b61025c60043560243560008260010160005082815481101561000757600091825260209091200154600160a060020a03169392505050565b60408051918252519081900360200190f35b005b604080519115158252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b50505060009283526020808420909201805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a0385168352908590526040909120819055600284018054600101905590505b505050565b509056",
- "nonce": "1",
- "storage": {}
- },
- "0xa529806c67cc6486d4d62024471772f47f6fd672": {
- "balance": "0x67820e39ac8fe9800",
- "code": "0x",
- "nonce": "68",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "31912170",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712388",
- "hash": "0x0855914bdc581bccdc62591fd438498386ffb59ea4d5361ed5c3702e26e2c72f",
- "miner": "0x334391aa808257952a462d1475562ee2106a6c90",
- "mixHash": "0x64bb70b8ca883cadb8fbbda2c70a861612407864089ed87b98e5de20acceada6",
- "nonce": "0x684129f283aaef18",
- "number": "11494",
- "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10",
- "timestamp": "1479735912",
- "totalDifficulty": "90744064339"
- },
- "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115",
- "result": {
- "calls": [
- {
- "calls": [
- {
- "from": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff",
- "gas": "0x2bf459",
- "gasUsed": "0x2aa",
- "input": "0x7d65837a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2",
- "type": "DELEGATECALL",
- "value": "0x0"
- }
- ],
- "from": "0x269296dddce321a6bcbaa2f0181127593d732cba",
- "gas": "0x2cae73",
- "gasUsed": "0xa9d",
- "input": "0x5dbe47e8000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0xa529806c67cc6486d4d62024471772f47f6fd672",
- "gas": "0x2dc6c0",
- "gasUsed": "0xbd55",
- "input": "0x7065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e",
- "to": "0x269296dddce321a6bcbaa2f0181127593d732cba",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json
deleted file mode 100644
index bb16a4a430..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json
+++ /dev/null
@@ -1,77 +0,0 @@
-{
- "context": {
- "difficulty": "3451177886",
- "gasLimit": "4709286",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2290744",
- "timestamp": "1513616439"
- },
- "genesis": {
- "alloc": {
- "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a": {
- "balance": "0x0",
- "code": "0x606060405263ffffffff60e060020a6000350416633b91f50681146100505780635bb47808146100715780635f51fca01461008c578063bc7647a9146100ad578063f1bd0d7a146100c8575b610000565b346100005761006f600160a060020a03600435811690602435166100e9565b005b346100005761006f600160a060020a0360043516610152565b005b346100005761006f600160a060020a036004358116906024351661019c565b005b346100005761006f600160a060020a03600435166101fa565b005b346100005761006f600160a060020a0360043581169060243516610db8565b005b600160a060020a038083166000908152602081905260408120549091908116903316811461011657610000565b839150600160a060020a038316151561012d573392505b6101378284610e2e565b6101418284610db8565b61014a826101fa565b5b5b50505050565b600154600160a060020a03908116903316811461016e57610000565b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0384161790555b5b5050565b600254600160a060020a0390811690331681146101b857610000565b600160a060020a038381166000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff19169184169190911790555b5b505050565b6040805160e260020a631a481fc102815260016024820181905260026044830152606482015262093a8060848201819052600060a4830181905260c06004840152601e60c48401527f736574456e7469747953746174757328616464726573732c75696e743829000060e484015292519091600160a060020a038516916369207f049161010480820192879290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526000602482018190526001604483015260606004830152602360648301527f626567696e506f6c6c28616464726573732c75696e7436342c626f6f6c2c626f60848301527f6f6c29000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f61646453746f636b28616464726573732c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f697373756553746f636b2875696e74382c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602160648301527f6772616e7453746f636b2875696e74382c75696e743235362c61646472657373608483015260f860020a60290260a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f115610000575050604080517f010555b8000000000000000000000000000000000000000000000000000000008152600160a060020a03338116602483015260006044830181905260606004840152603c60648401527f6772616e7456657374656453746f636b2875696e74382c75696e743235362c6160848401527f6464726573732c75696e7436342c75696e7436342c75696e743634290000000060a48401529251908716935063010555b89260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601260c48201527f626567696e53616c65286164647265737329000000000000000000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601a60648301527f7472616e7366657253616c6546756e64732875696e743235362900000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152602d60c48201527f7365744163636f756e74696e6753657474696e67732875696e743235362c756960e48201527f6e7436342c75696e7432353629000000000000000000000000000000000000006101048201529051600160a060020a03861692506369207f04916101248082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152603460648301527f637265617465526563757272696e6752657761726428616464726573732c756960848301527f6e743235362c75696e7436342c737472696e672900000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601b60648301527f72656d6f7665526563757272696e675265776172642875696e7429000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602360648301527f697373756552657761726428616464726573732c75696e743235362c7374726960848301527f6e6729000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f61737369676e53746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f72656d6f766553746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260026024808301919091526003604483015260006064830181905267ffffffffffffffff8616608484015260ff871660a484015260c0600484015260c48301919091527f7365744164647265737342796c617728737472696e672c616464726573732c6260e48301527f6f6f6c29000000000000000000000000000000000000000000000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152602160c48301527f73657453746174757342796c617728737472696e672c75696e74382c626f6f6c60e483015260f860020a6029026101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152603860c48301527f736574566f74696e6742796c617728737472696e672c75696e743235362c756960e48301527f6e743235362c626f6f6c2c75696e7436342c75696e74382900000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f115610000575050505b505050565b604080517f225553a4000000000000000000000000000000000000000000000000000000008152600160a060020a0383811660048301526002602483015291519184169163225553a49160448082019260009290919082900301818387803b156100005760325a03f115610000575050505b5050565b600082604051611fd280610f488339600160a060020a03909216910190815260405190819003602001906000f0801561000057905082600160a060020a03166308b027418260016040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b156100005760325a03f115610000575050604080517fa14e3ee300000000000000000000000000000000000000000000000000000000815260006004820181905260016024830152600160a060020a0386811660448401529251928716935063a14e3ee39260648084019382900301818387803b156100005760325a03f115610000575050505b5050505600606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029a165627a7a723058200e78a5f7e0f91739035d0fbf5eca02f79377210b722f63431f29a22e2880b3bd0029",
- "nonce": "789",
- "storage": {
- "0xfe9ec0542a1c009be8b1f3acf43af97100ffff42eb736850fb038fa1151ad4d9": "0x000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8"
- }
- },
- "0x5cb4a6b902fcb21588c86c3517e797b07cdaadb9": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- },
- "0xe4a13bc304682a903e9472f469c33801dd18d9e8": {
- "balance": "0x33c763c929f62c4f",
- "code": "0x",
- "nonce": "14",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3451177886",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4713874",
- "hash": "0x5d52a672417cd1269bf4f7095e25dcbf837747bba908cd5ef809dc1bd06144b5",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x01a12845ed546b94a038a7a03e8df8d7952024ed41ccb3db7a7ade4abc290ce1",
- "nonce": "0x28c446f1cb9748c1",
- "number": "2290743",
- "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708",
- "timestamp": "1513616414",
- "totalDifficulty": "7146523769022564"
- },
- "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281",
- "result": {
- "calls": [
- {
- "error": "contract creation code storage out of gas",
- "from": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a",
- "gas": "0x39ff0",
- "gasUsed": "0x39ff0",
- "input": "0x606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182",
- "type": "CREATE",
- "value": "0x0"
- }
- ],
- "error": "invalid jump destination",
- "from": "0xe4a13bc304682a903e9472f469c33801dd18d9e8",
- "gas": "0x493e0",
- "gasUsed": "0x493e0",
- "input": "0x3b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8",
- "to": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json
deleted file mode 100644
index 9b45b52fe9..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json
+++ /dev/null
@@ -1,61 +0,0 @@
-{
- "genesis": {
- "difficulty": "117067574",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712380",
- "hash": "0xe05db05eeb3f288041ecb10a787df121c0ed69499355716e17c307de313a4486",
- "miner": "0x0c062b329265c965deef1eede55183b3acb8f611",
- "mixHash": "0xb669ae39118a53d2c65fd3b1e1d3850dd3f8c6842030698ed846a2762d68b61d",
- "nonce": "0x2b469722b8e28c45",
- "number": "24973",
- "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369",
- "timestamp": "1479891145",
- "totalDifficulty": "1892250259406",
- "alloc": {
- "0x6c06b16512b332e6cd8293a2974872674716ce18": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d146036575b6000565b34600057604e60048080359060200190919050506050565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f19350505050505b5056",
- "storage": {}
- },
- "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31": {
- "balance": "0x229ebbb36c3e0f20",
- "nonce": "3",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 3,
- "homesteadBlock": 0,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "byzantiumBlock": 1700000,
- "constantinopleBlock": 4230000,
- "petersburgBlock": 4939394,
- "istanbulBlock": 6485846,
- "muirGlacierBlock": 7117117,
- "ethash": {}
- }
- },
- "context": {
- "number": "24974",
- "difficulty": "117067574",
- "timestamp": "1479891162",
- "gasLimit": "4712388",
- "miner": "0xc822ef32e6d26e170b70cf761e204c1806265914"
- },
- "input": "0xf889038504a81557008301f97e946c06b16512b332e6cd8293a2974872674716ce1880a42e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b1600002aa0e2a6558040c5d72bc59f2fb62a38993a314c849cd22fb393018d2c5af3112095a01bdb6d7ba32263ccc2ecc880d38c49d9f0c5a72d8b7908e3122b31356d349745",
- "result": {
- "type": "CALL",
- "from": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
- "to": "0x6c06b16512b332e6cd8293a2974872674716ce18",
- "value": "0x0",
- "gas": "0x1f97e",
- "gasUsed": "0x72de",
- "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json
deleted file mode 100644
index ad0627ccd6..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "genesis": {
- "baseFeePerGas": "1000000000",
- "difficulty": "1",
- "extraData": "0x00000000000000000000000000000000000000000000000000000000000000003623191d4ccfbbdf09e8ebf6382a1f8257417bc10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "gasLimit": "11500000",
- "hash": "0x2af138b8a06e65b8dd0999df70b9e87609e9fc91ea201f08b1cc4f25ef01fcf6",
- "miner": "0x0000000000000000000000000000000000000000",
- "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "nonce": "0x0000000000000000",
- "number": "0",
- "stateRoot": "0xa775801d572e9b79585eb131d18d79f8a0f71895455ab9a5b656911428e11708",
- "timestamp": "0",
- "totalDifficulty": "1",
- "alloc": {
- "0x3623191d4ccfbbdf09e8ebf6382a1f8257417bc1": {
- "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7"
- },
- "0xd15abca351f79181dedfb6d019e382db90f3628a": {
- "balance": "0x0"
- }
- },
- "config": {
- "chainId": 1337,
- "homesteadBlock": 0,
- "eip150Block": 0,
- "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "eip155Block": 0,
- "eip158Block": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 0,
- "petersburgBlock": 0,
- "istanbulBlock": 0,
- "muirGlacierBlock": 0,
- "berlinBlock": 0,
- "londonBlock": 0,
- "clique": {
- "period": 0,
- "epoch": 30000
- }
- }
- },
- "context": {
- "number": "1",
- "difficulty": "2",
- "timestamp": "1665537018",
- "gasLimit": "11511229",
- "miner": "0x0000000000000000000000000000000000000000"
- },
- "input": "0x02f9029d82053980849502f90085010c388d00832dc6c08080b90241608060405234801561001057600080fd5b50600060405161001f906100a2565b604051809103906000f08015801561003b573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c04062266040518163ffffffff1660e01b815260040160006040518083038186803b15801561008457600080fd5b505afa158015610098573d6000803e3d6000fd5b50505050506100af565b610145806100fc83390190565b603f806100bd6000396000f3fe6080604052600080fdfea264697066735822122077f7dbd3450d6e817079cf3fe27107de5768bb3163a402b94e2206b468eb025664736f6c63430008070033608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033c001a07566181071cabaf58b70fc41557eb813bfc7a24f5c58554e7fed0bf7c031f169a0420af50b5fe791a4d839e181a676db5250b415dfb35cb85d544db7a1475ae2cc",
- "result": {
- "from": "0x3623191d4ccfbbdf09e8ebf6382a1f8257417bc1",
- "gas": "0x2dc6c0",
- "gasUsed": "0x25590",
- "input": "0x608060405234801561001057600080fd5b50600060405161001f906100a2565b604051809103906000f08015801561003b573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c04062266040518163ffffffff1660e01b815260040160006040518083038186803b15801561008457600080fd5b505afa158015610098573d6000803e3d6000fd5b50505050506100af565b610145806100fc83390190565b603f806100bd6000396000f3fe6080604052600080fdfea264697066735822122077f7dbd3450d6e817079cf3fe27107de5768bb3163a402b94e2206b468eb025664736f6c63430008070033608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033",
- "output": "0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000012546869732063616c6c6564206661696c65640000000000000000000000000000",
- "error": "execution reverted",
- "revertReason": "This called failed",
- "calls": [
- {
- "from": "0xdebfb4b387033eac57af7b3de5116dd60056803b",
- "gas": "0x2ba851",
- "gasUsed": "0xe557",
- "to": "0xd15abca351f79181dedfb6d019e382db90f3628a",
- "input": "0x608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033",
- "output": "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033",
- "value": "0x0",
- "type": "CREATE"
- },
- {
- "from": "0xdebfb4b387033eac57af7b3de5116dd60056803b",
- "gas": "0x2ac548",
- "gasUsed": "0x1b2",
- "to": "0xd15abca351f79181dedfb6d019e382db90f3628a",
- "input": "0xc0406226",
- "output": "0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000012546869732063616c6c6564206661696c65640000000000000000000000000000",
- "error": "execution reverted",
- "revertReason": "This called failed",
- "type": "STATICCALL"
- }
- ],
- "value": "0x0",
- "type": "CREATE"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json
deleted file mode 100644
index a023ed6d9b..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json
+++ /dev/null
@@ -1,81 +0,0 @@
-{
- "context": {
- "difficulty": "3956606365",
- "gasLimit": "5413248",
- "miner": "0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d",
- "number": "2295104",
- "timestamp": "1513681256"
- },
- "genesis": {
- "alloc": {
- "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76": {
- "balance": "0x0",
- "code": "0x60606040526004361061015e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680625b4487146101a257806311df9995146101cb578063278ecde11461022057806330adce0e146102435780633197cbb61461026c5780634bb278f3146102955780636103d70b146102aa57806363a599a4146102bf5780636a2d1cb8146102d457806375f12b21146102fd57806378e979251461032a578063801db9cc1461035357806386d1a69f1461037c5780638da5cb5b146103915780638ef26a71146103e65780639890220b1461040f5780639b39caef14610424578063b85dfb801461044d578063be9a6555146104a1578063ccb07cef146104b6578063d06c91e4146104e3578063d669e1d414610538578063df40503c14610561578063e2982c2114610576578063f02e030d146105c3578063f2fde38b146105d8578063f3283fba14610611575b600060149054906101000a900460ff1615151561017a57600080fd5b60075442108061018b575060085442115b15151561019757600080fd5b6101a03361064a565b005b34156101ad57600080fd5b6101b5610925565b6040518082815260200191505060405180910390f35b34156101d657600080fd5b6101de61092b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561022b57600080fd5b6102416004808035906020019091905050610951565b005b341561024e57600080fd5b610256610c48565b6040518082815260200191505060405180910390f35b341561027757600080fd5b61027f610c4e565b6040518082815260200191505060405180910390f35b34156102a057600080fd5b6102a8610c54565b005b34156102b557600080fd5b6102bd610f3e565b005b34156102ca57600080fd5b6102d261105d565b005b34156102df57600080fd5b6102e76110d5565b6040518082815260200191505060405180910390f35b341561030857600080fd5b6103106110e1565b604051808215151515815260200191505060405180910390f35b341561033557600080fd5b61033d6110f4565b6040518082815260200191505060405180910390f35b341561035e57600080fd5b6103666110fa565b6040518082815260200191505060405180910390f35b341561038757600080fd5b61038f611104565b005b341561039c57600080fd5b6103a4611196565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f157600080fd5b6103f96111bb565b6040518082815260200191505060405180910390f35b341561041a57600080fd5b6104226111c1565b005b341561042f57600080fd5b610437611296565b6040518082815260200191505060405180910390f35b341561045857600080fd5b610484600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061129c565b604051808381526020018281526020019250505060405180910390f35b34156104ac57600080fd5b6104b46112c0565b005b34156104c157600080fd5b6104c9611341565b604051808215151515815260200191505060405180910390f35b34156104ee57600080fd5b6104f6611354565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561054357600080fd5b61054b61137a565b6040518082815260200191505060405180910390f35b341561056c57600080fd5b610574611385565b005b341561058157600080fd5b6105ad600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506116c3565b6040518082815260200191505060405180910390f35b34156105ce57600080fd5b6105d66116db565b005b34156105e357600080fd5b61060f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611829565b005b341561061c57600080fd5b610648600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118fe565b005b600080670de0b6b3a7640000341015151561066457600080fd5b61069b610696670de0b6b3a7640000610688610258346119d990919063ffffffff16565b611a0c90919063ffffffff16565b611a27565b9150660221b262dd80006106ba60065484611a7e90919063ffffffff16565b111515156106c757600080fd5b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156107d557600080fd5b6102c65a03f115156107e657600080fd5b5050506040518051905050610808828260010154611a7e90919063ffffffff16565b8160010181905550610827348260000154611a7e90919063ffffffff16565b816000018190555061084434600554611a7e90919063ffffffff16565b60058190555061085f82600654611a7e90919063ffffffff16565b6006819055503373ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c836040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e8583600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060085442108061096b5750651b48eb57e00060065410155b15151561097757600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154821415156109c757600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515610ac857600080fd5b6102c65a03f11515610ad957600080fd5b5050506040518051905050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68836000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610b7d57600080fd5b6102c65a03f11515610b8e57600080fd5b505050604051805190501515610ba357600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506000811115610c4457610c433382611a9c565b5b5050565b60055481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cb157600080fd5b600854421015610cd357660221b262dd8000600654141515610cd257600080fd5b5b651b48eb57e000600654108015610cf057506213c6806008540142105b151515610cfc57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501515610d7557600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610e3a57600080fd5b6102c65a03f11515610e4b57600080fd5b5050506040518051905090506000811115610f2057600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610ef957600080fd5b6102c65a03f11515610f0a57600080fd5b505050604051805190501515610f1f57600080fd5b5b6001600960006101000a81548160ff02191690831515021790555050565b600080339150600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114151515610f9657600080fd5b803073ffffffffffffffffffffffffffffffffffffffff163110151515610fbc57600080fd5b610fd181600254611b5090919063ffffffff16565b6002819055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561105957fe5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110b857600080fd5b6001600060146101000a81548160ff021916908315150217905550565b670de0b6b3a764000081565b600060149054906101000a900460ff1681565b60075481565b651b48eb57e00081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561115f57600080fd5b600060149054906101000a900460ff16151561117a57600080fd5b60008060146101000a81548160ff021916908315150217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561121c57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561129457600080fd5b565b61025881565b600a6020528060005260406000206000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561131b57600080fd5b600060075414151561132c57600080fd5b4260078190555062278d004201600881905550565b600960009054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b660221b262dd800081565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113e557600080fd5b600654660221b262dd800003925061142b670de0b6b3a764000061141c610258670de0b6b3a76400006119d990919063ffffffff16565b81151561142557fe5b04611a27565b915081831115151561143c57600080fd5b600a60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561158c57600080fd5b6102c65a03f1151561159d57600080fd5b50505060405180519050506115bf838260010154611a7e90919063ffffffff16565b81600101819055506115dc83600654611a7e90919063ffffffff16565b6006819055503073ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c846040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e856000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60016020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561173657600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f2fde38b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b151561181357600080fd5b6102c65a03f1151561182457600080fd5b505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415156118fb57806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561195957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561199557600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080828402905060008414806119fa57508284828115156119f757fe5b04145b1515611a0257fe5b8091505092915050565b6000808284811515611a1a57fe5b0490508091505092915050565b6000611a416202a300600754611a7e90919063ffffffff16565b421015611a7557611a6e611a5f600584611a0c90919063ffffffff16565b83611a7e90919063ffffffff16565b9050611a79565b8190505b919050565b6000808284019050838110151515611a9257fe5b8091505092915050565b611aee81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611a7e90919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b4681600254611a7e90919063ffffffff16565b6002819055505050565b6000828211151515611b5e57fe5b8183039050929150505600a165627a7a72305820ec0d82a406896ccf20989b3d6e650abe4dc104e400837f1f58e67ef499493ae90029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008d69d00910d0b2afb2a99ed6c16c8129fa8e1751",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000e819f024b41358d2c08e3a868a5c5dd0566078d4",
- "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000000000000000000000000000000000000005a388981",
- "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000005a3b38e6"
- }
- },
- "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826": {
- "balance": "0x2a2dd979a35cf000",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- },
- "0xe819f024b41358d2c08e3a868a5c5dd0566078d4": {
- "balance": "0x0",
- "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c681461027257806370a08231146102ad5780638da5cb5b146102fa57806395d89b411461034f578063a9059cbb146103dd578063dd62ed3e14610437578063f2fde38b146104a3575b600080fd5b34156100ca57600080fd5b6100d26104dc565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610515565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba61069c565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106a2565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610952565b6040518082815260200191505060405180910390f35b341561027d57600080fd5b6102936004808035906020019091905050610957565b604051808215151515815260200191505060405180910390f35b34156102b857600080fd5b6102e4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610abe565b6040518082815260200191505060405180910390f35b341561030557600080fd5b61030d610b07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561035a57600080fd5b610362610b2d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103e857600080fd5b61041d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b66565b604051808215151515815260200191505060405180910390f35b341561044257600080fd5b61048d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d01565b6040518082815260200191505060405180910390f35b34156104ae57600080fd5b6104da600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d88565b005b6040805190810160405280600b81526020017f416c6c436f6465436f696e00000000000000000000000000000000000000000081525081565b6000808214806105a157506000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15156105ac57600080fd5b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905061077683600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061080b83600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108618382610e7d90919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b600681565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109b557600080fd5b610a0782600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610a5f82600054610e7d90919063ffffffff16565b60008190555060003373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600481526020017f414c4c430000000000000000000000000000000000000000000000000000000081525081565b6000610bba82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c4f82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610de457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515610e5c5780600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000808284019050838110151515610e7357fe5b8091505092915050565b6000828211151515610e8b57fe5b8183039050929150505600a165627a7a7230582059f3ea3df0b054e9ab711f37969684ba83fe38f255ffe2c8d850d951121c51100029",
- "nonce": "1",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3956606365",
- "extraData": "0x566961425443",
- "gasLimit": "5418523",
- "hash": "0x6f37eb930a25da673ea1bb80fd9e32ddac19cdf7cd4bb2eac62cc13598624077",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "mixHash": "0x10971cde68c587c750c23b8589ae868ce82c2c646636b97e7d9856470c5297c7",
- "nonce": "0x810f923ff4b450a1",
- "number": "2295103",
- "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e",
- "timestamp": "1513681246",
- "totalDifficulty": "7162347056825919"
- },
- "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea",
- "result": {
- "calls": [
- {
- "error": "invalid opcode: INVALID",
- "from": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76",
- "gas": "0x75fe3",
- "gasUsed": "0x75fe3",
- "input": "0xa9059cbb000000000000000000000000d4fcab9f0a6dc0493af47c864f6f17a8a5e2e82600000000000000000000000000000000000000000000000000000000000002f4",
- "to": "0xe819f024b41358d2c08e3a868a5c5dd0566078d4",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "error": "execution reverted",
- "from": "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826",
- "gas": "0x7dfa6",
- "gasUsed": "0x7c1c8",
- "input": "0x",
- "to": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76",
- "type": "CALL",
- "value": "0xe92596fd6290000"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.md b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.md
deleted file mode 100644
index 2700578bd0..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.md
+++ /dev/null
@@ -1,19 +0,0 @@
-This test tests out the trace generated by the deployment of this contract:
-
-```solidity
-contract Revertor {
- function run() public pure {
- require(2 > 3, "This called failed");
- }
-}
-
-contract Contract {
- constructor() {
- Revertor r = new Revertor();
- r.run();
- }
-}
-```
-
-The trace should show a revert, with the revert reason for both the top-call as well
-as the inner call.
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json
deleted file mode 100644
index 333bdd038c..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
- "context": {
- "difficulty": "3699098917",
- "gasLimit": "5258985",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "number": "2294631",
- "timestamp": "1513675366"
- },
- "genesis": {
- "alloc": {
- "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62": {
- "balance": "0x0",
- "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c68146102785780635a3b7e42146102b357806370a082311461034157806379cc67901461038e57806395d89b41146103e8578063a9059cbb14610476578063dd62ed3e146104b8575b600080fd5b34156100ca57600080fd5b6100d2610524565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061055d565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba6105ea565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105f0565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610910565b604051808260ff1660ff16815260200191505060405180910390f35b341561028357600080fd5b6102996004808035906020019091905050610915565b604051808215151515815260200191505060405180910390f35b34156102be57600080fd5b6102c6610a18565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103065780820151818401526020810190506102eb565b50505050905090810190601f1680156103335780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a51565b6040518082815260200191505060405180910390f35b341561039957600080fd5b6103ce600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a69565b604051808215151515815260200191505060405180910390f35b34156103f357600080fd5b6103fb610bf8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561043b578082015181840152602081019050610420565b50505050905090810190601f1680156104685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561048157600080fd5b6104b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610c31565b005b34156104c357600080fd5b61050e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e34565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f446f70616d696e6500000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60005481565b6000808373ffffffffffffffffffffffffffffffffffffffff161415151561061757600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561066557600080fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101515156106f157fe5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561077c57600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561096557600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b6040805190810160405280600981526020017f446f706d6e20302e32000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b600081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ab957600080fd5b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610b4457600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b6040805190810160405280600581526020017f444f504d4e00000000000000000000000000000000000000000000000000000081525081565b60008273ffffffffffffffffffffffffffffffffffffffff1614151515610c5757600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ca557600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110151515610d3157fe5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60026020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058206d93424f4e7b11929b8276a269038402c10c0ddf21800e999916ddd9dff4a7630029",
- "nonce": "1",
- "storage": {
- "0x296b66049cc4f9c8bf3d4f14752add261d1a980b39bdd194a7897baf39ac7579": "0x0000000000000000000000000000000000000000033b2e3c9fc9653f9e72b1e0"
- }
- },
- "0x94194bc2aaf494501d7880b61274a169f6502a54": {
- "balance": "0xea8c39a876d19888d",
- "code": "0x",
- "nonce": "265",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3699098917",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "5263953",
- "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408",
- "nonce": "0xd1bdb150f6fd170e",
- "number": "2294630",
- "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1",
- "timestamp": "1513675347",
- "totalDifficulty": "7160543502214733"
- },
- "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956",
- "result": {
- "error": "out of gas",
- "from": "0x94194bc2aaf494501d7880b61274a169f6502a54",
- "gas": "0xca1d",
- "gasUsed": "0xca1d",
- "input": "0xa9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f9000",
- "to": "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json
deleted file mode 100644
index 3207a298a9..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "context": {
- "difficulty": "3665057456",
- "gasLimit": "5232723",
- "miner": "0xf4d8e706cfb25c0decbbdd4d2e2cc10c66376a3f",
- "number": "2294501",
- "timestamp": "1513673601"
- },
- "genesis": {
- "alloc": {
- "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9": {
- "balance": "0x2a3fc32bcc019283",
- "code": "0x",
- "nonce": "10",
- "storage": {}
- },
- "0xabbcd5b340c80b5f1c0545c04c987b87310296ae": {
- "balance": "0x0",
- "code": "0x606060405236156100755763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632d0335ab811461007a578063548db174146100ab5780637f649783146100fc578063b092145e1461014d578063c3f44c0a14610186578063c47cf5de14610203575b600080fd5b341561008557600080fd5b610099600160a060020a0360043516610270565b60405190815260200160405180910390f35b34156100b657600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061028f95505050505050565b005b341561010757600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061029e95505050505050565b005b341561015857600080fd5b610172600160a060020a03600435811690602435166102ad565b604051901515815260200160405180910390f35b341561019157600080fd5b6100fa6004803560ff1690602480359160443591606435600160a060020a0316919060a49060843590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965050509235600160a060020a031692506102cd915050565b005b341561020e57600080fd5b61025460046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061056a95505050505050565b604051600160a060020a03909116815260200160405180910390f35b600160a060020a0381166000908152602081905260409020545b919050565b61029a816000610594565b5b50565b61029a816001610594565b5b50565b600160209081526000928352604080842090915290825290205460ff1681565b60008080600160a060020a038416158061030d5750600160a060020a038085166000908152600160209081526040808320339094168352929052205460ff165b151561031857600080fd5b6103218561056a565b600160a060020a038116600090815260208190526040808220549295507f19000000000000000000000000000000000000000000000000000000000000009230918891908b908b90517fff000000000000000000000000000000000000000000000000000000000000008089168252871660018201526c01000000000000000000000000600160a060020a038088168202600284015286811682026016840152602a8301869052841602604a820152605e810182805190602001908083835b6020831061040057805182525b601f1990920191602091820191016103e0565b6001836020036101000a0380198251168184511617909252505050919091019850604097505050505050505051809103902091506001828a8a8a6040516000815260200160405260006040516020015260405193845260ff90921660208085019190915260408085019290925260608401929092526080909201915160208103908084039060008661646e5a03f1151561049957600080fd5b5050602060405103519050600160a060020a03838116908216146104bc57600080fd5b600160a060020a0380841660009081526020819052604090819020805460010190559087169086905180828051906020019080838360005b8381101561050d5780820151818401525b6020016104f4565b50505050905090810190601f16801561053a5780820380516001836020036101000a031916815260200191505b5091505060006040518083038160008661646e5a03f1915050151561055e57600080fd5b5b505050505050505050565b600060248251101561057e5750600061028a565b600160a060020a0360248301511690505b919050565b60005b825181101561060157600160a060020a033316600090815260016020526040812083918584815181106105c657fe5b90602001906020020151600160a060020a031681526020810191909152604001600020805460ff19169115159190911790555b600101610597565b5b5050505600a165627a7a723058200027e8b695e9d2dea9f3629519022a69f3a1d23055ce86406e686ea54f31ee9c0029",
- "nonce": "1",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3672229776",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "5227619",
- "hash": "0xa07b3d6c6bf63f5f981016db9f2d1d93033833f2c17e8bf7209e85f1faf08076",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x806e151ce2817be922e93e8d5921fa0f0d0fd213d6b2b9a3fa17458e74a163d0",
- "nonce": "0xbc5d43adc2c30c7d",
- "number": "2294500",
- "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d",
- "timestamp": "1513673552",
- "totalDifficulty": "7160066586979149"
- },
- "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a",
- "result": {
- "error": "execution reverted",
- "from": "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9",
- "gas": "0x2dc6c0",
- "gasUsed": "0x719b",
- "input": "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "to": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json
deleted file mode 100644
index f02e5c6863..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
- "context": {
- "difficulty": "2",
- "gasLimit": "8000000",
- "miner": "0x0000000000000000000000000000000000000000",
- "number": "3212651",
- "timestamp": "1597246515"
- },
- "genesis": {
- "alloc": {
- "0xf58833cf0c791881b494eb79d461e08a1f043f52": {
- "balance": "0x0",
- "code": "0x608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063609ff1bd11610078578063609ff1bd146101af5780639e7b8d61146101cd578063a3ec138d14610211578063e2ba53f0146102ae576100a5565b80630121b93f146100aa578063013cf08b146100d85780632e4176cf146101215780635c19a95c1461016b575b600080fd5b6100d6600480360360208110156100c057600080fd5b81019080803590602001909291905050506102cc565b005b610104600480360360208110156100ee57600080fd5b8101908080359060200190929190505050610469565b604051808381526020018281526020019250505060405180910390f35b61012961049a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ad6004803603602081101561018157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104bf565b005b6101b76108db565b6040518082815260200191505060405180910390f35b61020f600480360360208110156101e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610952565b005b6102536004803603602081101561022757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b53565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b6102b6610bb0565b6040518082815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561038a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f486173206e6f20726967687420746f20766f746500000000000000000000000081525060200191505060405180910390fd5b8060010160009054906101000a900460ff161561040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f416c726561647920766f7465642e00000000000000000000000000000000000081525060200191505060405180910390fd5b60018160010160006101000a81548160ff02191690831515021790555081816002018190555080600001546002838154811061044757fe5b9060005260206000209060020201600101600082825401925050819055505050565b6002818154811061047657fe5b90600052602060002090600202016000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff1615610587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f596f7520616c726561647920766f7465642e000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e000081525060200191505060405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107cc57600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f466f756e64206c6f6f7020696e2064656c65676174696f6e2e0000000000000081525060200191505060405180910390fd5b61062a565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156108bf578160000154600282600201548154811061089c57fe5b9060005260206000209060020201600101600082825401925050819055506108d6565b816000015481600001600082825401925050819055505b505050565b6000806000905060008090505b60028054905081101561094d57816002828154811061090357fe5b9060005260206000209060020201600101541115610940576002818154811061092857fe5b90600052602060002090600202016001015491508092505b80806001019150506108e8565b505090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180610bde6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f54686520766f74657220616c726561647920766f7465642e000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414610b0957600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610bbc6108db565b81548110610bc657fe5b90600052602060002090600202016000015490509056fe4f6e6c79206368616972706572736f6e2063616e206769766520726967687420746f20766f74652ea26469706673582212201d282819f8f06fed792100d60a8b08809b081a34a1ecd225e83a4b41122165ed64736f6c63430006060033",
- "nonce": "1",
- "storage": {
- "0x6200beec95762de01ce05f2a0e58ce3299dbb53c68c9f3254a242121223cdf58": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1": {
- "balance": "0x57af9d6b3df812900",
- "code": "0x",
- "nonce": "6",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 0,
- "constantinopleBlock": 0,
- "petersburgBlock": 0,
- "IstanbulBlock": 1561651,
- "chainId": 5,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294",
- "result": {
- "error": "execution reverted",
- "from": "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1",
- "gas": "0x2dc6c0",
- "gasUsed": "0x5940",
- "input": "0x5c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf1",
- "to": "0xf58833cf0c791881b494eb79d461e08a1f043f52",
- "type": "CALL",
- "value": "0x0",
- "output": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000",
- "revertReason": "Self-delegation is disallowed."
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json
deleted file mode 100644
index 620df1d614..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x61deadff",
- "nonce": "1",
- "storage": {}
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "result": {
- "calls": [
- {
- "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "gas": "0x0",
- "gasUsed": "0x0",
- "input": "0x",
- "to": "0x000000000000000000000000000000000000dead",
- "type": "SELFDESTRUCT",
- "value": "0x4d87094125a369d9bd5"
- }
- ],
- "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "gas": "0x15f90",
- "gasUsed": "0x6fcb",
- "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json
deleted file mode 100644
index 6c7d01de1f..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json
+++ /dev/null
@@ -1,80 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "result": {
- "calls": [
- {
- "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "gas": "0x6d05",
- "gasUsed": "0x0",
- "input": "0x",
- "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "type": "CALL",
- "value": "0x6f05b59d3b20000"
- }
- ],
- "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "gas": "0x15f90",
- "gasUsed": "0x9751",
- "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json b/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json
deleted file mode 100644
index affb4ab033..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json
+++ /dev/null
@@ -1,72 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "tracerConfig": {
- "onlyTopCall": true
- },
- "result": {
- "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "gas": "0x15f90",
- "gasUsed": "0x9751",
- "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json
deleted file mode 100644
index 499b449a6e..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json
+++ /dev/null
@@ -1,62 +0,0 @@
-{
- "context": {
- "difficulty": "117009631",
- "gasLimit": "4712388",
- "miner": "0x294e5d6c39a36ce38af1dca70c1060f78dee8070",
- "number": "25009",
- "timestamp": "1479891666"
- },
- "genesis": {
- "alloc": {
- "0x70c9217d814985faef62b124420f8dfbddd96433": {
- "balance": "0x4ecd70668f5d854a",
- "code": "0x",
- "nonce": "1638",
- "storage": {}
- },
- "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": {
- "balance": "0x0",
- "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000061a9",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433"
- }
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "117066792",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712388",
- "hash": "0xe23e8d4562a1045b70cbc99fefb20c101a8f0fc8559a80d65fea8896e2f1d46e",
- "miner": "0x71842f946b98800fe6feb49f0ae4e253259031c9",
- "mixHash": "0x0aada9d6e93dd4db0d09c0488dc0a048fca2ccdc1f3fc7b83ba2a8d393a3a4ff",
- "nonce": "0x70849d5838dee2e9",
- "number": "25008",
- "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b",
- "timestamp": "1479891641",
- "totalDifficulty": "1896347038589"
- },
- "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750",
- "result": {
- "error": "invalid jump destination",
- "from": "0x70c9217d814985faef62b124420f8dfbddd96433",
- "gas": "0x3d090",
- "gasUsed": "0x3d090",
- "input": "0x51a34eb8000000000000000000000000000000000000000000000027fad02094277c0000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json
deleted file mode 100644
index 617f52a14e..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- "genesis": {
- "difficulty": "50486697699375",
- "extraData": "0xd783010406844765746887676f312e362e32856c696e7578",
- "gasLimit": "4788482",
- "hash": "0xf6bbc5bbe34d5c93fd5b4712cd498d1026b8b0f586efefe7fe30231ed6b8a1a5",
- "miner": "0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1",
- "mixHash": "0xabca93555584c0463ee5c212251dd002bb3a93a157e06614276f93de53d4fdb8",
- "nonce": "0xa64136fcb9c2d4ca",
- "number": "1719576",
- "stateRoot": "0xab5eec2177a92d633e282936af66c46e24cfa8f2fdc2b8155f33885f483d06f3",
- "timestamp": "1466150166",
- "totalDifficulty": "28295412423546970038",
- "alloc": {
- "0xf8bda96b67036ee48107f2a0695ea673479dda56": {
- "balance": "0x1529e844f9ecdeec",
- "nonce": "33",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 1,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 3000000,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 1150000,
- "byzantiumBlock": 8772000,
- "constantinopleBlock": 9573000,
- "petersburgBlock": 10500839,
- "istanbulBlock": 10500839
- }
- },
- "context": {
- "number": "1719577",
- "difficulty": "50486697732143",
- "timestamp": "1466150178",
- "gasLimit": "4788484",
- "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
- },
- "input": "0xf874218504a817c800832318608080a35b620186a05a131560135760016020526000565b600080601f600039601f565b6000f31ba0575fa000a1f06659a7b6d3c7877601519a4997f04293f0dfa0eee6d8cd840c77a04c52ce50719ee2ff7a0c5753f4ee69c0340666f582dbb5148845a354ca726e4a",
- "result": [
- {
- "action": {
- "from": "0xf8bda96b67036ee48107f2a0695ea673479dda56",
- "gas": "0x231860",
- "init": "0x5b620186a05a131560135760016020526000565b600080601f600039601f565b6000f3",
- "value": "0x0"
- },
- "blockNumber": 1719577,
- "result": {
- "address": "0xb2e6a2546c45889427757171ab05b8b438525b42",
- "code": "0x",
- "gasUsed": "0x219202"
- },
- "subtraces": 0,
- "traceAddress": [],
- "type": "create"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json
deleted file mode 100644
index c796804a4b..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "genesis": {
- "difficulty": "4671584",
- "extraData": "0xd683010b05846765746886676f312e3133856c696e7578",
- "gasLimit": "9435026",
- "hash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "mixHash": "0x3a44525624571c31344ba57780f7664098fe7cbeafe532bcdee76a23fc474ba0",
- "nonce": "0x6dca647c00c72bbf",
- "number": "1555278",
- "stateRoot": "0x5f56d8323ee384b0c8d1de49d63e150e17283eea813483698362bc0ec9e0242a",
- "timestamp": "1590795319",
- "totalDifficulty": "2242614315030",
- "alloc": {
- "0x0000000000000000000000000000000000000004": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x62436e941792f02a5fb1",
- "nonce": "265356",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "1555279",
- "difficulty": "4669303",
- "timestamp": "1590795340",
- "gasLimit": "9444238",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf86f83040c8c843b9aca0083019f7880809b60206000600060006013600462030d40f26002556000516000550081a2a086ad228c89ad9664287b12a5602a635a803506904f4ce39795990ac4f945cd57a025b30ea8042d773f6c5b13d7cc1b3979f9f10ee674410b6a2112ce840d0302dc",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x19f78",
- "init": "0x60206000600060006013600462030d40f260025560005160005500"
- },
- "result": {
- "gasUsed": "0xf3bc",
- "code": "0x",
- "address": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224"
- },
- "traceAddress": [],
- "subtraces": 0,
- "transactionPosition": 74,
- "transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4",
- "blockNumber": 1555279,
- "blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46",
- "time": "209.346µs"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json
deleted file mode 100644
index fb29e49660..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json
+++ /dev/null
@@ -1,94 +0,0 @@
-{
- "genesis": {
- "difficulty": "4671584",
- "extraData": "0xd883010b05846765746888676f312e31342e33856c696e7578",
- "gasLimit": "9425823",
- "hash": "0x27dd7d052dbc8a29cc5b9487e1e41d842e7a643fcaea4964caa22b834964acaf",
- "miner": "0x73f26d124436b0791169d63a3af29c2ae47765a3",
- "mixHash": "0xb4a050624f5d147fdf02857cbfd55da3ddc1451743acc5c163861584589c3034",
- "nonce": "0x3c255875b17e0573",
- "number": "1555277",
- "stateRoot": "0x6290d79215a2eebc25d5e456b35876c6d78ffc1ea47bdd70e375ebb3cf325620",
- "timestamp": "1590795308",
- "totalDifficulty": "2242609643446",
- "alloc": {
- "0x0000000000000000000000000000000000000001": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x624329308610ab365fb1",
- "nonce": "265194",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "1555278",
- "difficulty": "4671584",
- "timestamp": "1590795319",
- "gasLimit": "9435026",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf8ee83040bea843b9aca008301a7588080b8997f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549606052602060806080600060006001610bb7f260025560a060020a6080510660005560005432146001550081a1a05b9a162d84bfe84faa7c176e21c26c0083645d4dd0d566547b7be2c2da0b4259a05b37ff12a4c27634cb0da6008d9b69726d415ff4694f9bc38c7806eb1fb60ae9",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x1a758",
- "init": "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549606052602060806080600060006001610bb7f260025560a060020a60805106600055600054321460015500"
- },
- "result": {
- "gasUsed": "0xf3e9",
- "code": "0x",
- "address": "0x568c19ecb14b87e4aec29b4d2d700a3ad3fd0613"
- },
- "traceAddress": [],
- "subtraces": 1,
- "transactionPosition": 141,
- "transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1",
- "blockNumber": 1555278,
- "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b",
- "time": "300.9µs"
- },
- {
- "type": "call",
- "action": {
- "from": "0x568c19ecb14b87e4aec29b4d2d700a3ad3fd0613",
- "to": "0x0000000000000000000000000000000000000001",
- "value": "0x0",
- "gas": "0xbb7",
- "input": "0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549",
- "callType": "callcode"
- },
- "error": "out of gas",
- "traceAddress": [
- 0
- ],
- "subtraces": 0,
- "transactionPosition": 141,
- "transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1",
- "blockNumber": 1555278,
- "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json
deleted file mode 100644
index 3c1e370f91..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json
+++ /dev/null
@@ -1,90 +0,0 @@
-{
- "genesis": {
- "difficulty": "4683014",
- "extraData": "0x537465762d63676574682d76312e31312e34",
- "gasLimit": "9435044",
- "hash": "0x3452ca5005cb73cd60dfa488a7b124251168e564491f80eb66765e79d78cfd95",
- "miner": "0x415aa6292d1db797a467b22139704956c030e62f",
- "mixHash": "0x6037612618507ae70c74a72bc2580253662971db959cfbc06d3f8527d4d01575",
- "nonce": "0x314fc90dee5e39a2",
- "number": "1555274",
- "stateRoot": "0x795751f3f96a5de1fd3944ddd78cbfe4ef10491e1086be47609869a30929d0e5",
- "timestamp": "1590795228",
- "totalDifficulty": "2242595605834",
- "alloc": {
- "0x0000000000000000000000000000000000000009": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x6242e3ccf48e66425fb1",
- "nonce": "264981",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "1555275",
- "difficulty": "4683014",
- "timestamp": "1590795244",
- "gasLimit": "9444256",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf87a83040b15843b9aca008301a0348080a636600060003760406103e8366000600060095af26001556103e851600255610408516003550081a1a0dd883fbbb489b640dadc8c1bf151767155228d0a1321f687f070f35f14374b05a02dd0ccb16a8de39bc8ee61381bbbbb54f0ab18422afd7b03c6163da1f5023934",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x1a034",
- "init": "0x36600060003760406103e8366000600060095af26001556103e8516002556104085160035500"
- },
- "error": "out of gas",
- "traceAddress": [],
- "subtraces": 1,
- "transactionPosition": 117,
- "transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9",
- "blockNumber": 1555275,
- "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd",
- "time": "332.877µs"
- },
- {
- "type": "call",
- "action": {
- "from": "0x8832ef498070145c3a5b30f47fbca71fd7b1de9f",
- "to": "0x0000000000000000000000000000000000000009",
- "value": "0x0",
- "gas": "0xc897",
- "input": "0x",
- "callType": "callcode"
- },
- "error": "invalid input length",
- "traceAddress": [
- 0
- ],
- "subtraces": 0,
- "transactionPosition": 117,
- "transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9",
- "blockNumber": 1555275,
- "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json
deleted file mode 100644
index 11bc4eae02..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json
+++ /dev/null
@@ -1,67 +0,0 @@
-{
- "context": {
- "difficulty": "3755480783",
- "gasLimit": "5401723",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "number": "2294702",
- "timestamp": "1513676146"
- },
- "genesis": {
- "alloc": {
- "0x13e4acefe6a6700604929946e70e6443e4e73447": {
- "balance": "0xcf3e0938579f000",
- "code": "0x",
- "nonce": "9",
- "storage": {}
- },
- "0x7dc9c9730689ff0b0fd506c67db815f12d90a448": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3757315409",
- "extraData": "0x566961425443",
- "gasLimit": "5406414",
- "hash": "0xae107f592eebdd9ff8d6ba00363676096e6afb0e1007a7d3d0af88173077378d",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "mixHash": "0xc927aa05a38bc3de864e95c33b3ae559d3f39c4ccd51cef6f113f9c50ba0caf1",
- "nonce": "0x93363bbd2c95f410",
- "number": "2294701",
- "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c",
- "timestamp": "1513676127",
- "totalDifficulty": "7160808139332585"
- },
- "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f",
- "result": [
- {
- "action": {
- "from": "0x13e4acefe6a6700604929946e70e6443e4e73447",
- "gas": "0x897be",
- "init": "0x606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a11",
- "value": "0x0"
- },
- "blockNumber": 2294702,
- "result": {
- "address": "0x7dc9c9730689ff0b0fd506c67db815f12d90a448",
- "code": "0x606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029",
- "gasUsed": "0x897be"
- },
- "subtraces": 0,
- "traceAddress": [],
- "type": "create"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json
deleted file mode 100644
index 375a163614..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json
+++ /dev/null
@@ -1,635 +0,0 @@
-{
- "context": {
- "difficulty": "117066904",
- "gasLimit": "4712384",
- "miner": "0x1977c248e1014cc103929dd7f154199c916e39ec",
- "number": "25001",
- "timestamp": "1479891545"
- },
- "genesis": {
- "alloc": {
- "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38": {
- "balance": "0x0",
- "code": "0x606060405236156100825760e060020a600035046302d05d3f811461008a5780630accce061461009c5780631ab9075a146100c757806331ed274614610102578063645a3b7214610133578063772fdae314610155578063a7f4377914610180578063ae5f80801461019e578063c9bded21146101ea578063f905c15a14610231575b61023a610002565b61023c600054600160a060020a031681565b61023a600435602435604435606435608435600254600160a060020a03166000141561024657610002565b61023a600435600254600160a060020a03166000148015906100f8575060025433600160a060020a03908116911614155b156102f457610002565b61023a60043560243560443560643560843560a43560c435600254600160a060020a03166000141561031657610002565b61023a600435602435600254600160a060020a0316600014156103d057610002565b61023a600435602435604435606435608435600254600160a060020a03166000141561046157610002565b61023a60025433600160a060020a0390811691161461051657610002565b61023a6004356024356044356060828152600160a060020a0382169060ff8516907fa6c2f0913db6f79ff0a4365762c61718973b3413d6e40382e704782a9a5099f690602090a3505050565b61023a600435602435600160a060020a038116606090815260ff8316907fee6348a7ec70f74e3d6cba55a53e9f9110d180d7698e9117fc466ae29a43e34790602090a25050565b61023c60035481565b005b6060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061029d57610002565b60408051858152602081018390528151600160a060020a03858116939087169260ff8a16927f5a690ecd0cb15c1c1fd6b6f8a32df0d4f56cb41a54fea7e94020f013595de796929181900390910190a45050505050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061036d57610002565b6040805186815260208101869052808201859052606081018490529051600160a060020a03831691889160ff8b16917fd65d9ddafbad8824e2bbd6f56cc9f4ac27ba60737035c10a321ea2f681c94d47919081900360800190a450505050505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061042757610002565b60408051828152905183917fa9c6cbc4bd352a6940479f6d802a1001550581858b310d7f68f7bea51218cda6919081900360200190a25050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104b857610002565b80600160a060020a031684600160a060020a03168660ff167f69bdaf789251e1d3a0151259c0c715315496a7404bce9fd0b714674685c2cab78686604051808381526020018281526020019250505060405180910390a45050505050565b600254600160a060020a0316ff",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0x2cccf5e0538493c235d1c5ef6580f77d99e91396": {
- "balance": "0x0",
- "code": "0x606060405236156100775760e060020a600035046302d05d3f811461007f57806313bc6d4b146100915780633688a877146100b95780635188f9961461012f5780637eadc976146101545780638ad79680146101d3578063a43e04d814610238578063a7f437791461025e578063e16c7d981461027c575b61029f610002565b6102a1600054600160a060020a031681565b6102be600435600160a060020a03811660009081526002602052604090205460ff165b919050565b6102d26004356040805160208181018352600080835284815260038252835190849020805460026001821615610100026000190190911604601f8101849004840283018401909552848252929390929183018282801561037d5780601f106103525761010080835404028352916020019161037d565b61029f6004356024356000805433600160a060020a039081169116146104a957610002565b61034060043560008181526001602090815260408083205481517ff905c15a0000000000000000000000000000000000000000000000000000000081529151600160a060020a03909116928392839263f905c15a92600483810193919291829003018189876161da5a03f1156100025750506040515195945050505050565b60408051602060248035600481810135601f810185900485028601850190965285855261029f9581359591946044949293909201918190840183828082843750949650505050505050600054600160a060020a0390811633909116146104f657610002565b61029f6004355b600080548190600160a060020a0390811633909116146105a457610002565b61029f60005433600160a060020a0390811691161461072957610002565b6102a1600435600081815260016020526040902054600160a060020a03166100b4565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103325780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b505050505090506100b4565b506000828152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a038581168086526002909352818520805460ff191690941790935580517f1ab9075a0000000000000000000000000000000000000000000000000000000081523090931660048401525184939192631ab9075a926024828101939192829003018183876161da5a03f11561000257505060408051602081018690528082019290925243606083015260808083526003908301527f414444000000000000000000000000000000000000000000000000000000000060a0830152517f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d39181900360c00190a15b505050565b600083815260016020526040902054600160a060020a03838116911614156104d0576104a4565b600083815260016020526040812054600160a060020a031614610389576103898361023f565b600082815260036020908152604082208054845182855293839020919360026001831615610100026000190190921691909104601f90810184900483019391929186019083901061056a57805160ff19168380011785555b5061059a9291505b808211156105a05760008155600101610556565b8280016001018555821561054e579182015b8281111561054e57825182600050559160200191906001019061057c565b50505050565b5090565b600083815260016020526040812054600160a060020a031614156105c757610002565b50506000818152600160205260408082205481517fa7f437790000000000000000000000000000000000000000000000000000000081529151600160a060020a0391909116928392839263a7f4377992600483810193919291829003018183876161da5a03f11561000257505050600160005060008460001916815260200190815260200160002060006101000a815490600160a060020a0302191690556002600050600083600160a060020a0316815260200190815260200160002060006101000a81549060ff02191690557f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d383834360405180806020018560001916815260200184600160a060020a03168152602001838152602001828103825260038152602001807f44454c000000000000000000000000000000000000000000000000000000000081526020015060200194505050505060405180910390a1505050565b600054600160a060020a0316ff",
- "nonce": "1",
- "storage": {
- "0x0684ac65a9fa32414dda56996f4183597d695987fdb82b145d722743891a6fe8": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "0x1cd76f78169a420d99346e3501dd3e541622c38a226f9b63e01cfebc69879dc7": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "0x8e54a4494fe5da016bfc01363f4f6cdc91013bb5434bd2a4a3359f13a23afa2f": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf",
- "0x94edf7f600ba56655fd65fca1f1424334ce369326c1dc3e53151dcd1ad06bc13": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xbbee47108b275f55f98482c6800f6372165e88b0330d3f5dae6419df4734366c": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "0xd38c0c4e84de118cfdcc775130155d83b8bbaaf23dc7f3c83a626b10473213bd": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xfb3aa5c655c2ec9d40609401f88d505d1da61afaa550e36ef5da0509ada257ba": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113"
- }
- },
- "0x3e9286eafa2db8101246c2131c09b49080d00690": {
- "balance": "0x0",
- "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063056d4470146100e957806316c66cc61461010c5780631ab9075a146101935780633ae1005c146101ce57806358541662146101fe5780635ed61af014610231578063644e3b791461025457806384dbac3b146102db578063949ae479146102fd5780639859387b14610321578063a7f4377914610340578063ab03fc261461035e578063e8161b7814610385578063e964d4e114610395578063f905c15a146103a5578063f92eb774146103ae575b6103be610002565b6103c0600054600160a060020a031681565b6103be6004356002546000908190600160a060020a031681141561040357610002565b6103dd60043560006108365b6040805160025460e360020a631c2d8fb30282527f636f6e747261637464620000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435600254600160a060020a03166000148015906101c4575060025433600160a060020a03908116911614155b1561088d57610002565b6103be600435602435604435606435600254600090819081908190600160a060020a03168114156108af57610002565b6103c0600435602435604435606435608435600254600090819081908190600160a060020a03168114156110e857610002565b6103be6004356002546000908190600160a060020a03168114156115ec57610002565b6103c06004356000611b635b6040805160025460e360020a631c2d8fb30282527f6d61726b6574646200000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435602435600254600160a060020a031660001415611bb557610002565b6103be600435602435600254600090600160a060020a0316811415611d2e57610002565b6103be600435600254600160a060020a031660001415611fc657610002565b6103be60025433600160a060020a0390811691161461207e57610002565b6103be600435602435604435600254600090600160a060020a031681141561208c57610002565b6103dd60043560006124b8610260565b6103c0600435600061250a610118565b6103f160035481565b6103f16004356000612561610260565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061046557610002565b8291506104e55b6040805160025460e360020a631c2d8fb30282527f63706f6f6c00000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f115610002575050604051519150505b90565b600160a060020a031663b2206e6d83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fb2206e6d0000000000000000000000000000000000000000000000000000000082526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f11561000257505060405151915061059b90506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f115610002575050506107355b6040805160025460e360020a631c2d8fb30282527f6c6f676d6772000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b50826120ee5b6040805160025460e360020a631c2d8fb30282527f6163636f756e7463746c0000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316630accce06600684600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150866040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050505050565b600160a060020a03166316c66cc6836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519150505b919050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061091157610002565b87935061091c610260565b600160a060020a031663bdbdb08685600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fbdbdb0860000000000000000000000000000000000000000000000000000000082526004820152602481018a905290516044808301935060209282900301816000876161da5a03f1156100025750506040515193506109ca90506106ba565b600160a060020a03166381982a7a8885876040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610a3661046c565b600160a060020a03166308636bdb85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517f08636bdb000000000000000000000000000000000000000000000000000000008252600482015260248101889052604481019290925251606482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919450600160a060020a03871692506314baa1b6916024828101926000929190829003018183876161da5a03f11561000257505050610b3561046c565b600160a060020a0316630a3b6ede85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038d16602482015290516044808301935060209282900301816000876161da5a03f115610002575050604051519150610bd590506106ba565b600160a060020a031663d5b205ce87838b6040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610c41610118565b600160a060020a031663988db79c888a6040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050610ca5610260565b600160a060020a031663f4f2821b896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610d6f5b6040805160025460e360020a631c2d8fb30282527f747261646564620000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316635f539d69896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610dc2610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928e9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610ec5610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928d9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610fc8610639565b600160a060020a031663645a3b7285600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151905061101e610260565b600160a060020a031663f92eb77488600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f115610002575050505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061114a57610002565b604051600254600160a060020a0316908a908a908a908a908a90611579806125b38339018087600160a060020a0316815260200186600160a060020a03168152602001856000191681526020018481526020018381526020018281526020019650505050505050604051809103906000f092506111c5610118565b600160a060020a031663b9858a288a856040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611229610260565b600160a060020a0316635188f99689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611288610260565b600160a060020a031663bdbdb08689896040518360e060020a0281526004018083600019168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750506040515192506112e590506106ba565b600160a060020a03166346d88e7d8a858a6040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506000604051808303816000876161da5a03f115610002575050506113516106ba565b600160a060020a03166381982a7a8a84866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050506113bd61046c565b600160a060020a0316632b58469689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f1156100025750505061141c61046c565b600160a060020a03166308636bdb8984866040518460e060020a028152600401808460001916815260200183815260200182600160a060020a0316815260200193505050506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919350600160a060020a03861692506314baa1b6916024828101926000929190829003018183876161da5a03f115610002575050506114d3610639565b6040805160e160020a630566670302815260016004820152602481018b9052600160a060020a0386811660448301528c811660648301526000608483018190529251931692630accce069260a480840193919291829003018183876161da5a03f11561000257505050611544610639565b600160a060020a031663645a3b728961155b610260565b600160a060020a031663f92eb7748c6040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448084019360009350829003018183876161da5a03f1156100025750939a9950505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061164e57610002565b82915061165961046c565b600160a060020a0316630a3b6ede83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f1156100025750506040515191506116f990506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f1156100025750505061179b6106ba565b600160a060020a031663d653078983600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517ff1ff78a0000000000000000000000000000000000000000000000000000000008252915191929163f1ff78a09160048181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f1156100025750505061189f610260565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506118f2610118565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050611945610639565b600160a060020a0316630accce06600484600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da44689181870191602091908190038801816000876161da5a03f115610002575050506040518051906020015060006040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050611a48610639565b600160a060020a031663645a3b7283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611a9e610260565b600160a060020a031663f92eb77486600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b600160a060020a03166381738c59836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611c1757610002565b611c1f610260565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060405151159050611c7457610002565b611c7c610260565b600160a060020a0316632243118a836040518260e060020a02815260040180826000191681526020019150506000604051808303816000876161da5a03f11561000257505050611cca610639565b600160a060020a031663ae5f8080600184846040518460e060020a028152600401808481526020018360001916815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611d9057610002565b5081611d9a610260565b600160a060020a031663581d5d6084846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505050611df5610639565b600160a060020a0316630accce06600283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630566670302825260048201949094526024810193909352600160a060020a038816604484015260006064840181905260848401819052905160a4808501949293509091829003018183876161da5a03f11561000257505050611eab610639565b600160a060020a031663645a3b7282600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611f01610260565b600160a060020a031663f92eb77485600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061202857610002565b612030610118565b600160a060020a0316639859387b826040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505050565b600254600160a060020a0316ff5b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f11561000257505060405151151590506106b457610002565b600160a060020a031663d65307898383600160a060020a031663f1ff78a06040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fd6530789000000000000000000000000000000000000000000000000000000008252600160a060020a039485166004830152602482015292891660448401525160648381019360009350829003018183876161da5a03f115610002575050506121a5610118565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506121f8610cf4565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505061224b610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d028252915191928a9290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f1156100025750505080600160a060020a031663ea71b02d6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a031660001490506124b25761239f610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fea71b02d000000000000000000000000000000000000000000000000000000008252915191928a92909163ea71b02d91600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f115610002575050505b50505050565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663213fe2b7836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663f92eb774836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f115610002575050604051519150610888905056606060405260405160c08061157983396101206040819052825160805160a051935160e0516101005160008054600160a060020a03199081163317909155600180546005805484168817905560048a90556006869055600b8590556008849055909116861760a060020a60ff02191690554360038190556002558686526101408390526101608190529396929594919390929091600160a060020a033016917f76885d242fb71c6f74a7e717416e42eff4d96faf54f6de75c6a0a6bbd8890c6b91a230600160a060020a03167fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff600b600050546040518082815260200191505060405180910390a250505050505061145e8061011b6000396000f3606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "16",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0x70c9217d814985faef62b124420f8dfbddd96433": {
- "balance": "0x4ef436dcbda6cd4a",
- "code": "0x",
- "nonce": "1634",
- "storage": {}
- },
- "0x7986bad81f4cbd9317f5a46861437dae58d69113": {
- "balance": "0x0",
- "code": "0x6060604052361561008d5760e060020a600035046302d05d3f811461009557806316c66cc6146100a75780631ab9075a146100d7578063213fe2b7146101125780639859387b1461013f578063988db79c1461015e578063a7f4377914610180578063b9858a281461019e578063c8e40fbf146101c0578063f4f2821b146101e8578063f905c15a14610209575b610212610002565b610214600054600160a060020a031681565b600160a060020a0360043581811660009081526005602052604081205461023193168114610257575060016101e3565b610212600435600254600160a060020a0316600014801590610108575060025433600160a060020a03908116911614155b1561025f57610002565b610214600435600160a060020a03811660009081526004602052604081205460ff16151561027557610002565b610212600435600254600160a060020a03166000141561029b57610002565b610212600435602435600254600160a060020a03166000141561050457610002565b61021260025433600160a060020a0390811691161461056757610002565b610212600435602435600254600160a060020a03166000141561057557610002565b610231600435600160a060020a03811660009081526004602052604090205460ff165b919050565b610212600435600254600090600160a060020a031681141561072057610002565b61024560035481565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060006101e3565b60028054600160a060020a031916821790555b50565b50600160a060020a038181166000908152600460205260409020546101009004166101e3565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506102fe57610002565b600160a060020a03811660009081526004602052604090205460ff161515610272576040516104028061092e833901809050604051809103906000f06004600050600083600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600083600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555050565b600160a060020a03821660009081526004602052604090205460ff1615156104725760405161040280610d30833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a03811660009081526006602052604090208054600160a060020a031916831790555b5050565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506103b957610002565b600254600160a060020a0316ff5b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506105d857610002565b600160a060020a03821660009081526004602052604090205460ff1615156106915760405161040280611132833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a031660009081526005602052604090208054600160a060020a0319169091179055565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f115610002575050604051511515905061078357610002565b50600160a060020a0381811660009081526005602090815260408083205490931680835260049091529190205460ff161561080f576040600081812054825160e260020a632e72bafd028152600160a060020a03868116600483015293516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260056020526040812054909116146108545760406000908120600160a060020a0384169091528054600160a060020a03191690555b50600160a060020a0381811660009081526006602090815260408083205490931680835260049091529190205460ff16156108e657600160a060020a038181166000908152604080518183205460e260020a632e72bafd028252868516600483015291516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260066020526040812054909116146105005760406000908120600160a060020a0384169091528054600160a060020a0319169055505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056",
- "nonce": "7",
- "storage": {
- "0xffc4df2d4f3d2cffad590bed6296406ab7926ca9e74784f74a95191fa069a174": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433"
- }
- },
- "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f": {
- "balance": "0x0",
- "code": "0x606060405236156100ae5760e060020a600035046302d05d3f81146100b65780631ab9075a146100c85780632b68bb2d146101035780634cc927d7146101c557806351a34eb81461028e57806356ccb6f0146103545780635928d37f1461041d578063599efa6b146104e9578063759297bb146105b2578063771d50e11461067e578063a7f4377914610740578063f905c15a1461075e578063f92eb77414610767578063febf661214610836575b610902610002565b610904600054600160a060020a031681565b610902600435600254600160a060020a03166000148015906100f9575060025433600160a060020a03908116911614155b1561092057610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061094257610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610a0d57610002565b61090260043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ae957610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610bbc57610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610c9657610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610de057610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ebb57610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f9e57610002565b61090260025433600160a060020a0390811691161461106957610002565b61090e60035481565b61090e60043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750506040805180517ff92eb774000000000000000000000000000000000000000000000000000000008252600482018790529151919350600160a060020a038416925063f92eb774916024828101926020929190829003018188876161da5a03f11561000257505060405151949350505050565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061107757610002565b005b6060908152602090f35b60408051918252519081900360200190f35b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5ed61af000000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152925190959286169350635ed61af092602483810193919291829003018183876161da5a03f115610002575050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fab03fc2600000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015260248301899052808816604484015292519095928616935063ab03fc2692606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f949ae47900000000000000000000000000000000000000000000000000000000825233600160a060020a0390811660048401526024830188905292519095928616935063949ae47992604483810193919291829003018183876161da5a03f11561000257505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f46d88e7d000000000000000000000000000000000000000000000000000000008252600160a060020a0380891660048401523381166024840152604483018890529251909592861693506346d88e7d92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5315cdde00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a16602484015260448301889052925190959286169350635315cdde92606483810193919291829003018183876161da5a03f115610002575050604080517f5928d37f00000000000000000000000000000000000000000000000000000000815233600160a060020a03908116600483015287166024820152604481018690529051635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fe68e401c00000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015280891660248401526044830188905292519095928616935063e68e401c92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5152f381000000000000000000000000000000000000000000000000000000008252600160a060020a03808a1660048401528089166024840152604483018890523381166064840152925190959286169350635152f38192608483810193919291829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f056d447000000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015292519095928616935063056d447092602483810193919291829003018183876161da5a03f115610002575050505050565b600254600160a060020a0316ff5b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f3ae1005c00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a166024840152808916604484015260648301889052925190959286169350633ae1005c92608483810193919291829003018183876161da5a03f11561000257505050505050505056",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": {
- "balance": "0x0",
- "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000006195",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000008ac7230489e80000",
- "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000"
- }
- },
- "0xcf00ffd997ad14939736f026006498e3f099baaf": {
- "balance": "0x0",
- "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063031e7f5d146100e95780631ab9075a1461010b5780632243118a1461014657806327aad68a1461016557806338a699a4146101da5780635188f996146101f8578063581d5d601461021e57806381738c5914610246578063977da54014610269578063a07421ce14610288578063a7f43779146102be578063bdbdb086146102dc578063e1c7111914610303578063f4f2821b14610325578063f905c15a1461034a578063f92eb77414610353575b610387610002565b610389600054600160a060020a031681565b610387600435602435600254600160a060020a0316600014156103a857610002565b610387600435600254600160a060020a031660001480159061013c575060025433600160a060020a03908116911614155b1561042957610002565b610387600435600254600160a060020a03166000141561044b57610002565b6102ac60043560008181526004602081815260408320547f524d81d3000000000000000000000000000000000000000000000000000000006060908152610100909104600160a060020a031692839263524d81d3926064928188876161da5a03f1156100025750506040515192506103819050565b61039c60043560008181526004602052604090205460ff165b919050565b6103876004356024356002546000908190600160a060020a031681141561079457610002565b61038760043560243560025460009081908190600160a060020a031681141561080457610002565b61038960043560008181526004602052604081205460ff1615156109e357610002565b610387600435600254600160a060020a0316600014156109fb57610002565b600435600090815260096020526040902054670de0b6b3a764000090810360243502045b60408051918252519081900360200190f35b61038760025433600160a060020a03908116911614610a9257610002565b600435600090815260086020526040902054670de0b6b3a7640000602435909102046102ac565b610387600435602435600254600160a060020a031660001415610aa057610002565b61038760043560025460009081908190600160a060020a0316811415610b3657610002565b6102ac60035481565b6102ac600435600081815260076020908152604080832054600690925290912054670de0b6b3a76400000204805b50919050565b005b600160a060020a03166060908152602090f35b15156060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506103fe57610002565b60008281526004602052604090205460ff16151561041b57610002565b600860205260406000205550565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104a157610002565b604080516000838152600460205291909120805460ff1916600117905561040280610de2833901809050604051809103906000f0600460005060008360001916815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555066470de4df8200006008600050600083600019168152602001908152602001600020600050819055506703782dace9d9000060096000506000836000191681526020019081526020016000206000508190555050565b600460005060008560001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151821415905061060057838152600660209081526040808320839055600790915281208190555b81600160a060020a0316630a3b0a4f846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050600160a060020a038316808252600560209081526040808420879055805160e160020a6364a81ff102815290518694670de0b6b3a7640000949363c9503fe29360048181019492939183900301908290876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008660001916815260200190815260200160002060008282825054019250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000866000191681526020019081526020016000206000828282505401925050819055505b50505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f11561000257505060405151151590506107e957610002565b8381526004602052604081205460ff16151561056657610002565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f115610002575050604051511515905061085957610002565b849250670de0b6b3a764000083600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575060408051805160e160020a6364a81ff102825291519189028590049650600481810192602092909190829003018188876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b9391600481810192602092909190829003018189876161da5a03f115610002575050506040518051906020015002049050806006600050600085600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750604080518051855260208681528286208054989098039097557f2e94420f00000000000000000000000000000000000000000000000000000000815290518896600483810193919291829003018187876161da5a03f115610002575050604080515183526020939093525020805490910190555050505050565b60409020546101009004600160a060020a03166101f3565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610a5157610002565b60008181526004602052604090205460ff161515610a6e57610002565b6040600020805474ffffffffffffffffffffffffffffffffffffffffff1916905550565b600254600160a060020a0316ff5b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610af657610002565b60008281526004602052604090205460ff161515610b1357610002565b670de0b6b3a7640000811115610b2857610002565b600960205260406000205550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f1156100025750506040515115159050610b8b57610002565b600160a060020a038416815260056020908152604080832054808452600490925282205490935060ff161515610bc057610002565b600460005060008460001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663b9caebf4856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506005600050600085600160a060020a0316815260200190815260200160002060005060009055839050600082600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519190911115905061078e57670de0b6b3a764000081600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008560001916815260200190815260200160002060008282825054039250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000856000191681526020019081526020016000206000828282505403925050819055505050505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056",
- "nonce": "3",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x3571d73f14f31a1463bd0a2f92f7fde1653d4e1ead7aedf4b0a5df02f16092ab": "0x0000000000000000000000000000000000000000000007d634e4c55188be0000",
- "0x4e64fe2d1b72d95a0a31945cc6e4f4e524ac5ad56d6bd44a85ec7bc9cc0462c0": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000"
- }
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "117124093",
- "extraData": "0xd5830105008650617269747986312e31322e31826d61",
- "gasLimit": "4707788",
- "hash": "0xad325e4c49145fb7a4058a68ac741cc8607a71114e23fc88083c7e881dd653e7",
- "miner": "0x00714b9ac97fd6bd9325a059a70c9b9fa94ce050",
- "mixHash": "0x0af918f65cb4af04b608fc1f14a849707696986a0e7049e97ef3981808bcc65f",
- "nonce": "0x38dee147326a8d40",
- "number": "25000",
- "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b",
- "timestamp": "1479891517",
- "totalDifficulty": "1895410389427"
- },
- "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0x70c9217d814985faef62b124420f8dfbddd96433",
- "gas": "0x3d090",
- "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 25001,
- "result": {
- "gasUsed": "0x1810b",
- "output": "0x"
- },
- "subtraces": 2,
- "traceAddress": [],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "gas": "0x31217",
- "input": "0xe16c7d98636f6e7472616374617069000000000000000000000000000000000000000000",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x334",
- "output": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f"
- },
- "subtraces": 0,
- "traceAddress": [0],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "gas": "0x30b4a",
- "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000",
- "to": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0xedb7",
- "output": "0x"
- },
- "subtraces": 4,
- "traceAddress": [1],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x2a68d",
- "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x334",
- "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690"
- },
- "subtraces": 0,
- "traceAddress": [1, 0],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x29f35",
- "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b",
- "to": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0xf8d",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 2,
- "traceAddress": [1, 1],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x23ac9",
- "input": "0xe16c7d98636f6e7472616374646200000000000000000000000000000000000000000000",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x334",
- "output": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113"
- },
- "subtraces": 0,
- "traceAddress": [1, 1, 0],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x23366",
- "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b",
- "to": "0x7986bad81f4cbd9317f5a46861437dae58d69113",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x273",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 0,
- "traceAddress": [1, 1, 1],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x28a9e",
- "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x334",
- "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690"
- },
- "subtraces": 0,
- "traceAddress": [1, 2],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x283b9",
- "input": "0x949ae479000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000",
- "to": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0xc51c",
- "output": "0x"
- },
- "subtraces": 12,
- "traceAddress": [1, 3],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x21d79",
- "input": "0x13bc6d4b000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x24d",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 0],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x2165b",
- "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x334",
- "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 1],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x20ee1",
- "input": "0x581d5d60000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000",
- "to": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x5374",
- "output": "0x"
- },
- "subtraces": 6,
- "traceAddress": [1, 3, 2],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1a8e8",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x24d",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 2, 0],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1a2c6",
- "input": "0xc9503fe2",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x3cb",
- "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 2, 1],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x19b72",
- "input": "0xc9503fe2",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x3cb",
- "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 2, 2],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x19428",
- "input": "0x6f265b93",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x305",
- "output": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 2, 3],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x18d45",
- "input": "0x2e94420f",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x229",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 2, 4],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1734e",
- "input": "0x2e94420f",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x229",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 2, 5],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1b6c1",
- "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x334",
- "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 3],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1af69",
- "input": "0x2e94420f",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x229",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 4],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1a91d",
- "input": "0x0accce0600000000000000000000000000000000000000000000000000000000000000025842545553440000000000000000000000000000000000000000000000000000000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x12fa",
- "output": "0x"
- },
- "subtraces": 1,
- "traceAddress": [1, 3, 5],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "gas": "0x143a5",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x24d",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 5, 0],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x19177",
- "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x334",
- "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 6],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x18a22",
- "input": "0x2e94420f",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x229",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 7],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x18341",
- "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x334",
- "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 8],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x17bec",
- "input": "0x2e94420f",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x229",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 9],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1764e",
- "input": "0xf92eb7745842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x45c",
- "output": "0x00000000000000000000000000000000000000000000002816d180e30c390000"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 10],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x16e62",
- "input": "0x645a3b72584254555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002816d180e30c390000",
- "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0xebb",
- "output": "0x"
- },
- "subtraces": 1,
- "traceAddress": [1, 3, 11],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "gas": "0x108ba",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x24d",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 0,
- "traceAddress": [1, 3, 11, 0],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json
deleted file mode 100644
index e5a37cbfdd..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json
+++ /dev/null
@@ -1,120 +0,0 @@
-{
- "context": {
- "difficulty": "31927752",
- "gasLimit": "4707788",
- "miner": "0x5659922ce141eedbc2733678f9806c77b4eebee8",
- "number": "11495",
- "timestamp": "1479735917"
- },
- "genesis": {
- "alloc": {
- "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff": {
- "balance": "0x0",
- "code": "0x606060405236156100825760e060020a60003504630a0313a981146100875780630a3b0a4f146101095780630cd40fea1461021257806329092d0e1461021f5780634cd06a5f146103295780635dbe47e8146103395780637a9e5410146103d9578063825db5f7146103e6578063a820b44d146103f3578063efa52fb31461047a575b610002565b34610002576104fc600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a26333556e849091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f415610002575050604051519150505b919050565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f21ce24d4000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926321ce24d49260448082019391829003018186803b156100025760325a03f415610002575050505b50565b3461000257610512600181565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f89489a87000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926389489a879260448082019391829003018186803b156100025760325a03f4156100025750505061020f565b3461000257610528600435610403565b34610002576104fc600435604080516000602091820181905282517f7d65837a00000000000000000000000000000000000000000000000000000000815260048101829052600160a060020a0385166024820152925190927342b02b5deeb78f34cd5ac896473b63e6c99a71a292637d65837a92604480840193829003018186803b156100025760325a03f4156100025750506040515191506101049050565b3461000257610512600c81565b3461000257610512600081565b3461000257610528600061055660005b600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263685a1f3c9091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b346100025761053a600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263f775b6b59091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b604080519115158252519081900360200190f35b005b6040805160ff9092168252519081900360200190f35b60408051918252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b90509056",
- "nonce": "1",
- "storage": {
- "0x4d140b25abf3c71052885c66f73ce07cff141c1afabffdaf5cba04d625b7ebcc": "0x0000000000000000000000000000000000000000000000000000000000000001"
- }
- },
- "0x269296dddce321a6bcbaa2f0181127593d732cba": {
- "balance": "0x0",
- "code": "0x606060405236156101275760e060020a60003504630cd40fea811461012c578063173825d9146101395780631849cb5a146101c7578063285791371461030f5780632a58b3301461033f5780632cb0d48a146103565780632f54bf6e1461036a578063332b9f061461039d5780633ca8b002146103c55780633df4ddf4146103d557806341c0e1b5146103f457806347799da81461040557806362a51eee1461042457806366907d13146104575780637065cb48146104825780637a9e541014610496578063825db5f7146104a3578063949d225d146104b0578063a51687df146104c7578063b4da4e37146104e6578063b4e6850b146104ff578063bd7474ca14610541578063e75623d814610541578063e9938e1114610555578063f5d241d314610643575b610002565b3461000257610682600181565b34610002576106986004356106ff335b60006001600a9054906101000a9004600160a060020a0316600160a060020a0316635dbe47e8836000604051602001526040518260e060020a0281526004018082600160a060020a03168152602001915050602060405180830381600087803b156100025760325a03f1156100025750506040515191506103989050565b3461000257604080516101008082018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a0360043581168752600586529589902089519788018a528054808816808a52605060020a91829004600160a060020a0316978a01889052600183015463ffffffff8082169d8c018e905264010000000082048116988c01899052604060020a90910416958a018690526002830154948a01859052600390920154808916938a01849052049096169690970186905293969495949293604080516001605060020a03998a16815297891660208901529590971686860152600160a060020a03909316606086015263ffffffff9182166080860152811660a08501521660c083015260e08201929092529051908190036101000190f35b346100025761069a60043560018054600091829160ff60f060020a909104161515141561063d5761072833610376565b34610002576106ae6004546001605060020a031681565b34610002576106986004356108b333610149565b346100025761069a6004355b600160a060020a03811660009081526002602052604090205460ff1615156001145b919050565b34610002576106986001805460ff60f060020a9091041615151415610913576108ed33610376565b346100025761069a600435610149565b34610002576106ae6003546001605060020a03605060020a9091041681565b346100025761069861091533610149565b34610002576106ae6003546001605060020a0360a060020a9091041681565b346100025761069a60043560243560018054600091829160ff60f060020a909104161515141561095e5761092633610376565b34610002576106986004356001805460ff60f060020a909104161515141561072557610a8b33610376565b3461000257610698600435610aa533610149565b3461000257610682600c81565b3461000257610682600081565b34610002576106ae6003546001605060020a031681565b34610002576106ca600154600160a060020a03605060020a9091041681565b346100025761069a60015460ff60f060020a9091041681565b346100025761069a60043560243560443560643560843560a43560c43560018054600091829160ff60f060020a9091041615151415610b5857610ad233610376565b3461000257610698600435610bd633610149565b34610002576106e6600435604080516101008181018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a03808b168752600586529589902089519788018a5280548088168952600160a060020a03605060020a918290041696890196909652600181015463ffffffff8082169b8a019b909b5264010000000081048b1695890195909552604060020a90940490981691860182905260028301549086015260039091015480841696850196909652940416918101919091525b50919050565b346100025761069a60043560243560443560643560843560a43560018054600091829160ff60f060020a9091041615151415610c8e57610bfb33610376565b6040805160ff9092168252519081900360200190f35b005b604080519115158252519081900360200190f35b604080516001605060020a039092168252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b6040805163ffffffff9092168252519081900360200190f35b1561012757600160a060020a0381166000908152600260205260409020805460ff191690555b50565b1561063d57506001605060020a0380831660009081526005602052604090208054909116151561075b576000915061063d565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610817905b8051600354600090819060016001605060020a0390911611610c995760038054605060020a60f060020a0319169055610ddf565b600380546001605060020a031981166000196001605060020a03928316011782558416600090815260056020526040812080547fffff000000000000000000000000000000000000000000000000000000000000168155600181810180546bffffffffffffffffffffffff191690556002820192909255909101805473ffffffffffffffffffffffffffffffffffffffff19169055915061063d565b1561012757600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a8302179055610725565b1561091357600480546001605060020a031981166001605060020a039091166001011790555b565b156101275733600160a060020a0316ff5b1561095e57506001605060020a03808416600090815260056020526040902080549091161515610965576000915061095e565b600191505b5092915050565b60038101546001605060020a0384811691161415610986576001915061095e565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610a12906107e3565b61095983825b80546003546001605060020a0391821691600091161515610de55760038054605060020a60a060020a031916605060020a84021760a060020a69ffffffffffffffffffff02191660a060020a84021781558301805473ffffffffffffffffffffffffffffffffffffffff19169055610ddf565b1561072557600480546001605060020a0319168217905550565b1561012757600160a060020a0381166000908152600260205260409020805460ff19166001179055610725565b15610b5857506001605060020a038088166000908152600560205260409020805490911615610b645760009150610b58565b6004546001605060020a0390811690891610610b3057600480546001605060020a03191660018a011790555b6003805460016001605060020a03821681016001605060020a03199092169190911790915591505b50979650505050505050565b80546001605060020a0319168817605060020a60f060020a031916605060020a880217815560018101805463ffffffff1916871767ffffffff0000000019166401000000008702176bffffffff00000000000000001916604060020a860217905560028101839055610b048982610a18565b156101275760018054605060020a60f060020a031916605060020a8302179055610725565b15610c8e57506001605060020a03808816600090815260056020526040902080549091161515610c2e5760009150610c8e565b8054605060020a60f060020a031916605060020a88021781556001808201805463ffffffff1916881767ffffffff0000000019166401000000008802176bffffffff00000000000000001916604060020a87021790556002820184905591505b509695505050505050565b6003546001605060020a03848116605060020a909204161415610d095760e084015160038054605060020a928302605060020a60a060020a031990911617808255919091046001605060020a031660009081526005602052604090200180546001605060020a0319169055610ddf565b6003546001605060020a0384811660a060020a909204161415610d825760c08401516003805460a060020a92830260a060020a69ffffffffffffffffffff021990911617808255919091046001605060020a03166000908152600560205260409020018054605060020a60a060020a0319169055610ddf565b505060c082015160e08301516001605060020a0380831660009081526005602052604080822060039081018054605060020a60a060020a031916605060020a8702179055928416825290200180546001605060020a031916831790555b50505050565b6001605060020a0384161515610e6457600380546001605060020a03605060020a9182900481166000908152600560205260409020830180546001605060020a0319908116871790915583548785018054918590049093168402605060020a60a060020a03199182161790911690915582549185029116179055610ddf565b506001605060020a038381166000908152600560205260409020600390810180549185018054605060020a60a060020a0319908116605060020a94859004909516808502959095176001605060020a0319168817909155815416918402919091179055801515610ef4576003805460a060020a69ffffffffffffffffffff02191660a060020a8402179055610ddf565b6003808401546001605060020a03605060020a9091041660009081526005602052604090200180546001605060020a031916831790555050505056",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000113204f5d64c28326fd7bd05fd4ea855302d7f2ff00000000000000000000"
- }
- },
- "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2": {
- "balance": "0x0",
- "code": "0x6504032353da7150606060405236156100695760e060020a60003504631bf7509d811461006e57806321ce24d41461008157806333556e84146100ec578063685a1f3c146101035780637d65837a1461011757806389489a8714610140578063f775b6b5146101fc575b610007565b61023460043560006100fd82600061010d565b610246600435602435600160a060020a03811660009081526020839052604081205415156102cb57826001016000508054806001018281815481835581811511610278576000838152602090206102789181019083015b808211156102d057600081556001016100d8565b610248600435602435600182015481105b92915050565b6102346004356024355b60018101906100fd565b610248600435602435600160a060020a03811660009081526020839052604090205415156100fd565b61024660043560243580600160a060020a031632600160a060020a03161415156101f857600160a060020a038116600090815260208390526040902054156101f857600160a060020a038116600090815260208390526040902054600183018054909160001901908110156100075760009182526020808320909101805473ffffffffffffffffffffffffffffffffffffffff19169055600160a060020a038316825283905260408120556002820180546000190190555b5050565b61025c60043560243560008260010160005082815481101561000757600091825260209091200154600160a060020a03169392505050565b60408051918252519081900360200190f35b005b604080519115158252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b50505060009283526020808420909201805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a0385168352908590526040909120819055600284018054600101905590505b505050565b509056",
- "nonce": "1",
- "storage": {}
- },
- "0xa529806c67cc6486d4d62024471772f47f6fd672": {
- "balance": "0x67820e39ac8fe9800",
- "code": "0x",
- "nonce": "68",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "31912170",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712388",
- "hash": "0x0855914bdc581bccdc62591fd438498386ffb59ea4d5361ed5c3702e26e2c72f",
- "miner": "0x334391aa808257952a462d1475562ee2106a6c90",
- "mixHash": "0x64bb70b8ca883cadb8fbbda2c70a861612407864089ed87b98e5de20acceada6",
- "nonce": "0x684129f283aaef18",
- "number": "11494",
- "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10",
- "timestamp": "1479735912",
- "totalDifficulty": "90744064339"
- },
- "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0xa529806c67cc6486d4d62024471772f47f6fd672",
- "gas": "0x2dc6c0",
- "input": "0x7065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e",
- "to": "0x269296dddce321a6bcbaa2f0181127593d732cba",
- "value": "0x0"
- },
- "blockNumber": 11495,
- "result": {
- "gasUsed": "0xbd55",
- "output": "0x"
- },
- "subtraces": 1,
- "traceAddress": [],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x269296dddce321a6bcbaa2f0181127593d732cba",
- "gas": "0x2cae73",
- "input": "0x5dbe47e8000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672",
- "to": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0xa9d",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 1,
- "traceAddress": [0],
- "type": "call"
- },
- {
- "action": {
- "callType": "delegatecall",
- "from": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff",
- "gas": "0x2bf459",
- "input": "0x7d65837a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672",
- "to": "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2",
- "value": "0x0"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x2aa",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 0,
- "traceAddress": [0, 0],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json
deleted file mode 100644
index 177912420a..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json
+++ /dev/null
@@ -1,103 +0,0 @@
-{
- "genesis": {
- "number": "566098",
- "hash": "0xba134562590a59291892395a29c5088899c2c64d720135dad88f7f076cf55f5f",
- "nonce": "0x4b281be9594e3eb3",
- "mixHash": "0xdb4ec386166d9c0dc9ba147755ecbb87af9f0a22563cbda02c799efa4e29db6e",
- "stateRoot": "0xfc01993ad96a8fb8790a093cea4f505f8db1b0e1143c5f57bb1d173db0baa9e3",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "difficulty": "1926740",
- "totalDifficulty": "482216286599",
- "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578",
- "gasLimit": "19388354",
- "timestamp": "1577558314",
- "alloc": {
- "0x6ab9dd83108698b9ca8d03af3c7eb91c0e54c3fc": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0xcbd5b9b25d1c38c2aad",
- "nonce": "134969",
- "code": "0x",
- "storage": {}
- },
- "0x91765918420bcb5ad22ee0997abed04056705798": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x366000803760206000366000736ab9dd83108698b9ca8d03af3c7eb91c0e54c3fc60325a03f41560015760206000f3",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "566099",
- "difficulty": "1927680",
- "timestamp": "1577558317",
- "gasLimit": "19369422",
- "miner": "0x774c398d763161f55b66a646f17edda4addad2ca"
- },
- "input": "0xf87983020f3985746a52880083015f909491765918420bcb5ad22ee0997abed04056705798888ac7230489e80000884e45375a4741394181a1a04b7260723fd02830754916b3bdf1537b6a851a7ae27c7e9296cfe1fc8275ec08a049d32158988eb717d61b4503b27c7583037c067daba1eb56f4bdfafc1b0045f6",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "gas": "0x15f90",
- "input": "0x4e45375a47413941",
- "to": "0x91765918420bcb5ad22ee0997abed04056705798",
- "value": "0x8ac7230489e80000"
- },
- "blockHash": "0xb05cc5c8f11df2b5d53ced342ee79e2805785f04c2f40add4539f27bd349f74e",
- "blockNumber": 566099,
- "result": {
- "gasUsed": "0x5721",
- "output": "0x4e45375a47413941000000000000000000000000000000000000000000000000"
- },
- "subtraces": 1,
- "traceAddress": [],
- "transactionHash": "0x6e26dffe2f66186f03a2c36a16a4cd9724d07622c83746f1e35f988515713d4b",
- "transactionPosition": 10,
- "type": "call"
- },
- {
- "action": {
- "callType": "delegatecall",
- "from": "0x91765918420bcb5ad22ee0997abed04056705798",
- "gas": "0x10463",
- "input": "0x4e45375a47413941",
- "to": "0x6ab9dd83108698b9ca8d03af3c7eb91c0e54c3fc",
- "value": "0x8ac7230489e80000"
- },
- "blockHash": "0xb05cc5c8f11df2b5d53ced342ee79e2805785f04c2f40add4539f27bd349f74e",
- "blockNumber": 566099,
- "result": {
- "gasUsed": "0x0",
- "output": "0x"
- },
- "subtraces": 0,
- "traceAddress": [
- 0
- ],
- "transactionHash": "0x6e26dffe2f66186f03a2c36a16a4cd9724d07622c83746f1e35f988515713d4b",
- "transactionPosition": 10,
- "type": "call"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json
deleted file mode 100644
index d977dbe30d..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json
+++ /dev/null
@@ -1,95 +0,0 @@
-{
- "genesis": {
- "difficulty": "4683014",
- "extraData": "0x537465762d63676574682d76312e31312e34",
- "gasLimit": "9435044",
- "hash": "0x3452ca5005cb73cd60dfa488a7b124251168e564491f80eb66765e79d78cfd95",
- "miner": "0x415aa6292d1db797a467b22139704956c030e62f",
- "mixHash": "0x6037612618507ae70c74a72bc2580253662971db959cfbc06d3f8527d4d01575",
- "nonce": "0x314fc90dee5e39a2",
- "number": "1555274",
- "stateRoot": "0x795751f3f96a5de1fd3944ddd78cbfe4ef10491e1086be47609869a30929d0e5",
- "timestamp": "1590795228",
- "totalDifficulty": "2242595605834",
- "alloc": {
- "0x0000000000000000000000000000000000000001": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x6242e3ccf48e66425fb1",
- "nonce": "264882",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "1555275",
- "difficulty": "4683014",
- "timestamp": "1590795244",
- "gasLimit": "9444256",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf9011583040ab2843b9aca008301a9c88080b8c0601b565b6000555b005b630badf00d6003565b63c001f00d6003565b7319e7e376e7c213b7e7e7e46cc70a5dd086daff2a7f22ae6da6b482f9b1b19b0b897c3fd43884180a1c5ee361e1107a1bc635649dda600052601b603f537f16433dce375ce6dc8151d3f0a22728bc4a1d9fd6ed39dfd18b4609331937367f6040527f306964c0cf5d74f04129fdc60b54d35b596dde1bf89ad92cb4123318f4c0e40060605260206080607f60006000600161fffff2156007576080511460125760095681a1a07682fc43dbe1fb13c6474f5e70e121c826dd996168d8bb1d8ca7a63470127b46a00a25b308ba417b7770899e8f98a3f0c14aa9bf7db0edacfe4e78d00dbbd3c31e",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x1a9c8",
- "init": "0x601b565b6000555b005b630badf00d6003565b63c001f00d6003565b7319e7e376e7c213b7e7e7e46cc70a5dd086daff2a7f22ae6da6b482f9b1b19b0b897c3fd43884180a1c5ee361e1107a1bc635649dda600052601b603f537f16433dce375ce6dc8151d3f0a22728bc4a1d9fd6ed39dfd18b4609331937367f6040527f306964c0cf5d74f04129fdc60b54d35b596dde1bf89ad92cb4123318f4c0e40060605260206080607f60006000600161fffff21560075760805114601257600956"
- },
- "result": {
- "gasUsed": "0x137e5",
- "code": "0x",
- "address": "0x1a05d76017ca02010533a470e05e8925a0380d8f"
- },
- "traceAddress": [],
- "subtraces": 1,
- "transactionPosition": 18,
- "transactionHash": "0xc1c42a325856d513523aec464811923b2e2926f54015c7ba37877064cf889803",
- "blockNumber": 1555275,
- "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd",
- "time": "453.925µs"
- },
- {
- "type": "call",
- "action": {
- "from": "0x1a05d76017ca02010533a470e05e8925a0380d8f",
- "to": "0x0000000000000000000000000000000000000001",
- "value": "0x0",
- "gas": "0xc8c6",
- "input": "0x22ae6da6b482f9b1b19b0b897c3fd43884180a1c5ee361e1107a1bc635649dda000000000000000000000000000000000000000000000000000000000000001b16433dce375ce6dc8151d3f0a22728bc4a1d9fd6ed39dfd18b4609331937367f306964c0cf5d74f04129fdc60b54d35b596dde1bf89ad92cb4123318f4c0e4",
- "callType": "callcode"
- },
- "result": {
- "gasUsed": "0xbb8",
- "output": "0x00000000000000000000000019e7e376e7c213b7e7e7e46cc70a5dd086daff2a"
- },
- "traceAddress": [0],
- "subtraces": 0,
- "transactionPosition": 18,
- "transactionHash": "0xc1c42a325856d513523aec464811923b2e2926f54015c7ba37877064cf889803",
- "blockNumber": 1555275,
- "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json
deleted file mode 100644
index 0f28c07a9b..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json
+++ /dev/null
@@ -1,832 +0,0 @@
-{
- "genesis": {
- "number": "559197",
- "hash": "0x0742a2bfab0452e2c634f3685b7e49ceb065c7000609b2b73f086e01fd1dfb58",
- "nonce": "0x3060ad521440e1c2",
- "mixHash": "0x59e7d4ae6cc3c38d23dac3f869b21984c7ba8f38070f4116a4941d9c403b6299",
- "stateRoot": "0x68418fb5cf4afa9b807dc079e8cdde0e148ac2c8afb378e675465b5bed1fbd02",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "difficulty": "1813945",
- "totalDifficulty": "469107641961",
- "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578",
- "gasLimit": "6321166",
- "timestamp": "1577471202",
- "alloc": {
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0xc5e6fdae52af83f7e28",
- "nonce": "77947",
- "code": "0x",
- "storage": {}
- },
- "0x774c398d763161f55b66a646f17edda4addad2ca": {
- "balance": "0xf09ef316eff819ee488",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x60006121df537c01000000000000000000000000000000000000000000000000000000006000350463b041b2858114156100d257600435604052780100000000000000000000000000000000000000000000000060606060599059016000905260038152604051816020015260008160400152809050205404606052606051151561008f57600060a052602060a0f35b604051601c604459905901600090520163e0e9a17b601c82035260605160048201526020610100602483600030602d5a03f1506101005190501460c052602060c0f35b632cce81aa81141561019957600435610120526001610120511280156100f85780610143565b78010000000000000000000000000000000000000000000000006060606059905901600090526003815266040000000000025481602001526000816040015280905020540461012051135b905015610157576000610180526020610180f35b601c604459905901600090520163e0e9a17b601c82035261012051600482015260206101c0602483600030602d5a03f1506101c05190506101a05260206101a0f35b63e0e9a17b8114156102e957600435610120526604000000000002546101e0526007610200525b610120517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540413156102da575b6102005160050a610120517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e051816020015260008160400152809050205404031215610269576000610200511361026c565b60005b1561028157600161020051036102005261020b565b7c01000000000000000000000000000000000000000000000000000000006102005160200260020a606060605990590160009052600381526101e05181602001526001816040015280905020540204546101e0526101c0565b6101e051610280526020610280f35b63cef887b08114156103e757365990590160009052366004823760043560208201016102c0526024356102e052506060601c61014c5990590160009052016390fa337d601c8203526102c0516020601f602083035101046020026020018360048401526020820360648401528060c8840152808401935050506102e051602482015233604482015281600401599059016000905260648160648460006004601cf161039057fe5b60648101925060c882015180808582606487015160006004600a8705601201f16103b657fe5b5080840193505080830360206103a08284600030602d5a03f1506103a0519050905090509050610300526020610300f35b6390fa337d81141561065f57365990590160009052366004823760043560208201016102c0526024356102e0526044356103e052505a610400526020601c608c599059016000905201632b861629601c8203526102c0516020601f6020830351010460200260200183600484015260208203602484015280604884015280840193505050816004015990590160009052602481602484600060046015f161048a57fe5b602481019250604882015180808582602487015160006004600a8705601201f16104b057fe5b5080840193505080830360206104408284600030602d5a03f15061044051905090509050905061042052610420511561065e576102c05160208103516020599059016000905260208183856000600287604801f150805190509050905061046052602059905901600090526020816020610460600060026068f1508051905060005b6020811215610552578181601f031a816105400153600181019050610532565b5050610540516101e0526102e0516c010000000000000000000000006103e0510217606060605990590160009052600381526101e05181602001526003816040015280905020555a61058052700100000000000000000000000000000000660400000000000154046105a0526104006105a0516103ff02056105c0526104006105a05161040102056105e0526105c0513a12156105f6576105c05161060052610615565b6105e0513a131561060e576105e05161060052610614565b3a610600525b5b6105805161040051036106005160020202610620526106205170010000000000000000000000000000000061060051021766040000000000015561042051610640526020610640f35b5b63d467ae0381141561073257600435604052602435610660526106605134121515610725576000341315610718576c01000000000000000000000000606060605990590160009052600381526040518160200152600381604001528090502054046103e0526000600060006000346103e051611388f115156106dd57fe5b601c60405990590160009052013481526103e0517f15e746bf513b8a58e4265cc1162d7fc445da5c9b1928d7cfcde2582735d4677f602083a2505b60016106a05260206106a0f35b60006106c05260206106c0f35b63ea4971ee811415610851576004356101e0526024356102e0526044356103e052601c606459905901600090520163d467ae03601c8203526101e05160048201526604000000000001546fffffffffffffffffffffffffffffffff16602482015260206106e060448334306123555a03f1506106e051905015156107bd576000610700526020610700f35b606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff166102e0511215610844576102e0516c010000000000000000000000006103e0510217606060605990590160009052600381526101e05181602001526003816040015280905020556001610760526020610760f35b6000610780526020610780f35b6387def0818114156108a3576004356101e0526c01000000000000000000000000606060605990590160009052600381526101e0518160200152600381604001528090502054046107a05260206107a0f35b630aece23c8114156108f4576004356101e052606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff166107e05260206107e0f35b63fa14df6b811415610926576604000000000001546fffffffffffffffffffffffffffffffff16610820526020610820f35b63b8c48f8c811415610b1b576004356101e0526024356108405260443561086052600066040000000000035414151561096a576000610880526020610880f3610976565b60016604000000000003555b6101e051660400000000000255606060605990590160009052600381526101e05181602001526000816040015280905020546108a0526108a0610840518060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a600783015350506108a051606060605990590160009052600381526101e0518160200152600081604001528090502055606060605990590160009052600381526101e051816020015260008160400152809050205461094052601061094001610860518060101a82538060111a60018301538060121a60028301538060131a60038301538060141a60048301538060151a60058301538060161a60068301538060171a60078301538060181a60088301538060191a600983015380601a1a600a83015380601b1a600b83015380601c1a600c83015380601d1a600d83015380601e1a600e83015380601f1a600f830153505061094051606060605990590160009052600381526101e051816020015260008160400152809050205560016109e05260206109e0f35b632b86162981141561179457365990590160009052366004823760043560208201016102c0525060483560005b6020811215610b68578181601f031a81610a600153600181019050610b48565b5050610a6051610a00526102c05160208103516020599059016000905260208183856000600287604801f1508051905090509050610a8052602059905901600090526020816020610a80600060026068f1508051905060005b6020811215610be1578181601f031a81610b600153600181019050610bc1565b5050610b60516101e05270010000000000000000000000000000000070010000000000000000000000000000000060606060599059016000905260038152610a005181602001526000816040015280905020540204610b8052610b80511515610c8b57601c602059905901600090520161272e6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610bc0526020610bc0f35b700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204610be0526000610be051141515610d2e57601c60205990590160009052016127386101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610c20526020610c20f35b608c35610c40526301000000610c405160031a0262010000610c405160021a02610100610c405160011a02610c405160001a010101610c60526301000000610c605104610ca05262ffffff610c605116610cc0526003610ca051036101000a610cc05102610c805260006101e0511315610db057610c80516101e05112610db3565b60005b1561174d57780100000000000000000000000000000000000000000000000060606060599059016000905260038152610a00518160200152600081604001528090502054046001016101205260806080599059016000905260038152610a005181602001526002816040015260008160600152809050206002810154610d405250610d405160081a610d405160091a61010002610d4051600a1a6201000002610d4051600b1a630100000002010101610d005260006107e0610120510614158015610e7e5780610e8b565b6001660400000000000054145b905015610f0257610d0051610c6051141515610eae576000610d00511415610eb1565b60005b15610efd57601c602059905901600090520161271a6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610da0526020610da0f35b6111b4565b6301000000610d005104610de05262ffffff610d005116610e00526003610de051036101000a610e005102610dc05260806080599059016000905260038152610a005181602001526002816040015260008160600152809050206002810154610e605250610e605160041a610e605160051a61010002610e605160061a6201000002610e605160071a630100000002010101610e2052601c604459905901600090520163e0e9a17b601c8203526107e0610120510360048201526020610ec0602483600030602d5a03f150610ec0519050610ea05260806080599059016000905260038152610ea05181602001526002816040015260008160600152809050206002810154610f205250610f205160041a610f205160051a61010002610f205160061a6201000002610f205160071a630100000002010101610ee052610ee051610e20510362049d408112156110595762049d4090505b6249d40081131561106b576249d40090505b62127500610dc0518202047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156110ba577bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90505b600860076000835b80156110d9576002810490506001820191506110c2565b5080905001046000600382131515611103578160030360080260020a62ffffff841602905061111a565b6003820360080260020a8304905062ffffff811690505b6280000081161561113357610100810490506001820191505b6301000000820281179050905090509050610f6052610f6051610c6051141515611164576000610f60511415611167565b60005b156111b357601c60205990590160009052016127246101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000611040526020611040f35b5b6101e0516101e0516101e05166040000000000005455606060605990590160009052600381526101e0518160200152600081604001528090502054611060526008611060016604000000000000548060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a6007830153505061106051606060605990590160009052600381526101e0518160200152600081604001528090502055600166040000000000005401660400000000000055606060605990590160009052600381526101e0518160200152600081604001528090502054611100526111006001780100000000000000000000000000000000000000000000000060606060599059016000905260038152610a0051816020015260008160400152809050205404018060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a6007830153505061110051606060605990590160009052600381526101e051816020015260008160400152809050205560006111c05278010000000000000000000000000000000000000000000000006801000000000000000060606060599059016000905260038152610a0051816020015260008160400152809050205402046111e0526111c06111e05180601c1a825380601d1a600183015380601e1a600283015380601f1a600383015350506001611260525b6008611260511215611515576112605160050a611280526001611280517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540407141561148757611260516004026111c0016111e05180601c1a825380601d1a600183015380601e1a600283015380601f1a60038301535050611505565b611260516004026111c0017c01000000000000000000000000000000000000000000000000000000006112605160200260020a60606060599059016000905260038152610a00518160200152600181604001528090502054020480601c1a825380601d1a600183015380601e1a600283015380601f1a600383015350505b60016112605101611260526113ec565b6111c051606060605990590160009052600381526101e05181602001526001816040015280905020555050608060805990590160009052600381526101e051816020015260028160400152600081606001528090502060005b600281121561159057806020026102c05101518282015560018101905061156e565b700100000000000000000000000000000000600003816020026102c051015116828201555050610c80517bffff0000000000000000000000000000000000000000000000000000056113e0526113e051610b805101610be052606060605990590160009052600381526101e051816020015260008160400152809050205461140052601061140001610be0518060101a82538060111a60018301538060121a60028301538060131a60038301538060141a60048301538060151a60058301538060161a60068301538060171a60078301538060181a60088301538060191a600983015380601a1a600a83015380601b1a600b83015380601c1a600c83015380601d1a600d83015380601e1a600e83015380601f1a600f830153505061140051606060605990590160009052600381526101e0518160200152600081604001528090502055660400000000000354610be051121515611703576101e051660400000000000255610be0516604000000000003555b601c6020599059016000905201610120516101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a350610120516114a05260206114a0f35b601c602059905901600090520161276a6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a35060006114c05260206114c0f35b630f5995ce8114156119a157365990590160009052366004823760043560208201016114e05260243561150052604435602082010161152052606435604052506114e05160208103516020599059016000905260208183856000600287604801f150805190509050905061156052602059905901600090526020816020611560600060026068f1508051905060005b6020811215611843578181601f031a816116400153600181019050611823565b50506116405161154052604060206114e051035114156118a457601c6020599059016000905201614e52611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a3506000611660526020611660f35b6080601c6101ac59905901600090520163bd136cb3601c8203526115405160048201526115005160248201526115205160208103516020026020018360448401526020820360c48401528061014884015280840193505050604051606482015281600401599059016000905260848160848460006004601ff161192357fe5b6084810192506101488201518080858260c487015160006004600a8705601201f161194a57fe5b508084019350508083036020611680828434306123555a03f15061168051905090509050905061042052600161042051141561199357611540516116a05260206116a0f36119a0565b60006116c05260206116c0f35b5b63bd136cb3811415611d8c573659905901600090523660048237600435611540526024356115005260443560208201016115205260643560405250601c606459905901600090520163d467ae03601c82035260405160048201526060606059905901600090526003815260405181602001526003816040015280905020546bffffffffffffffffffffffff166024820152602061170060448334306123555a03f1506117005190501515611a9757601c6020599059016000905201614e2a611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e2a611720526020611720f35b601c6044599059016000905201633d73b705601c82035260405160048201526020611740602483600030602d5a03f15061174051905015611b1a57601c6020599059016000905201614e34611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e34611760526020611760f35b601c604459905901600090520163b041b285601c82035260405160048201526020611780602483600030602d5a03f1506117805190501515611b9e57601c6020599059016000905201614e3e611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e3e6117a05260206117a0f35b6060601c61014c59905901600090520163b7129afb601c8203526115405160048201526115005160248201526115205160208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf1611c1557fe5b6064810192506101088201518080858260a487015160006004600a8705601201f1611c3c57fe5b5080840193505080830360206117e08284600030602d5a03f1506117e05190509050905090506117c0526080608059905901600090526003815260405181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006002820154046401000000006001830154020160005b6020811215611ce4578181601f031a816118a00153600181019050611cc4565b50506118a051905061180052611800516117c0511415611d4457601c60205990590160009052016001611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a35060016118c05260206118c0f35b601c6020599059016000905201614e48611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e486118e05260206118e0f35b63318a3fee81141561205657365990590160009052366004823760043560208201016114e0526024356115005260443560208201016115205260643560405260843561190052506080601c6101ac599059016000905201630f5995ce601c8203526114e0516020601f6020830351010460200260200183600484015260208203608484015280610108840152808401935050506115005160248201526115205160208103516020026020018360448401526020820360c48401528061014884015280840193505050604051606482015281600401599059016000905260848160848460006004601ff1611e7b57fe5b60848101925061010882015180808582608487015160006004600a8705601201f1611ea257fe5b508084019350506101488201518080858260c487015160006004600a8705601201f1611eca57fe5b508084019350508083036020611920828434306123555a03f15061192051905090509050905061154052600061154051141515612010576040601c60ec599059016000905201631c0b6367601c8203526114e0516020601f6020830351010460200260200183600484015260208203604484015280608884015280840193505050611540516024820152816004015990590160009052604481604484600060046018f1611f7357fe5b604481019250608882015180808582604487015160006004600a8705601201f1611f9957fe5b5080840193505080830360206119608284600061190051602d5a03f15061196051905090509050905061194052601c602059905901600090520161194051611540517f2d0d11d0f27e21fab56a8712078721096066b7faaa8540a3ea566e70b97de2d4600084a35061194051611980526020611980f35b601c602059905901600090520161753a60007f2d0d11d0f27e21fab56a8712078721096066b7faaa8540a3ea566e70b97de2d4600084a35061753a6119a05260206119a0f35b6309dd0e81811415612076576604000000000002546119c05260206119c0f35b63023948728114156120d2577801000000000000000000000000000000000000000000000000606060605990590160009052600381526604000000000002548160200152600081604001528090502054046119e05260206119e0f35b632c181929811415612139577001000000000000000000000000000000007001000000000000000000000000000000006060606059905901600090526003815266040000000000025481602001526000816040015280905020540204611a20526020611a20f35b637ca823d58114156122af576604000000000002546101e052700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204611a60526000611260525b600a61126051121561224c57608060805990590160009052600381526101e05181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006001820154046401000000008254020160005b6020811215612230578181601f031a81611b200153600181019050612210565b5050611b205190506101e05260016112605101611260526121a8565b700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204611b4052611b4051611a605103611b80526020611b80f35b63b7129afb81141561246a57365990590160009052366004823760043561154052602435611500526044356020820101611520525061154051611ba0526020611520510351611bc0526000611260525b611bc05161126051121561245b5761126051602002611520510151611be05260026115005107611c00526001611c0051141561234a57611be051611c2052611ba051611c4052612368565b6000611c0051141561236757611ba051611c2052611be051611c40525b5b60405990590160009052611c205160005b6020811215612399578181601f031a81611ca00153600181019050612379565b5050611ca0518152611c405160005b60208112156123c8578181601f031a81611d2001536001810190506123a8565b5050611d2051602082015260205990590160009052602081604084600060026088f15080519050611d4052602059905901600090526020816020611d40600060026068f1508051905060005b6020811215612434578181601f031a81611de00153600181019050612414565b5050611de0519050611ba052600261150051056115005260016112605101611260526122ff565b611ba051611e00526020611e00f35b633d73b70581141561255b576004356040526604000000000002546101e0526000611260525b600661126051121561254e576101e05160405114156124b6576001611e20526020611e20f35b608060805990590160009052600381526101e05181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006001820154046401000000008254020160005b6020811215612532578181601f031a81611ec00153600181019050612512565b5050611ec05190506101e0526001611260510161126052612490565b6000611ee0526020611ee0f35b631f794436811415612737576004356101e052601c606459905901600090520163d467ae03601c8203526101e0516004820152606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff1660248201526020611f2060448334306123555a03f150611f20519050151561265657601c602059905901600090520160006101e0517f60ab231f060fa320acea170017564b7ee77f477e6465a8c964380cffb270aaf4600084a350602159905901600090526001815260006020820152602081019050602060408203526020601f6020830351604001010460200260408203f3505b601c602059905901600090520160016101e0517f60ab231f060fa320acea170017564b7ee77f477e6465a8c964380cffb270aaf4600084a350608060805990590160009052600381526101e0518160200152600281604001526000816060015280905020607059905901600090526050815260208101905060005b60028112156126f05780830154816020028301526001810190506126d1565b70010000000000000000000000000000000060000381840154168160200283015281905090509050602060408203526020601f6020830351604001010460200260408203f3505b6313f955e18114156128ca573659905901600090523660048237600435602082010161204052602435612060525060506120805260006120a052612080516120c0526000611260525b612060516112605112156128bb576120a051806120c051038080602001599059016000905281815260208101905090508180828286612040510160006004600a8705601201f16127cc57fe5b50809050905090506120e0526020601c608c599059016000905201632b861629601c8203526120e0516020601f6020830351010460200260200183600484015260208203602484015280604884015280840193505050816004015990590160009052602481602484600060046015f161284157fe5b602481019250604882015180808582602487015160006004600a8705601201f161286757fe5b5080840193505080830360206121a08284600030602d5a03f1506121a051905090509050905061042052612080516120a051016120a052612080516120c051016120c0526001611260510161126052612780565b610420516121c05260206121c0f35b50",
- "storage": {
- "0x292b7a8d467a95cffd303c7edd99875892cdb3eaee87e5ca29057dc88a09ffbd": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x4d2fcf8ac901ad7dcf5b1c3979801430d9979c87157230ae066a0276984c6ac7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xdf951a5d1d9283b06d4f1de58542f1e1e310d8d17aada46586ddb9598bc42894": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x9c8d09d387f3ba5dd4733e24c63e4d549864a7cd57a1bdf1fdd831a2a0184815": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x4ab3b783bb170e11b0932a5ce8f5f343f67058b3925da271001a75ae498bd655": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x0000000000000000000000000000000000000004": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x0000000000000000000000000000000000000002": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "559198",
- "difficulty": "1814830",
- "timestamp": "1577471205",
- "gasLimit": "6327338",
- "miner": "0x774c398d763161f55b66a646f17edda4addad2ca"
- },
- "tracerConfig": {
- "includePrecompiles": true
- },
- "input": "0xf9026f8301307b85746a52880083124f80946cc68eb482a757c690dd151d2bd5e774ada38bdc80b9020413f955e100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000019004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae704000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30304000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e00000000000000000000000000000000081a1a01c9e9d742c8e69daba2a026ccafdde618f2e44c96db281c2209c22f183ad03a2a049a61d267d22226896d4c065525819c238784c439dc2afa7d17fce76595730d1",
- "result": [
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "gas": "0x124f80",
- "input": "0x13f955e100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000019004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae704000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30304000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x1c6ff",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 20,
- "traceAddress": [],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1a",
- "input": "0x04000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x18",
- "output": "0x04000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67"
- },
- "subtraces": 0,
- "traceAddress": [
- 0
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x15",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x15",
- "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020"
- },
- "subtraces": 0,
- "traceAddress": [
- 1
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1e",
- "input": "0x000000000000000000000000000000000000000000000000000000000000005004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a6700000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x1b",
- "output": "0x000000000000000000000000000000000000000000000000000000000000005004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a6700000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 2
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x114243",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a6700000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 2,
- "traceAddress": [
- 3
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x98",
- "input": "0x04000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x60",
- "output": "0xb099ea4048830027371dc31039920ae4fd19a641a7cbe57c198edd19d60f158a"
- },
- "subtraces": 0,
- "traceAddress": [
- 3,
- 0
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x68",
- "input": "0xb099ea4048830027371dc31039920ae4fd19a641a7cbe57c198edd19d60f158a",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x48",
- "output": "0x5b53875b0f1381589859adcf938980f4a8fb0af4c88450070000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 3,
- 1
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1a",
- "input": "0x040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae7",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x18",
- "output": "0x040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae7"
- },
- "subtraces": 0,
- "traceAddress": [
- 4
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x15",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x15",
- "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020"
- },
- "subtraces": 0,
- "traceAddress": [
- 5
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1e",
- "input": "0x0000000000000000000000000000000000000000000000000000000000000050040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae700000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x1b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000050040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae700000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 6
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x110d3b",
- "input": "0x2b86162900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000050040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae700000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 2,
- "traceAddress": [
- 7
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x98",
- "input": "0x040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae7",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x60",
- "output": "0xa0c6939b58a99b0d940f4435ab7db7d54d6b7786e68e00d9ff3890d69f95565d"
- },
- "subtraces": 0,
- "traceAddress": [
- 7,
- 0
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x68",
- "input": "0xa0c6939b58a99b0d940f4435ab7db7d54d6b7786e68e00d9ff3890d69f95565d",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x48",
- "output": "0xabbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 7,
- 1
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1a",
- "input": "0x04000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc303",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x18",
- "output": "0x04000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc303"
- },
- "subtraces": 0,
- "traceAddress": [
- 8
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x15",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x15",
- "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020"
- },
- "subtraces": 0,
- "traceAddress": [
- 9
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1e",
- "input": "0x000000000000000000000000000000000000000000000000000000000000005004000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30300000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x1b",
- "output": "0x000000000000000000000000000000000000000000000000000000000000005004000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30300000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 10
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x10d833",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30300000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 2,
- "traceAddress": [
- 11
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x98",
- "input": "0x04000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc303",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x60",
- "output": "0x6defff59ba277fa4511f8675ca98ca7d9c237c7433684490cf1ce09a9249e32f"
- },
- "subtraces": 0,
- "traceAddress": [
- 11,
- 0
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x68",
- "input": "0x6defff59ba277fa4511f8675ca98ca7d9c237c7433684490cf1ce09a9249e32f",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x48",
- "output": "0xe93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 11,
- 1
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1a",
- "input": "0x04000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x18",
- "output": "0x04000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de"
- },
- "subtraces": 0,
- "traceAddress": [
- 12
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x15",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x15",
- "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020"
- },
- "subtraces": 0,
- "traceAddress": [
- 13
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1e",
- "input": "0x000000000000000000000000000000000000000000000000000000000000005004000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de00000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x1b",
- "output": "0x000000000000000000000000000000000000000000000000000000000000005004000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de00000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 14
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x10a328",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de00000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 2,
- "traceAddress": [
- 15
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x98",
- "input": "0x04000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x60",
- "output": "0x996652142ffecd9cc272f376ca0e8228871a903772996289f847a6dbe2ce2698"
- },
- "subtraces": 0,
- "traceAddress": [
- 15,
- 0
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x68",
- "input": "0x996652142ffecd9cc272f376ca0e8228871a903772996289f847a6dbe2ce2698",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x48",
- "output": "0xf2e372a0b5b837116eee8f968840393d85975a15313468070000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 15,
- 1
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1a",
- "input": "0x04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e0",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x18",
- "output": "0x04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e0"
- },
- "subtraces": 0,
- "traceAddress": [
- 16
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x15",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x15",
- "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020"
- },
- "subtraces": 0,
- "traceAddress": [
- 17
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x1e",
- "input": "0x000000000000000000000000000000000000000000000000000000000000005004000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000004",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x1b",
- "output": "0x000000000000000000000000000000000000000000000000000000000000005004000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 18
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x106e1d",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 2,
- "traceAddress": [
- 19
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x98",
- "input": "0x04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e0",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x60",
- "output": "0xe57cf1c1d6132b9cfd9e90f54f907c038b47941b2a7f3800783af26e852ec116"
- },
- "subtraces": 0,
- "traceAddress": [
- 19,
- 0
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x68",
- "input": "0xe57cf1c1d6132b9cfd9e90f54f907c038b47941b2a7f3800783af26e852ec116",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x0000000000000000000000000000000000000002",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x48",
- "output": "0x8d5b6fafc6216500f9ef1ab16b30a59df9122d7de0f4910a0000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 19,
- 1
- ],
- "type": "call"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json
deleted file mode 100644
index 6c4ce18063..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json
+++ /dev/null
@@ -1,88 +0,0 @@
-{
- "context": {
- "difficulty": "3451177886",
- "gasLimit": "4709286",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2290744",
- "timestamp": "1513616439"
- },
- "genesis": {
- "alloc": {
- "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a": {
- "balance": "0x0",
- "code": "0x606060405263ffffffff60e060020a6000350416633b91f50681146100505780635bb47808146100715780635f51fca01461008c578063bc7647a9146100ad578063f1bd0d7a146100c8575b610000565b346100005761006f600160a060020a03600435811690602435166100e9565b005b346100005761006f600160a060020a0360043516610152565b005b346100005761006f600160a060020a036004358116906024351661019c565b005b346100005761006f600160a060020a03600435166101fa565b005b346100005761006f600160a060020a0360043581169060243516610db8565b005b600160a060020a038083166000908152602081905260408120549091908116903316811461011657610000565b839150600160a060020a038316151561012d573392505b6101378284610e2e565b6101418284610db8565b61014a826101fa565b5b5b50505050565b600154600160a060020a03908116903316811461016e57610000565b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0384161790555b5b5050565b600254600160a060020a0390811690331681146101b857610000565b600160a060020a038381166000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff19169184169190911790555b5b505050565b6040805160e260020a631a481fc102815260016024820181905260026044830152606482015262093a8060848201819052600060a4830181905260c06004840152601e60c48401527f736574456e7469747953746174757328616464726573732c75696e743829000060e484015292519091600160a060020a038516916369207f049161010480820192879290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526000602482018190526001604483015260606004830152602360648301527f626567696e506f6c6c28616464726573732c75696e7436342c626f6f6c2c626f60848301527f6f6c29000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f61646453746f636b28616464726573732c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f697373756553746f636b2875696e74382c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602160648301527f6772616e7453746f636b2875696e74382c75696e743235362c61646472657373608483015260f860020a60290260a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f115610000575050604080517f010555b8000000000000000000000000000000000000000000000000000000008152600160a060020a03338116602483015260006044830181905260606004840152603c60648401527f6772616e7456657374656453746f636b2875696e74382c75696e743235362c6160848401527f6464726573732c75696e7436342c75696e7436342c75696e743634290000000060a48401529251908716935063010555b89260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601260c48201527f626567696e53616c65286164647265737329000000000000000000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601a60648301527f7472616e7366657253616c6546756e64732875696e743235362900000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152602d60c48201527f7365744163636f756e74696e6753657474696e67732875696e743235362c756960e48201527f6e7436342c75696e7432353629000000000000000000000000000000000000006101048201529051600160a060020a03861692506369207f04916101248082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152603460648301527f637265617465526563757272696e6752657761726428616464726573732c756960848301527f6e743235362c75696e7436342c737472696e672900000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601b60648301527f72656d6f7665526563757272696e675265776172642875696e7429000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602360648301527f697373756552657761726428616464726573732c75696e743235362c7374726960848301527f6e6729000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f61737369676e53746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f72656d6f766553746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260026024808301919091526003604483015260006064830181905267ffffffffffffffff8616608484015260ff871660a484015260c0600484015260c48301919091527f7365744164647265737342796c617728737472696e672c616464726573732c6260e48301527f6f6f6c29000000000000000000000000000000000000000000000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152602160c48301527f73657453746174757342796c617728737472696e672c75696e74382c626f6f6c60e483015260f860020a6029026101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152603860c48301527f736574566f74696e6742796c617728737472696e672c75696e743235362c756960e48301527f6e743235362c626f6f6c2c75696e7436342c75696e74382900000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f115610000575050505b505050565b604080517f225553a4000000000000000000000000000000000000000000000000000000008152600160a060020a0383811660048301526002602483015291519184169163225553a49160448082019260009290919082900301818387803b156100005760325a03f115610000575050505b5050565b600082604051611fd280610f488339600160a060020a03909216910190815260405190819003602001906000f0801561000057905082600160a060020a03166308b027418260016040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b156100005760325a03f115610000575050604080517fa14e3ee300000000000000000000000000000000000000000000000000000000815260006004820181905260016024830152600160a060020a0386811660448401529251928716935063a14e3ee39260648084019382900301818387803b156100005760325a03f115610000575050505b5050505600606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029a165627a7a723058200e78a5f7e0f91739035d0fbf5eca02f79377210b722f63431f29a22e2880b3bd0029",
- "nonce": "789",
- "storage": {
- "0xfe9ec0542a1c009be8b1f3acf43af97100ffff42eb736850fb038fa1151ad4d9": "0x000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8"
- }
- },
- "0x5cb4a6b902fcb21588c86c3517e797b07cdaadb9": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- },
- "0xe4a13bc304682a903e9472f469c33801dd18d9e8": {
- "balance": "0x33c763c929f62c4f",
- "code": "0x",
- "nonce": "14",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3451177886",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4713874",
- "hash": "0x5d52a672417cd1269bf4f7095e25dcbf837747bba908cd5ef809dc1bd06144b5",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x01a12845ed546b94a038a7a03e8df8d7952024ed41ccb3db7a7ade4abc290ce1",
- "nonce": "0x28c446f1cb9748c1",
- "number": "2290743",
- "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708",
- "timestamp": "1513616414",
- "totalDifficulty": "7146523769022564"
- },
- "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0xe4a13bc304682a903e9472f469c33801dd18d9e8",
- "gas": "0x493e0",
- "input": "0x3b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8",
- "to": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a",
- "value": "0x0"
- },
- "blockNumber": 2290744,
- "error": "invalid jump destination",
- "result": {},
- "subtraces": 1,
- "traceAddress": [],
- "type": "call"
- },
- {
- "action": {
- "from": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a",
- "gas": "0x39ff0",
- "init": "0x606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182",
- "value": "0x0"
- },
- "blockNumber": 0,
- "error": "contract creation code storage out of gas",
- "result": {},
- "subtraces": 0,
- "traceAddress": [0],
- "type": "create"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json
deleted file mode 100644
index 4de08f2cca..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json
+++ /dev/null
@@ -1,72 +0,0 @@
-{
- "genesis": {
- "difficulty": "117067574",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712380",
- "hash": "0xe05db05eeb3f288041ecb10a787df121c0ed69499355716e17c307de313a4486",
- "miner": "0x0c062b329265c965deef1eede55183b3acb8f611",
- "mixHash": "0xb669ae39118a53d2c65fd3b1e1d3850dd3f8c6842030698ed846a2762d68b61d",
- "nonce": "0x2b469722b8e28c45",
- "number": "24973",
- "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369",
- "timestamp": "1479891145",
- "totalDifficulty": "1892250259406",
- "alloc": {
- "0x6c06b16512b332e6cd8293a2974872674716ce18": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d146036575b6000565b34600057604e60048080359060200190919050506050565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f19350505050505b5056",
- "storage": {}
- },
- "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31": {
- "balance": "0x229ebbb36c3e0f20",
- "nonce": "3",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 3,
- "homesteadBlock": 0,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "byzantiumBlock": 1700000,
- "constantinopleBlock": 4230000,
- "petersburgBlock": 4939394,
- "istanbulBlock": 6485846,
- "muirGlacierBlock": 7117117,
- "ethash": {}
- }
- },
- "context": {
- "number": "24974",
- "difficulty": "117067574",
- "timestamp": "1479891162",
- "gasLimit": "4712388",
- "miner": "0xc822ef32e6d26e170b70cf761e204c1806265914"
- },
- "input": "0xf889038504a81557008301f97e946c06b16512b332e6cd8293a2974872674716ce1880a42e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b1600002aa0e2a6558040c5d72bc59f2fb62a38993a314c849cd22fb393018d2c5af3112095a01bdb6d7ba32263ccc2ecc880d38c49d9f0c5a72d8b7908e3122b31356d349745",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
- "gas": "0x1f97e",
- "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000",
- "to": "0x6c06b16512b332e6cd8293a2974872674716ce18",
- "value": "0x0"
- },
- "blockNumber": 24974,
- "result": {
- "gasUsed": "0x72de",
- "output": "0x"
- },
- "subtraces": 0,
- "traceAddress": [],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json
deleted file mode 100644
index 70442fdb9a..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json
+++ /dev/null
@@ -1,219 +0,0 @@
-{
- "genesis": {
- "number": "559197",
- "hash": "0x0742a2bfab0452e2c634f3685b7e49ceb065c7000609b2b73f086e01fd1dfb58",
- "nonce": "0x3060ad521440e1c2",
- "mixHash": "0x59e7d4ae6cc3c38d23dac3f869b21984c7ba8f38070f4116a4941d9c403b6299",
- "stateRoot": "0x68418fb5cf4afa9b807dc079e8cdde0e148ac2c8afb378e675465b5bed1fbd02",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "difficulty": "1813945",
- "totalDifficulty": "469107641961",
- "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578",
- "gasLimit": "6321166",
- "timestamp": "1577471202",
- "alloc": {
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0xc5e6fdae52af83f7e28",
- "nonce": "77947",
- "code": "0x",
- "storage": {}
- },
- "0x774c398d763161f55b66a646f17edda4addad2ca": {
- "balance": "0xf09ef316eff819ee488",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x60006121df537c01000000000000000000000000000000000000000000000000000000006000350463b041b2858114156100d257600435604052780100000000000000000000000000000000000000000000000060606060599059016000905260038152604051816020015260008160400152809050205404606052606051151561008f57600060a052602060a0f35b604051601c604459905901600090520163e0e9a17b601c82035260605160048201526020610100602483600030602d5a03f1506101005190501460c052602060c0f35b632cce81aa81141561019957600435610120526001610120511280156100f85780610143565b78010000000000000000000000000000000000000000000000006060606059905901600090526003815266040000000000025481602001526000816040015280905020540461012051135b905015610157576000610180526020610180f35b601c604459905901600090520163e0e9a17b601c82035261012051600482015260206101c0602483600030602d5a03f1506101c05190506101a05260206101a0f35b63e0e9a17b8114156102e957600435610120526604000000000002546101e0526007610200525b610120517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540413156102da575b6102005160050a610120517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e051816020015260008160400152809050205404031215610269576000610200511361026c565b60005b1561028157600161020051036102005261020b565b7c01000000000000000000000000000000000000000000000000000000006102005160200260020a606060605990590160009052600381526101e05181602001526001816040015280905020540204546101e0526101c0565b6101e051610280526020610280f35b63cef887b08114156103e757365990590160009052366004823760043560208201016102c0526024356102e052506060601c61014c5990590160009052016390fa337d601c8203526102c0516020601f602083035101046020026020018360048401526020820360648401528060c8840152808401935050506102e051602482015233604482015281600401599059016000905260648160648460006004601cf161039057fe5b60648101925060c882015180808582606487015160006004600a8705601201f16103b657fe5b5080840193505080830360206103a08284600030602d5a03f1506103a0519050905090509050610300526020610300f35b6390fa337d81141561065f57365990590160009052366004823760043560208201016102c0526024356102e0526044356103e052505a610400526020601c608c599059016000905201632b861629601c8203526102c0516020601f6020830351010460200260200183600484015260208203602484015280604884015280840193505050816004015990590160009052602481602484600060046015f161048a57fe5b602481019250604882015180808582602487015160006004600a8705601201f16104b057fe5b5080840193505080830360206104408284600030602d5a03f15061044051905090509050905061042052610420511561065e576102c05160208103516020599059016000905260208183856000600287604801f150805190509050905061046052602059905901600090526020816020610460600060026068f1508051905060005b6020811215610552578181601f031a816105400153600181019050610532565b5050610540516101e0526102e0516c010000000000000000000000006103e0510217606060605990590160009052600381526101e05181602001526003816040015280905020555a61058052700100000000000000000000000000000000660400000000000154046105a0526104006105a0516103ff02056105c0526104006105a05161040102056105e0526105c0513a12156105f6576105c05161060052610615565b6105e0513a131561060e576105e05161060052610614565b3a610600525b5b6105805161040051036106005160020202610620526106205170010000000000000000000000000000000061060051021766040000000000015561042051610640526020610640f35b5b63d467ae0381141561073257600435604052602435610660526106605134121515610725576000341315610718576c01000000000000000000000000606060605990590160009052600381526040518160200152600381604001528090502054046103e0526000600060006000346103e051611388f115156106dd57fe5b601c60405990590160009052013481526103e0517f15e746bf513b8a58e4265cc1162d7fc445da5c9b1928d7cfcde2582735d4677f602083a2505b60016106a05260206106a0f35b60006106c05260206106c0f35b63ea4971ee811415610851576004356101e0526024356102e0526044356103e052601c606459905901600090520163d467ae03601c8203526101e05160048201526604000000000001546fffffffffffffffffffffffffffffffff16602482015260206106e060448334306123555a03f1506106e051905015156107bd576000610700526020610700f35b606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff166102e0511215610844576102e0516c010000000000000000000000006103e0510217606060605990590160009052600381526101e05181602001526003816040015280905020556001610760526020610760f35b6000610780526020610780f35b6387def0818114156108a3576004356101e0526c01000000000000000000000000606060605990590160009052600381526101e0518160200152600381604001528090502054046107a05260206107a0f35b630aece23c8114156108f4576004356101e052606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff166107e05260206107e0f35b63fa14df6b811415610926576604000000000001546fffffffffffffffffffffffffffffffff16610820526020610820f35b63b8c48f8c811415610b1b576004356101e0526024356108405260443561086052600066040000000000035414151561096a576000610880526020610880f3610976565b60016604000000000003555b6101e051660400000000000255606060605990590160009052600381526101e05181602001526000816040015280905020546108a0526108a0610840518060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a600783015350506108a051606060605990590160009052600381526101e0518160200152600081604001528090502055606060605990590160009052600381526101e051816020015260008160400152809050205461094052601061094001610860518060101a82538060111a60018301538060121a60028301538060131a60038301538060141a60048301538060151a60058301538060161a60068301538060171a60078301538060181a60088301538060191a600983015380601a1a600a83015380601b1a600b83015380601c1a600c83015380601d1a600d83015380601e1a600e83015380601f1a600f830153505061094051606060605990590160009052600381526101e051816020015260008160400152809050205560016109e05260206109e0f35b632b86162981141561179457365990590160009052366004823760043560208201016102c0525060483560005b6020811215610b68578181601f031a81610a600153600181019050610b48565b5050610a6051610a00526102c05160208103516020599059016000905260208183856000600287604801f1508051905090509050610a8052602059905901600090526020816020610a80600060026068f1508051905060005b6020811215610be1578181601f031a81610b600153600181019050610bc1565b5050610b60516101e05270010000000000000000000000000000000070010000000000000000000000000000000060606060599059016000905260038152610a005181602001526000816040015280905020540204610b8052610b80511515610c8b57601c602059905901600090520161272e6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610bc0526020610bc0f35b700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204610be0526000610be051141515610d2e57601c60205990590160009052016127386101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610c20526020610c20f35b608c35610c40526301000000610c405160031a0262010000610c405160021a02610100610c405160011a02610c405160001a010101610c60526301000000610c605104610ca05262ffffff610c605116610cc0526003610ca051036101000a610cc05102610c805260006101e0511315610db057610c80516101e05112610db3565b60005b1561174d57780100000000000000000000000000000000000000000000000060606060599059016000905260038152610a00518160200152600081604001528090502054046001016101205260806080599059016000905260038152610a005181602001526002816040015260008160600152809050206002810154610d405250610d405160081a610d405160091a61010002610d4051600a1a6201000002610d4051600b1a630100000002010101610d005260006107e0610120510614158015610e7e5780610e8b565b6001660400000000000054145b905015610f0257610d0051610c6051141515610eae576000610d00511415610eb1565b60005b15610efd57601c602059905901600090520161271a6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610da0526020610da0f35b6111b4565b6301000000610d005104610de05262ffffff610d005116610e00526003610de051036101000a610e005102610dc05260806080599059016000905260038152610a005181602001526002816040015260008160600152809050206002810154610e605250610e605160041a610e605160051a61010002610e605160061a6201000002610e605160071a630100000002010101610e2052601c604459905901600090520163e0e9a17b601c8203526107e0610120510360048201526020610ec0602483600030602d5a03f150610ec0519050610ea05260806080599059016000905260038152610ea05181602001526002816040015260008160600152809050206002810154610f205250610f205160041a610f205160051a61010002610f205160061a6201000002610f205160071a630100000002010101610ee052610ee051610e20510362049d408112156110595762049d4090505b6249d40081131561106b576249d40090505b62127500610dc0518202047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156110ba577bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90505b600860076000835b80156110d9576002810490506001820191506110c2565b5080905001046000600382131515611103578160030360080260020a62ffffff841602905061111a565b6003820360080260020a8304905062ffffff811690505b6280000081161561113357610100810490506001820191505b6301000000820281179050905090509050610f6052610f6051610c6051141515611164576000610f60511415611167565b60005b156111b357601c60205990590160009052016127246101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000611040526020611040f35b5b6101e0516101e0516101e05166040000000000005455606060605990590160009052600381526101e0518160200152600081604001528090502054611060526008611060016604000000000000548060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a6007830153505061106051606060605990590160009052600381526101e0518160200152600081604001528090502055600166040000000000005401660400000000000055606060605990590160009052600381526101e0518160200152600081604001528090502054611100526111006001780100000000000000000000000000000000000000000000000060606060599059016000905260038152610a0051816020015260008160400152809050205404018060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a6007830153505061110051606060605990590160009052600381526101e051816020015260008160400152809050205560006111c05278010000000000000000000000000000000000000000000000006801000000000000000060606060599059016000905260038152610a0051816020015260008160400152809050205402046111e0526111c06111e05180601c1a825380601d1a600183015380601e1a600283015380601f1a600383015350506001611260525b6008611260511215611515576112605160050a611280526001611280517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540407141561148757611260516004026111c0016111e05180601c1a825380601d1a600183015380601e1a600283015380601f1a60038301535050611505565b611260516004026111c0017c01000000000000000000000000000000000000000000000000000000006112605160200260020a60606060599059016000905260038152610a00518160200152600181604001528090502054020480601c1a825380601d1a600183015380601e1a600283015380601f1a600383015350505b60016112605101611260526113ec565b6111c051606060605990590160009052600381526101e05181602001526001816040015280905020555050608060805990590160009052600381526101e051816020015260028160400152600081606001528090502060005b600281121561159057806020026102c05101518282015560018101905061156e565b700100000000000000000000000000000000600003816020026102c051015116828201555050610c80517bffff0000000000000000000000000000000000000000000000000000056113e0526113e051610b805101610be052606060605990590160009052600381526101e051816020015260008160400152809050205461140052601061140001610be0518060101a82538060111a60018301538060121a60028301538060131a60038301538060141a60048301538060151a60058301538060161a60068301538060171a60078301538060181a60088301538060191a600983015380601a1a600a83015380601b1a600b83015380601c1a600c83015380601d1a600d83015380601e1a600e83015380601f1a600f830153505061140051606060605990590160009052600381526101e0518160200152600081604001528090502055660400000000000354610be051121515611703576101e051660400000000000255610be0516604000000000003555b601c6020599059016000905201610120516101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a350610120516114a05260206114a0f35b601c602059905901600090520161276a6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a35060006114c05260206114c0f35b630f5995ce8114156119a157365990590160009052366004823760043560208201016114e05260243561150052604435602082010161152052606435604052506114e05160208103516020599059016000905260208183856000600287604801f150805190509050905061156052602059905901600090526020816020611560600060026068f1508051905060005b6020811215611843578181601f031a816116400153600181019050611823565b50506116405161154052604060206114e051035114156118a457601c6020599059016000905201614e52611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a3506000611660526020611660f35b6080601c6101ac59905901600090520163bd136cb3601c8203526115405160048201526115005160248201526115205160208103516020026020018360448401526020820360c48401528061014884015280840193505050604051606482015281600401599059016000905260848160848460006004601ff161192357fe5b6084810192506101488201518080858260c487015160006004600a8705601201f161194a57fe5b508084019350508083036020611680828434306123555a03f15061168051905090509050905061042052600161042051141561199357611540516116a05260206116a0f36119a0565b60006116c05260206116c0f35b5b63bd136cb3811415611d8c573659905901600090523660048237600435611540526024356115005260443560208201016115205260643560405250601c606459905901600090520163d467ae03601c82035260405160048201526060606059905901600090526003815260405181602001526003816040015280905020546bffffffffffffffffffffffff166024820152602061170060448334306123555a03f1506117005190501515611a9757601c6020599059016000905201614e2a611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e2a611720526020611720f35b601c6044599059016000905201633d73b705601c82035260405160048201526020611740602483600030602d5a03f15061174051905015611b1a57601c6020599059016000905201614e34611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e34611760526020611760f35b601c604459905901600090520163b041b285601c82035260405160048201526020611780602483600030602d5a03f1506117805190501515611b9e57601c6020599059016000905201614e3e611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e3e6117a05260206117a0f35b6060601c61014c59905901600090520163b7129afb601c8203526115405160048201526115005160248201526115205160208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf1611c1557fe5b6064810192506101088201518080858260a487015160006004600a8705601201f1611c3c57fe5b5080840193505080830360206117e08284600030602d5a03f1506117e05190509050905090506117c0526080608059905901600090526003815260405181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006002820154046401000000006001830154020160005b6020811215611ce4578181601f031a816118a00153600181019050611cc4565b50506118a051905061180052611800516117c0511415611d4457601c60205990590160009052016001611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a35060016118c05260206118c0f35b601c6020599059016000905201614e48611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e486118e05260206118e0f35b63318a3fee81141561205657365990590160009052366004823760043560208201016114e0526024356115005260443560208201016115205260643560405260843561190052506080601c6101ac599059016000905201630f5995ce601c8203526114e0516020601f6020830351010460200260200183600484015260208203608484015280610108840152808401935050506115005160248201526115205160208103516020026020018360448401526020820360c48401528061014884015280840193505050604051606482015281600401599059016000905260848160848460006004601ff1611e7b57fe5b60848101925061010882015180808582608487015160006004600a8705601201f1611ea257fe5b508084019350506101488201518080858260c487015160006004600a8705601201f1611eca57fe5b508084019350508083036020611920828434306123555a03f15061192051905090509050905061154052600061154051141515612010576040601c60ec599059016000905201631c0b6367601c8203526114e0516020601f6020830351010460200260200183600484015260208203604484015280608884015280840193505050611540516024820152816004015990590160009052604481604484600060046018f1611f7357fe5b604481019250608882015180808582604487015160006004600a8705601201f1611f9957fe5b5080840193505080830360206119608284600061190051602d5a03f15061196051905090509050905061194052601c602059905901600090520161194051611540517f2d0d11d0f27e21fab56a8712078721096066b7faaa8540a3ea566e70b97de2d4600084a35061194051611980526020611980f35b601c602059905901600090520161753a60007f2d0d11d0f27e21fab56a8712078721096066b7faaa8540a3ea566e70b97de2d4600084a35061753a6119a05260206119a0f35b6309dd0e81811415612076576604000000000002546119c05260206119c0f35b63023948728114156120d2577801000000000000000000000000000000000000000000000000606060605990590160009052600381526604000000000002548160200152600081604001528090502054046119e05260206119e0f35b632c181929811415612139577001000000000000000000000000000000007001000000000000000000000000000000006060606059905901600090526003815266040000000000025481602001526000816040015280905020540204611a20526020611a20f35b637ca823d58114156122af576604000000000002546101e052700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204611a60526000611260525b600a61126051121561224c57608060805990590160009052600381526101e05181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006001820154046401000000008254020160005b6020811215612230578181601f031a81611b200153600181019050612210565b5050611b205190506101e05260016112605101611260526121a8565b700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204611b4052611b4051611a605103611b80526020611b80f35b63b7129afb81141561246a57365990590160009052366004823760043561154052602435611500526044356020820101611520525061154051611ba0526020611520510351611bc0526000611260525b611bc05161126051121561245b5761126051602002611520510151611be05260026115005107611c00526001611c0051141561234a57611be051611c2052611ba051611c4052612368565b6000611c0051141561236757611ba051611c2052611be051611c40525b5b60405990590160009052611c205160005b6020811215612399578181601f031a81611ca00153600181019050612379565b5050611ca0518152611c405160005b60208112156123c8578181601f031a81611d2001536001810190506123a8565b5050611d2051602082015260205990590160009052602081604084600060026088f15080519050611d4052602059905901600090526020816020611d40600060026068f1508051905060005b6020811215612434578181601f031a81611de00153600181019050612414565b5050611de0519050611ba052600261150051056115005260016112605101611260526122ff565b611ba051611e00526020611e00f35b633d73b70581141561255b576004356040526604000000000002546101e0526000611260525b600661126051121561254e576101e05160405114156124b6576001611e20526020611e20f35b608060805990590160009052600381526101e05181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006001820154046401000000008254020160005b6020811215612532578181601f031a81611ec00153600181019050612512565b5050611ec05190506101e0526001611260510161126052612490565b6000611ee0526020611ee0f35b631f794436811415612737576004356101e052601c606459905901600090520163d467ae03601c8203526101e0516004820152606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff1660248201526020611f2060448334306123555a03f150611f20519050151561265657601c602059905901600090520160006101e0517f60ab231f060fa320acea170017564b7ee77f477e6465a8c964380cffb270aaf4600084a350602159905901600090526001815260006020820152602081019050602060408203526020601f6020830351604001010460200260408203f3505b601c602059905901600090520160016101e0517f60ab231f060fa320acea170017564b7ee77f477e6465a8c964380cffb270aaf4600084a350608060805990590160009052600381526101e0518160200152600281604001526000816060015280905020607059905901600090526050815260208101905060005b60028112156126f05780830154816020028301526001810190506126d1565b70010000000000000000000000000000000060000381840154168160200283015281905090509050602060408203526020601f6020830351604001010460200260408203f3505b6313f955e18114156128ca573659905901600090523660048237600435602082010161204052602435612060525060506120805260006120a052612080516120c0526000611260525b612060516112605112156128bb576120a051806120c051038080602001599059016000905281815260208101905090508180828286612040510160006004600a8705601201f16127cc57fe5b50809050905090506120e0526020601c608c599059016000905201632b861629601c8203526120e0516020601f6020830351010460200260200183600484015260208203602484015280604884015280840193505050816004015990590160009052602481602484600060046015f161284157fe5b602481019250604882015180808582602487015160006004600a8705601201f161286757fe5b5080840193505080830360206121a08284600030602d5a03f1506121a051905090509050905061042052612080516120a051016120a052612080516120c051016120c0526001611260510161126052612780565b610420516121c05260206121c0f35b50",
- "storage": {
- "0x292b7a8d467a95cffd303c7edd99875892cdb3eaee87e5ca29057dc88a09ffbd": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x4d2fcf8ac901ad7dcf5b1c3979801430d9979c87157230ae066a0276984c6ac7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xdf951a5d1d9283b06d4f1de58542f1e1e310d8d17aada46586ddb9598bc42894": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x9c8d09d387f3ba5dd4733e24c63e4d549864a7cd57a1bdf1fdd831a2a0184815": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x4ab3b783bb170e11b0932a5ce8f5f343f67058b3925da271001a75ae498bd655": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x0000000000000000000000000000000000000004": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x0000000000000000000000000000000000000002": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "559198",
- "difficulty": "1814830",
- "timestamp": "1577471205",
- "gasLimit": "6327338",
- "miner": "0x774c398d763161f55b66a646f17edda4addad2ca"
- },
- "input": "0xf9026f8301307b85746a52880083124f80946cc68eb482a757c690dd151d2bd5e774ada38bdc80b9020413f955e100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000019004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae704000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30304000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e00000000000000000000000000000000081a1a01c9e9d742c8e69daba2a026ccafdde618f2e44c96db281c2209c22f183ad03a2a049a61d267d22226896d4c065525819c238784c439dc2afa7d17fce76595730d1",
- "result": [
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "gas": "0x124f80",
- "input": "0x13f955e100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000019004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae704000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30304000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x1c6ff",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 5,
- "traceAddress": [],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x114243",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a6700000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 0
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x110d3b",
- "input": "0x2b86162900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000050040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae700000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 1
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x10d833",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30300000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 2
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x10a328",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de00000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 3
- ],
- "type": "call"
- },
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "gas": "0x106e1d",
- "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc",
- "value": "0x0"
- },
- "result": {
- "address": "0x0000000000000000000000000000000000000000",
- "gasUsed": "0x27c3",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000"
- },
- "subtraces": 0,
- "traceAddress": [
- 4
- ],
- "type": "call"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json
deleted file mode 100644
index bc94708718..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json
+++ /dev/null
@@ -1,95 +0,0 @@
-{
- "context": {
- "difficulty": "3956606365",
- "gasLimit": "5413248",
- "miner": "0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d",
- "number": "2295104",
- "timestamp": "1513681256"
- },
- "genesis": {
- "alloc": {
- "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76": {
- "balance": "0x0",
- "code": "0x60606040526004361061015e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680625b4487146101a257806311df9995146101cb578063278ecde11461022057806330adce0e146102435780633197cbb61461026c5780634bb278f3146102955780636103d70b146102aa57806363a599a4146102bf5780636a2d1cb8146102d457806375f12b21146102fd57806378e979251461032a578063801db9cc1461035357806386d1a69f1461037c5780638da5cb5b146103915780638ef26a71146103e65780639890220b1461040f5780639b39caef14610424578063b85dfb801461044d578063be9a6555146104a1578063ccb07cef146104b6578063d06c91e4146104e3578063d669e1d414610538578063df40503c14610561578063e2982c2114610576578063f02e030d146105c3578063f2fde38b146105d8578063f3283fba14610611575b600060149054906101000a900460ff1615151561017a57600080fd5b60075442108061018b575060085442115b15151561019757600080fd5b6101a03361064a565b005b34156101ad57600080fd5b6101b5610925565b6040518082815260200191505060405180910390f35b34156101d657600080fd5b6101de61092b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561022b57600080fd5b6102416004808035906020019091905050610951565b005b341561024e57600080fd5b610256610c48565b6040518082815260200191505060405180910390f35b341561027757600080fd5b61027f610c4e565b6040518082815260200191505060405180910390f35b34156102a057600080fd5b6102a8610c54565b005b34156102b557600080fd5b6102bd610f3e565b005b34156102ca57600080fd5b6102d261105d565b005b34156102df57600080fd5b6102e76110d5565b6040518082815260200191505060405180910390f35b341561030857600080fd5b6103106110e1565b604051808215151515815260200191505060405180910390f35b341561033557600080fd5b61033d6110f4565b6040518082815260200191505060405180910390f35b341561035e57600080fd5b6103666110fa565b6040518082815260200191505060405180910390f35b341561038757600080fd5b61038f611104565b005b341561039c57600080fd5b6103a4611196565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f157600080fd5b6103f96111bb565b6040518082815260200191505060405180910390f35b341561041a57600080fd5b6104226111c1565b005b341561042f57600080fd5b610437611296565b6040518082815260200191505060405180910390f35b341561045857600080fd5b610484600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061129c565b604051808381526020018281526020019250505060405180910390f35b34156104ac57600080fd5b6104b46112c0565b005b34156104c157600080fd5b6104c9611341565b604051808215151515815260200191505060405180910390f35b34156104ee57600080fd5b6104f6611354565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561054357600080fd5b61054b61137a565b6040518082815260200191505060405180910390f35b341561056c57600080fd5b610574611385565b005b341561058157600080fd5b6105ad600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506116c3565b6040518082815260200191505060405180910390f35b34156105ce57600080fd5b6105d66116db565b005b34156105e357600080fd5b61060f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611829565b005b341561061c57600080fd5b610648600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118fe565b005b600080670de0b6b3a7640000341015151561066457600080fd5b61069b610696670de0b6b3a7640000610688610258346119d990919063ffffffff16565b611a0c90919063ffffffff16565b611a27565b9150660221b262dd80006106ba60065484611a7e90919063ffffffff16565b111515156106c757600080fd5b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156107d557600080fd5b6102c65a03f115156107e657600080fd5b5050506040518051905050610808828260010154611a7e90919063ffffffff16565b8160010181905550610827348260000154611a7e90919063ffffffff16565b816000018190555061084434600554611a7e90919063ffffffff16565b60058190555061085f82600654611a7e90919063ffffffff16565b6006819055503373ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c836040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e8583600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060085442108061096b5750651b48eb57e00060065410155b15151561097757600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154821415156109c757600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515610ac857600080fd5b6102c65a03f11515610ad957600080fd5b5050506040518051905050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68836000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610b7d57600080fd5b6102c65a03f11515610b8e57600080fd5b505050604051805190501515610ba357600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506000811115610c4457610c433382611a9c565b5b5050565b60055481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cb157600080fd5b600854421015610cd357660221b262dd8000600654141515610cd257600080fd5b5b651b48eb57e000600654108015610cf057506213c6806008540142105b151515610cfc57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501515610d7557600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610e3a57600080fd5b6102c65a03f11515610e4b57600080fd5b5050506040518051905090506000811115610f2057600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610ef957600080fd5b6102c65a03f11515610f0a57600080fd5b505050604051805190501515610f1f57600080fd5b5b6001600960006101000a81548160ff02191690831515021790555050565b600080339150600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114151515610f9657600080fd5b803073ffffffffffffffffffffffffffffffffffffffff163110151515610fbc57600080fd5b610fd181600254611b5090919063ffffffff16565b6002819055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561105957fe5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110b857600080fd5b6001600060146101000a81548160ff021916908315150217905550565b670de0b6b3a764000081565b600060149054906101000a900460ff1681565b60075481565b651b48eb57e00081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561115f57600080fd5b600060149054906101000a900460ff16151561117a57600080fd5b60008060146101000a81548160ff021916908315150217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561121c57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561129457600080fd5b565b61025881565b600a6020528060005260406000206000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561131b57600080fd5b600060075414151561132c57600080fd5b4260078190555062278d004201600881905550565b600960009054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b660221b262dd800081565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113e557600080fd5b600654660221b262dd800003925061142b670de0b6b3a764000061141c610258670de0b6b3a76400006119d990919063ffffffff16565b81151561142557fe5b04611a27565b915081831115151561143c57600080fd5b600a60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561158c57600080fd5b6102c65a03f1151561159d57600080fd5b50505060405180519050506115bf838260010154611a7e90919063ffffffff16565b81600101819055506115dc83600654611a7e90919063ffffffff16565b6006819055503073ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c846040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e856000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60016020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561173657600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f2fde38b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b151561181357600080fd5b6102c65a03f1151561182457600080fd5b505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415156118fb57806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561195957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561199557600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080828402905060008414806119fa57508284828115156119f757fe5b04145b1515611a0257fe5b8091505092915050565b6000808284811515611a1a57fe5b0490508091505092915050565b6000611a416202a300600754611a7e90919063ffffffff16565b421015611a7557611a6e611a5f600584611a0c90919063ffffffff16565b83611a7e90919063ffffffff16565b9050611a79565b8190505b919050565b6000808284019050838110151515611a9257fe5b8091505092915050565b611aee81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611a7e90919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b4681600254611a7e90919063ffffffff16565b6002819055505050565b6000828211151515611b5e57fe5b8183039050929150505600a165627a7a72305820ec0d82a406896ccf20989b3d6e650abe4dc104e400837f1f58e67ef499493ae90029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008d69d00910d0b2afb2a99ed6c16c8129fa8e1751",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000e819f024b41358d2c08e3a868a5c5dd0566078d4",
- "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000000000000000000000000000000000000005a388981",
- "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000005a3b38e6"
- }
- },
- "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826": {
- "balance": "0x2a2dd979a35cf000",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- },
- "0xe819f024b41358d2c08e3a868a5c5dd0566078d4": {
- "balance": "0x0",
- "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c681461027257806370a08231146102ad5780638da5cb5b146102fa57806395d89b411461034f578063a9059cbb146103dd578063dd62ed3e14610437578063f2fde38b146104a3575b600080fd5b34156100ca57600080fd5b6100d26104dc565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610515565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba61069c565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106a2565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610952565b6040518082815260200191505060405180910390f35b341561027d57600080fd5b6102936004808035906020019091905050610957565b604051808215151515815260200191505060405180910390f35b34156102b857600080fd5b6102e4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610abe565b6040518082815260200191505060405180910390f35b341561030557600080fd5b61030d610b07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561035a57600080fd5b610362610b2d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103e857600080fd5b61041d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b66565b604051808215151515815260200191505060405180910390f35b341561044257600080fd5b61048d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d01565b6040518082815260200191505060405180910390f35b34156104ae57600080fd5b6104da600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d88565b005b6040805190810160405280600b81526020017f416c6c436f6465436f696e00000000000000000000000000000000000000000081525081565b6000808214806105a157506000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15156105ac57600080fd5b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905061077683600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061080b83600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108618382610e7d90919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b600681565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109b557600080fd5b610a0782600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610a5f82600054610e7d90919063ffffffff16565b60008190555060003373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600481526020017f414c4c430000000000000000000000000000000000000000000000000000000081525081565b6000610bba82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c4f82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610de457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515610e5c5780600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000808284019050838110151515610e7357fe5b8091505092915050565b6000828211151515610e8b57fe5b8183039050929150505600a165627a7a7230582059f3ea3df0b054e9ab711f37969684ba83fe38f255ffe2c8d850d951121c51100029",
- "nonce": "1",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3956606365",
- "extraData": "0x566961425443",
- "gasLimit": "5418523",
- "hash": "0x6f37eb930a25da673ea1bb80fd9e32ddac19cdf7cd4bb2eac62cc13598624077",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "mixHash": "0x10971cde68c587c750c23b8589ae868ce82c2c646636b97e7d9856470c5297c7",
- "nonce": "0x810f923ff4b450a1",
- "number": "2295103",
- "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e",
- "timestamp": "1513681246",
- "totalDifficulty": "7162347056825919"
- },
- "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826",
- "gas": "0x7dfa6",
- "input": "0x",
- "to": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76",
- "value": "0xe92596fd6290000"
- },
- "blockNumber": 2295104,
- "error": "execution reverted",
- "result": {
- "gasUsed": "0x7c1c8"
- },
- "subtraces": 1,
- "traceAddress": [],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76",
- "gas": "0x75fe3",
- "input": "0xa9059cbb000000000000000000000000d4fcab9f0a6dc0493af47c864f6f17a8a5e2e82600000000000000000000000000000000000000000000000000000000000002f4",
- "to": "0xe819f024b41358d2c08e3a868a5c5dd0566078d4",
- "value": "0x0"
- },
- "blockNumber": 0,
- "error": "invalid opcode: INVALID",
- "result": {},
- "subtraces": 0,
- "traceAddress": [0],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json
deleted file mode 100644
index 3fcc61fc80..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json
+++ /dev/null
@@ -1,94 +0,0 @@
-{
- "genesis": {
- "difficulty": "1808543",
- "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578",
- "gasLimit": "4875092",
- "hash": "0x3851fdc18bd5f2314cf0c90439356f9a1fe157d7fb06c20e20b77954da903671",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "mixHash": "0x3d4e702d6058acf94c9547560f05536d45d515bd4f9014564ec41b5b4ff9578b",
- "nonce": "0x1695153e7b16c1e7",
- "number": "555461",
- "stateRoot": "0xba8272acd0dfeb5f04376328e8bfc5b276b177697000c204a060f6f7b629ae32",
- "timestamp": "1577423350",
- "totalDifficulty": "462222992438",
- "alloc": {
- "0xcf5b3467dfa45cdc8e5358a7a1ba4deb02e5faed": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x16c102a3b09c02abdace",
- "nonce": "19049",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "555462",
- "difficulty": "1808543",
- "timestamp": "1577423360",
- "gasLimit": "4873701",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf90451824a6985746a52880083053e908080b903fb60606040525b60405161015b806102a0833901809050604051809103906000f0600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b610247806100596000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900480632ef9db1314610044578063e37678761461007157610042565b005b61005b6004803590602001803590602001506100ad565b6040518082815260200191505060405180910390f35b61008860048035906020018035906020015061008a565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000600060008484604051808381526020018281526020019250505060405180910390209150610120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167f6164640000000000000000000000000000000000000000000000000000000000846101e3565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681868660405180807f616464000000000000000000000000000000000000000000000000000000000081526020015060200184815260200183815260200182815260200193505050506000604051808303816000866161da5a03f191505050600060005060008281526020019081526020016000206000505492506101db565b505092915050565b60004340848484604051808581526020018473ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140183815260200182815260200194505050505060405180910390209050610240565b9392505050566060604052610148806100136000396000f30060606040526000357c010000000000000000000000000000000000000000000000000000000090048063471407e614610044578063e37678761461007757610042565b005b6100616004803590602001803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b61008e600480359060200180359060200150610090565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000818301905080506100c684826100d5565b8090506100ce565b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff16828260405180807f7265676973746572496e74000000000000000000000000000000000000000000815260200150602001838152602001828152602001925050506000604051808303816000866161da5a03f1915050505b50505681a1a0b9a85df655d3b6aa081e52d8c3db52c50c2bf97d9d993a980113b2262649c125a00d51e63880ca8ef4705914a71e7ff906834a9cdcff0cbd063ff4e43a5905890d",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x53e90",
- "init": "0x60606040525b60405161015b806102a0833901809050604051809103906000f0600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b610247806100596000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900480632ef9db1314610044578063e37678761461007157610042565b005b61005b6004803590602001803590602001506100ad565b6040518082815260200191505060405180910390f35b61008860048035906020018035906020015061008a565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000600060008484604051808381526020018281526020019250505060405180910390209150610120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167f6164640000000000000000000000000000000000000000000000000000000000846101e3565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681868660405180807f616464000000000000000000000000000000000000000000000000000000000081526020015060200184815260200183815260200182815260200193505050506000604051808303816000866161da5a03f191505050600060005060008281526020019081526020016000206000505492506101db565b505092915050565b60004340848484604051808581526020018473ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140183815260200182815260200194505050505060405180910390209050610240565b9392505050566060604052610148806100136000396000f30060606040526000357c010000000000000000000000000000000000000000000000000000000090048063471407e614610044578063e37678761461007757610042565b005b6100616004803590602001803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b61008e600480359060200180359060200150610090565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000818301905080506100c684826100d5565b8090506100ce565b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff16828260405180807f7265676973746572496e74000000000000000000000000000000000000000000815260200150602001838152602001828152602001925050506000604051808303816000866161da5a03f1915050505b505056"
- },
- "result": {
- "gasUsed": "0x53e90",
- "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632ef9db1314610044578063e37678761461007157610042565b005b61005b6004803590602001803590602001506100ad565b6040518082815260200191505060405180910390f35b61008860048035906020018035906020015061008a565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000600060008484604051808381526020018281526020019250505060405180910390209150610120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167f6164640000000000000000000000000000000000000000000000000000000000846101e3565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681868660405180807f616464000000000000000000000000000000000000000000000000000000000081526020015060200184815260200183815260200182815260200193505050506000604051808303816000866161da5a03f191505050600060005060008281526020019081526020016000206000505492506101db565b505092915050565b60004340848484604051808581526020018473ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140183815260200182815260200194505050505060405180910390209050610240565b939250505056",
- "address": "0x9db7a1baf185a865ffee3824946ccd8958191e5e"
- },
- "traceAddress": [],
- "subtraces": 1,
- "transactionPosition": 23,
- "transactionHash": "0xe267552ce8437a5bc7081385c99f912de5723ad34b958db215dbc41abd5f6c03",
- "blockNumber": 555462,
- "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1",
- "time": "1.147715ms"
- },
- {
- "type": "create",
- "action": {
- "from": "0x9db7a1baf185a865ffee3824946ccd8958191e5e",
- "value": "0x0",
- "gas": "0x30b34",
- "init": "0x6060604052610148806100136000396000f30060606040526000357c010000000000000000000000000000000000000000000000000000000090048063471407e614610044578063e37678761461007757610042565b005b6100616004803590602001803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b61008e600480359060200180359060200150610090565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000818301905080506100c684826100d5565b8090506100ce565b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff16828260405180807f7265676973746572496e74000000000000000000000000000000000000000000815260200150602001838152602001828152602001925050506000604051808303816000866161da5a03f1915050505b505056"
- },
- "result": {
- "gasUsed": "0x1009d",
- "code": "0x60606040526000357c010000000000000000000000000000000000000000000000000000000090048063471407e614610044578063e37678761461007757610042565b005b6100616004803590602001803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b61008e600480359060200180359060200150610090565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000818301905080506100c684826100d5565b8090506100ce565b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff16828260405180807f7265676973746572496e74000000000000000000000000000000000000000000815260200150602001838152602001828152602001925050506000604051808303816000866161da5a03f1915050505b505056",
- "address": "0xcf5b3467dfa45cdc8e5358a7a1ba4deb02e5faed"
- },
- "traceAddress": [0],
- "subtraces": 0,
- "transactionPosition": 23,
- "transactionHash": "0xe267552ce8437a5bc7081385c99f912de5723ad34b958db215dbc41abd5f6c03",
- "blockNumber": 555462,
- "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json
deleted file mode 100644
index 0eaa3f867a..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json
+++ /dev/null
@@ -1,94 +0,0 @@
-{
- "genesis": {
- "difficulty": "4635413",
- "extraData": "0xd683010b05846765746886676f312e3133856c696e7578",
- "gasLimit": "9289294",
- "hash": "0x359775cf1a2ae2400e26ec68bf33bcfe38b7979c76b7e616f42c4ca7e7605e39",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "mixHash": "0x4b2a0ef121a9c7d732fa0fbd4166a0e1041d2da2b8cb677c61edabf8b7183b64",
- "nonce": "0x2a8a64ad9757be55",
- "number": "1555160",
- "stateRoot": "0x95067c12148e2362fcd4a89df286ff0b1739ef097a40ca42ae7f698af9a9d913",
- "timestamp": "1590793999",
- "totalDifficulty": "2242063623471",
- "alloc": {
- "0x8785e369f0ef0a4e5c5a5f929680427dc75273a5": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x623145b285b3f551fa3f",
- "nonce": "260617",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "1555161",
- "difficulty": "4633150",
- "timestamp": "1590794020",
- "gasLimit": "9298364",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf85e8303fa09843b9aca0083019ed880808a6000600060006000f50081a2a0485ea410e210740eef8e6f6de11c530f46f8da80eecb02afbb6c5f61749ac015a068d72f1b0f1d3cb4e214d5def79b49a73e6ee91db2df83499a54c656c144600f",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x19ed8",
- "init": "0x6000600060006000f500"
- },
- "result": {
- "gasUsed": "0x14c78",
- "code": "0x",
- "address": "0x2e8eded627eead210cb6143eb39ef7a3e44e4f00"
- },
- "traceAddress": [],
- "subtraces": 1,
- "transactionPosition": 31,
- "transactionHash": "0x1257b698c5833c54ce786734087002b097275abc3877af082b5c2a538e894a41",
- "blockNumber": 1555161,
- "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171",
- "time": "889.048µs"
- },
- {
- "type": "create",
- "action": {
- "from": "0x2e8eded627eead210cb6143eb39ef7a3e44e4f00",
- "value": "0x0",
- "gas": "0x5117",
- "init": "0x"
- },
- "result": {
- "gasUsed": "0x0",
- "code": "0x",
- "address": "0x8785e369f0ef0a4e5c5a5f929680427dc75273a5"
- },
- "traceAddress": [0],
- "subtraces": 0,
- "transactionPosition": 31,
- "transactionHash": "0x1257b698c5833c54ce786734087002b097275abc3877af082b5c2a538e894a41",
- "blockNumber": 1555161,
- "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json
deleted file mode 100644
index 132b84df36..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json
+++ /dev/null
@@ -1,90 +0,0 @@
-{
- "genesis": {
- "difficulty": "4639933",
- "extraData": "0xd883010b05846765746888676f312e31342e33856c696e7578",
- "gasLimit": "9280188",
- "hash": "0x9a5f3a98eb1c60f6e3f450658a9cea190157e7021d04f927b752ad6482cf9194",
- "miner": "0x73f26d124436b0791169d63a3af29c2ae47765a3",
- "mixHash": "0x6b6f8fcaa54b8565c4c1ae7cf0a020e938a53007f4561e758b17bc05c9044d78",
- "nonce": "0x773aba50dc51b462",
- "number": "1555169",
- "stateRoot": "0xc4b9703de3e59ff795baae2c3afa010cf039c37244a7a6af7f3f491a10601348",
- "timestamp": "1590794111",
- "totalDifficulty": "2242105342155",
- "alloc": {
- "0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x62325b40cbbd0915c4b9",
- "nonce": "260875",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "1555170",
- "difficulty": "4642198",
- "timestamp": "1590794112",
- "gasLimit": "9289249",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf8658303fb0b843b9aca0083019ee48080915a600055600060006000f0505a6001550081a2a01a7deb3a16d967b766459ef486b00656c6581e5ad58968184a33701e27e0eb8aa07162ccdfe2018d64360a605310a62c399dd586c7282dd42a88c54f02f51d451f",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x19ee4",
- "init": "0x5a600055600060006000f0505a60015500"
- },
- "error": "out of gas",
- "traceAddress": [],
- "subtraces": 1,
- "transactionPosition": 63,
- "transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650",
- "blockNumber": 1555170,
- "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e",
- "time": "952.736µs"
- },
- {
- "type": "create",
- "action": {
- "from": "0x9c5cfe45b15eaff4ad617af4250189e26024a4f8",
- "value": "0x0",
- "gas": "0x3cb",
- "init": "0x"
- },
- "result": {
- "gasUsed": "0x0",
- "code": "0x",
- "address": "0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d"
- },
- "traceAddress": [0],
- "subtraces": 0,
- "transactionPosition": 63,
- "transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650",
- "blockNumber": 1555170,
- "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json
deleted file mode 100644
index 28e96684b2..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json
+++ /dev/null
@@ -1,81 +0,0 @@
-{
- "genesis": {
- "difficulty": "3244991",
- "extraData": "0x",
- "gasLimit": "7968787",
- "hash": "0x62bbf18c203068a8793af8d8360d054f95a63bc62b87ade550861ed490af3f15",
- "miner": "0x9f2659ffe7b3b467e46dcec3623392cf51635079",
- "mixHash": "0xc8dec711fd1e03972b6a279a09dc0cd29c5171b60f42c4ce37c7c51ff445f776",
- "nonce": "0x40b1bbcc25ddb804",
- "number": "839246",
- "stateRoot": "0x4bb3b02ec70b837651233957fb61a6ea3fc6a4244c1f55df7a713c154829ec0a",
- "timestamp": "1581179375",
- "totalDifficulty": "1023985623933",
- "alloc": {
- "0x76554b33410b6d90b7dc889bfed0451ad195f27e": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x6080604052348015600f57600080fd5b506004361060505760003560e01c8063391521f414605557806355313dea14605d5780636d3d14161460655780638da5cb5b14606d578063b9d1e5aa1460b5575b600080fd5b605b60bd565b005b606360c8565b005b606b60ca565b005b607360cf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60bb60f4565b005b6020610123600af050565b005b600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565bfefea165627a7a723058202094d5aa5dbbd493e9a2c64c50b62eba4b109b2a12d2bb73a5d0d54982651fc80029",
- "storage": {}
- },
- "0xed69ab7145a9bae7152406d062c077c6ecc6ae18": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0xa3b31cbd5168d3c99756660d4b7625d679e12573": {
- "balance": "0x569bc6535d3083fce",
- "nonce": "26",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "839247",
- "difficulty": "3213311",
- "timestamp": "1581179571",
- "gasLimit": "7961006",
- "miner": "0x9f2659ffe7b3b467e46dcec3623392cf51635079"
- },
- "input": "0xf86a1a8509502f9000830334509476554b33410b6d90b7dc889bfed0451ad195f27e8084391521f481a2a02e4ff0d171a860c8c7de2283978e2f225f9ba3ed4dec446b773c6b2d73ef22dea02a6a517528b491cb71b204f534db11a1c8059035f54d5bae347d1cab536bde2c",
- "result": [
- {
- "type": "call",
- "action": {
- "from": "0xa3b31cbd5168d3c99756660d4b7625d679e12573",
- "to": "0x76554b33410b6d90b7dc889bfed0451ad195f27e",
- "value": "0x0",
- "gas": "0x33450",
- "input": "0x391521f4",
- "callType": "call"
- },
- "result": {
- "gasUsed": "0xd0b5",
- "output": "0x"
- },
- "traceAddress": [],
- "subtraces": 0,
- "transactionPosition": 26,
- "transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4",
- "blockNumber": 839247,
- "blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c",
- "time": "182.267µs"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json
deleted file mode 100644
index c3191d61bc..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json
+++ /dev/null
@@ -1,189 +0,0 @@
-{
- "genesis": {
- "number": "13535",
- "hash": "0x6f706fe8026edb51577b57685574dc152dba4e2ebfc8a50bb63a8c95a4f8818d",
- "nonce": "0x0000000000000000",
- "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "stateRoot": "0x7f54db248a004ca182fe87fdfa6efda97163908b4f0cc84b36a6d60699d5d1be",
- "miner": "0x0000000000000000000000000000000000000000",
- "difficulty": "1",
- "totalDifficulty": "24766",
- "extraData": "0xf09f928e20407072796c616273206e6f64652d3020f09f928e000000000000001d32ac3baf238e163e18ed6d77b67b0b54b08ad9781dc4ffd93c5ede1ca12c5f21b36ac39c7ebb88dff65da91f5b9461f19873a02602230b931ba388a809119f00",
- "gasLimit": "8000000",
- "timestamp": "1549153003",
- "alloc": {
- "0x0b1ba0af832d7c05fd64161e0db78e85978e8082": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x6080604052600436106100ae5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100b8578063095ea7b31461014257806318160ddd1461018757806323b872dd146101ae5780632e1a7d4d146101e5578063313ce567146101fd57806370a082311461022857806395d89b4114610256578063a9059cbb1461026b578063d0e30db0146100ae578063dd62ed3e1461029c575b6100b66102d0565b005b3480156100c457600080fd5b506100cd61031f565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101075781810151838201526020016100ef565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014e57600080fd5b5061017373ffffffffffffffffffffffffffffffffffffffff600435166024356103cb565b604080519115158252519081900360200190f35b34801561019357600080fd5b5061019c61043e565b60408051918252519081900360200190f35b3480156101ba57600080fd5b5061017373ffffffffffffffffffffffffffffffffffffffff60043581169060243516604435610443565b3480156101f157600080fd5b506100b66004356105e3565b34801561020957600080fd5b50610212610678565b6040805160ff9092168252519081900360200190f35b34801561023457600080fd5b5061019c73ffffffffffffffffffffffffffffffffffffffff60043516610681565b34801561026257600080fd5b506100cd610693565b34801561027757600080fd5b5061017373ffffffffffffffffffffffffffffffffffffffff6004351660243561070b565b3480156102a857600080fd5b5061019c73ffffffffffffffffffffffffffffffffffffffff6004358116906024351661071f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156103c35780601f10610398576101008083540402835291602001916103c3565b820191906000526020600020905b8154815290600101906020018083116103a657829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b303190565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081205482111561047557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906104eb575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105655773ffffffffffffffffffffffffffffffffffffffff8416600090815260046020908152604080832033845290915290205482111561052d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b336000908152600360205260409020548111156105ff57600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f1935050505015801561063e573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156103c35780601f10610398576101008083540402835291602001916103c3565b6000610718338484610443565b9392505050565b6004602090815260009283526040808420909152908252902054815600a165627a7a72305820228981f11f47ad9630080069b0a81423fcfba5aa8e0f478a579c4bc080ba7e820029",
- "storage": {
- "0xbe8a6e3827dad84a671edac41a02b0f5b47b9d0339adb1e9411b9ba4e2118738": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x48bacb9266a570d521063ef5dd96e61686dbe788": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x6080604052600436106101b65763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663288cdc9181146101bb578063297bb70b146101f15780632ac126221461021e5780633683ef8e1461024b5780633c28d8611461026d5780633e228bae1461029a5780633fd3c997146102ba5780634ac14782146102e75780634d0ae546146103075780634f9559b11461032757806350dde190146103475780636070410814610367578063642f2eaf1461039457806364a3bc15146103b457806377fcce68146103d45780637b8e3514146103f45780637e1d9808146104145780637e9d74dc1461043457806382c174d0146104615780638da5cb5b146104815780639363470214610496578063a3e20380146104b6578063b4be83d5146104d6578063bfc8bfce146104f6578063c585bb9314610516578063c75e0a8114610536578063d46b02c314610563578063d9bfa73e14610583578063db123b1a146105a3578063dd1c7d18146105c5578063e306f779146105e5578063e5fa431b146105fa578063eea086ba1461061a578063f2fde38b1461062f578063ffa1ad741461064f575b600080fd5b3480156101c757600080fd5b506101db6101d63660046148ee565b610664565b6040516101e89190615513565b60405180910390f35b3480156101fd57600080fd5b5061021161020c366004614811565b610676565b6040516101e891906157ed565b34801561022a57600080fd5b5061023e6102393660046148ee565b6107a1565b6040516101e89190615505565b34801561025757600080fd5b5061026b61026636600461492b565b6107b6565b005b34801561027957600080fd5b5061028d610288366004614a5f565b6108a3565b6040516101e891906157fb565b3480156102a657600080fd5b506102116102b5366004614b1f565b610a3a565b3480156102c657600080fd5b506102da6102d53660046149ee565b610a90565b6040516101e891906155cf565b3480156102f357600080fd5b5061026b6103023660046147dc565b610ab8565b34801561031357600080fd5b50610211610322366004614811565b610b85565b34801561033357600080fd5b5061026b6103423660046148ee565b610c75565b34801561035357600080fd5b50610211610362366004614811565b610e2a565b34801561037357600080fd5b506103876103823660046149ee565b610ebe565b6040516101e89190615425565b3480156103a057600080fd5b5061023e6103af3660046148ee565b610f0c565b3480156103c057600080fd5b506102116103cf366004614b1f565b610f21565b3480156103e057600080fd5b5061026b6103ef3660046147ac565b610fcc565b34801561040057600080fd5b5061023e61040f366004614772565b611106565b34801561042057600080fd5b5061021161042f3660046148a5565b611126565b34801561044057600080fd5b5061045461044f3660046147dc565b61128a565b6040516101e891906154f4565b34801561046d57600080fd5b5061023e61047c36600461490c565b61131f565b34801561048d57600080fd5b5061038761133f565b3480156104a257600080fd5b5061023e6104b1366004614993565b61135b565b3480156104c257600080fd5b506102116104d13660046148a5565b6118de565b3480156104e257600080fd5b506102116104f1366004614b1f565b6119f1565b34801561050257600080fd5b5061026b610511366004614b68565b611a6c565b34801561052257600080fd5b5061026b610531366004614754565b611d05565b34801561054257600080fd5b50610556610551366004614a2a565b611f30565b6040516101e8919061580a565b34801561056f57600080fd5b5061026b61057e366004614a2a565b61202a565b34801561058f57600080fd5b506101db61059e366004614772565b6120c6565b3480156105af57600080fd5b506105b86120e3565b6040516101e891906155be565b3480156105d157600080fd5b506102116105e03660046148a5565b61218e565b3480156105f157600080fd5b506101db612263565b34801561060657600080fd5b506102116106153660046148a5565b612269565b34801561062657600080fd5b506103876123db565b34801561063b57600080fd5b5061026b61064a366004614754565b6123f7565b34801561065b57600080fd5b506105b86124a8565b60046020526000908152604090205481565b61067e614386565b600080610689614386565b60005460ff16156106cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781558751935091505b81831461076f57610758878381518110151561071957fe5b90602001906020020151878481518110151561073157fe5b90602001906020020151878581518110151561074957fe5b906020019060200201516124df565b9050610764848261257d565b600190910190610701565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055509392505050565b60056020526000908152604090205460ff1681565b73ffffffffffffffffffffffffffffffffffffffff831633146108465761080e848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375061135b945050505050565b1515610846576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061569d565b5050600091825260076020908152604080842073ffffffffffffffffffffffffffffffffffffffff9093168452919052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6108ab6143af565b6108b36143de565b6108bb6143de565b6000805460ff16156108f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561016080890151610140808a01919091528901519088015261094588611f30565b925061095087611f30565b915061095a6125df565b905061096888848389612611565b61097487838388612611565b61097e88886127a9565b610992888885604001518560400151612809565b8051602081015190519195506109ad918a9186918190612990565b6020808501519081015190516109c99189918591908190612990565b6109e28882856020015186604001518860000151612aa9565b6109fb8782846020015185604001518860200151612aa9565b610a0788888387612b55565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550949350505050565b610a42614386565b6060610a4f858585612d2d565b9050608081825160208401305af48015610a8657815183526020820151602084015260408201516040840152606082015160608401525b505b509392505050565b600b6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60008054819060ff1615610af8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781558151905b808214610b5857610b508382815181101515610b4157fe5b90602001906020020151612eff565b600101610b29565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550565b610b8d614386565b600080610b98614386565b60005460ff1615610bd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781558751935091505b81831461076f57610c5e8783815181101515610c1f57fe5b906020019060200201518784815181101515610c3757fe5b906020019060200201518785815181101515610c4f57fe5b90602001906020020151612f2a565b9050610c6a848261257d565b600190910190610c07565b6000805481908190819060ff1615610cb9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610cec6125df565b935073ffffffffffffffffffffffffffffffffffffffff84163314610d115733610d14565b60005b73ffffffffffffffffffffffffffffffffffffffff8086166000908152600660209081526040808320938516835292905220549093506001860192509050808211610d8b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061572d565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526006602090815260408083209488168084529490915290819020859055517f82af639571738f4ebd4268fb0363d8957ebe1bbb9e78dba5ebd69eed39b154f090610df3908690615513565b60405180910390a35050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055505050565b610e32614386565b600080610e3d614386565b86519250600091505b818314610eb457610e9d8783815181101515610e5e57fe5b906020019060200201518784815181101515610e7657fe5b906020019060200201518785815181101515610e8e57fe5b90602001906020020151610a3a565b9050610ea9848261257d565b600190910190610e46565b5050509392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff165b919050565b60096020526000908152604090205460ff1681565b610f29614386565b60005460ff1615610f66576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610f9c848484612f2a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055949350505050565b6000805460ff161561100a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561103d6125df565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600860209081526040808320948916808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168715151790555192935090917fa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba891906110d1908690615505565b60405180910390a35050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550565b600860209081526000928352604080842090915290825290205460ff1681565b61112e614386565b6060600080600061113d614386565b60005460ff161561117a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117815589518a919081106111b257fe5b906020019060200201516101600151945088519350600092505b828414611255578489848151811015156111e257fe5b906020019060200201516101600181905250611202888760200151612f7d565b915061122e898481518110151561121557fe5b9060200190602002015183898681518110151561074957fe5b905061123a868261257d565b6020860151881161124a57611255565b6001909201916111cc565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055509195945050505050565b606060006060600084519250826040519080825280602002602001820160405280156112d057816020015b6112bd6143de565b8152602001906001900390816112b55790505b509150600090505b808314610a88576112ff85828151811015156112f057fe5b90602001906020020151611f30565b828281518110151561130d57fe5b602090810290910101526001016112d8565b600760209081526000928352604080842090915290825290205460ff1681565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600080600080600089511115156113a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061571d565b6113ad89612fc4565b7f010000000000000000000000000000000000000000000000000000000000000090049650600760ff88161061140f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061563d565b8660ff16600781111561141e57fe5b9550600086600781111561142e57fe5b1415611466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061570d565b600186600781111561147457fe5b14156114bc578851156114b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157dd565b600097506118d0565b60028660078111156114ca57fe5b141561160557885160411461150b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906155dd565b88600081518110151561151a57fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061155a89600163ffffffff61308816565b935061156d89602163ffffffff61308816565b925060018b86868660405160008152602001604052604051611592949392919061556e565b60206040516020810390808403906000865af11580156115b6573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8c811690821614995092506118d09050565b600386600781111561161357fe5b14156117b9578851604114611654576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906155dd565b88600081518110151561166357fe5b01602001517f01000000000000000000000000000000000000000000000000000000000000009081900481020494506116a389600163ffffffff61308816565b93506116b689602163ffffffff61308816565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061175757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161171a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822060008352910192839052611592945092508991899150889061556e565b60048660078111156117c757fe5b14156117df576117d88b8b8b6130d3565b97506118d0565b60058660078111156117ed57fe5b1415611850576117fc89613228565b73ffffffffffffffffffffffffffffffffffffffff808c1660009081526008602090815260408083209385168352929052205490915060ff16151561184457600097506118d0565b6117d8818c8c8c6132a1565b600686600781111561185e57fe5b141561189e5760008b815260076020908152604080832073ffffffffffffffffffffffffffffffffffffffff8e16845290915290205460ff1697506118d0565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061563d565b505050505050509392505050565b6118e6614386565b60606000806000806118f6614386565b89600081518110151561190557fe5b906020019060200201516101400151955089519450600093505b8385146119e457858a8581518110151561193557fe5b6020908102909101015161014001528651611951908a90612f7d565b92506119948a8581518110151561196457fe5b9060200190602002015160a001518b8681518110151561198057fe5b9060200190602002015160800151856133fd565b91506119c08a858151811015156119a757fe5b90602001906020020151838a87815181101515610e8e57fe5b90506119cc878261257d565b865189116119d9576119e4565b60019093019261191f565b5050505050509392505050565b6119f9614386565b60005460ff1615611a36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610f9c8484846124df565b600a5460009073ffffffffffffffffffffffffffffffffffffffff1615611abf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b611b02611afd888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843750613453945050505050565b613694565b60008181526009602052604090205490915060ff1615611b4e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061568d565b73ffffffffffffffffffffffffffffffffffffffff86163314611c1f57611ba6818785858080601f0160208091040260200160405190810160405280939291908181526020018383808284375061135b945050505050565b1515611bde576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157cd565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790555b6000818152600960205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555130908690869080838380828437820191505092505050600060405180830381855af49150501515611cb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156bd565b73ffffffffffffffffffffffffffffffffffffffff86163314611cfc57600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555b50505050505050565b6003546000908190819073ffffffffffffffffffffffffffffffffffffffff163314611d5d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061577d565b8392508273ffffffffffffffffffffffffffffffffffffffff1663ae25532e6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611dc457600080fd5b505af1158015611dd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611dfc9190810190614a0c565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600b602052604090205490925073ffffffffffffffffffffffffffffffffffffffff1690508015611e81576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061561d565b7fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600b60205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616179055517fd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c0319490611f2290849087906155a3565b60405180910390a150505050565b611f386143de565b611f41826136d1565b6020808301829052600091825260049052604090819020549082015260808201511515611f755760015b60ff168152610f07565b60a08201511515611f87576002611f6b565b60a0820151604082015110611f9d576005611f6b565b6101008201514210611fb0576004611f6b565b60208082015160009081526005909152604090205460ff1615611fd4576006611f6b565b610120820151825173ffffffffffffffffffffffffffffffffffffffff90811660009081526006602090815260408083206060880151909416835292905220541115612021576006611f6b565b60038152919050565b60005460ff1615612067576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561209b81612eff565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600660209081526000928352604080842090915290825290205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156121865780601f1061215b57610100808354040283529160200191612186565b820191906000526020600020905b81548152906001019060200180831161216957829003601f168201915b505050505081565b612196614386565b606060008060006121a5614386565b8860008151811015156121b457fe5b906020019060200201516101600151945088519350600092505b828414612257578489848151811015156121e457fe5b906020019060200201516101600181905250612204888760200151612f7d565b9150612230898481518110151561221757fe5b90602001906020020151838986815181101515610e8e57fe5b905061223c868261257d565b6020860151881161224c57612257565b6001909201916121ce565b50505050509392505050565b60025481565b612271614386565b6060600080600080612281614386565b60005460ff16156122be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781558a518b919081106122f657fe5b906020019060200201516101400151955089519450600093505b8385146123a557858a8581518110151561232657fe5b6020908102909101015161014001528651612342908a90612f7d565b92506123558a8581518110151561196457fe5b91506123818a8581518110151561236857fe5b90602001906020020151838a8781518110151561074957fe5b905061238d878261257d565b8651891161239a576123a5565b600190930192612310565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550929695505050505050565b600a5473ffffffffffffffffffffffffffffffffffffffff1681565b60035473ffffffffffffffffffffffffffffffffffffffff163314612448576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061577d565b73ffffffffffffffffffffffffffffffffffffffff8116156124a557600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b60408051808201909152600581527f322e302e30000000000000000000000000000000000000000000000000000000602082015281565b6124e7614386565b6124ef6143de565b60008060006124fd88611f30565b93506125076125df565b925061251588858589612611565b6125278860a001518560400151612f7d565b915061253387836136df565b9050612546888589848960000151612990565b61255088826136f5565b945061256788848660200151876040015189612aa9565b612572888487613756565b505050509392505050565b8151815161258b9190613864565b8252602080830151908201516125a19190613864565b6020830152604080830151908201516125ba9190613864565b6040830152606080830151908201516125d39190613864565b60609092019190915250565b600a5460009073ffffffffffffffffffffffffffffffffffffffff16818115612608578161260a565b335b9392505050565b825160ff1660031461264f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061579d565b606084015173ffffffffffffffffffffffffffffffffffffffff16156126c257606084015173ffffffffffffffffffffffffffffffffffffffff1633146126c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157ad565b602084015173ffffffffffffffffffffffffffffffffffffffff161561274d578173ffffffffffffffffffffffffffffffffffffffff16846020015173ffffffffffffffffffffffffffffffffffffffff1614151561274d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906155ed565b604083015115156127a35761276b836020015185600001518361135b565b15156127a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061565d565b50505050565b6127bb8260a001518260a001516138ae565b6127cd836080015183608001516138ae565b1015612805576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157bd565b5050565b6128116143af565b6000806000806128258960a0015188612f7d565b935061283a89608001518a60a0015186613909565b925061284a8860a0015187612f7d565b915061285f88608001518960a0015184613909565b90508084106128a25760208086018051839052805182018490525151865182015260808a015160a08b015187519092015161289a9290613909565b8551526128df565b845183905284516020908101859052855181015190860180519190915260a089015160808a01519151516128d69290613986565b60208087015101525b84515160208087015101516128f49190612f7d565b604086015284515160808a015160c08b0151612911929190613909565b85516040015284516020015160a08a015160e08b0151612932929190613909565b855160600152602085015151608089015160c08a0151612953929190613909565b8560200151604001818152505061297b8560200151602001518960a001518a60e00151613909565b60208601516060015250505050949350505050565b8215156129c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156dd565b82821115612a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156cd565b8460a00151612a16856040015184613864565b1115612a4e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906155fd565b612a5c8560800151836138ae565b612a6a828760a001516138ae565b1115612aa2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061575d565b5050505050565b612ab7828260200151613864565b600084815260046020908152604091829020929092558681015187518451938501518584015160608701516101408c01516101608d015196518b9873ffffffffffffffffffffffffffffffffffffffff9788169897909616967f0bcc4c97732e47d9946f229edb95f5b6323f601300e4690de719993f3c37112996612b46968f96339692959194909390615433565b60405180910390a45050505050565b60018054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101008789161502019095169490940493840181900481028201810190925282815260609390929091830182828015612bfe5780601f10612bd357610100808354040283529160200191612bfe565b820191906000526020600020905b815481529060010190602001808311612be157829003601f168201915b50505050509050612c2685610140015186600001518660000151856020015160200151613a23565b61014084015184518651845160200151612c4293929190613a23565b612c5b8561014001518660000151858560400151613a23565b612c778186600001518760400151856000015160400151613a23565b612c938185600001518660400151856020015160400151613a23565b836040015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff161415612cfd57612cf881848760400151612cf3866000015160600151876020015160600151613864565b613a23565b612aa2565b612d1581848760400151856000015160600151613a23565b612aa281848660400151856020015160600151613a23565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b81811015612e34578351855260209485019490930192600101612e16565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b81811015612e7d578351855260209485019490930192600101612e5f565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b81811015612ec5578351855260209485019490930192600101612ea7565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b612f076143de565b612f1082611f30565b9050612f1c8282613bed565b612805828260200151613d04565b612f32614386565b612f3d8484846124df565b6020810151909150831461260a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061574d565b600082821115612fb9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061560d565b508082035b92915050565b6000808251111515613002576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156fd565b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061303257fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b6000816020018351101515156130ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061562d565b50016020015190565b6040516000906060907f1626ba7e000000000000000000000000000000000000000000000000000000009061310e908790869060240161554e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093178352815191935090829081885afa8080156131ab576001811461321c57612572565b7f08c379a0000000000000000000000000000000000000000000000000000000006000527c20000000000000000000000000000000000000000000000000000000006020527c0c57414c4c45545f4552524f5200000000000000000000000000000000604052600060605260646000fd5b50505195945050505050565b60006014825110151515613268576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061578d565b613276826014845103613dab565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b6040516000906060907f9363470200000000000000000000000000000000000000000000000000000000906132de90879087908790602401615521565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783528151919350908290818a5afa80801561337b57600181146133ec576133f1565b7f08c379a0000000000000000000000000000000000000000000000000000000006000527c20000000000000000000000000000000000000000000000000000000006020527c0f56414c494441544f525f4552524f5200000000000000000000000000604052600060605260646000fd5b825194505b50505050949350505050565b6000808311613438576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b61344b61344585846138ae565b84613e0c565b949350505050565b604080517f5a65726f45785472616e73616374696f6e2800000000000000000000000000006020808301919091527f75696e743235362073616c742c0000000000000000000000000000000000000060328301527f61646472657373207369676e6572416464726573732c00000000000000000000603f8301527f627974657320646174610000000000000000000000000000000000000000000060558301527f2900000000000000000000000000000000000000000000000000000000000000605f830152825180830384018152606090920192839052815160009384938493909282918401908083835b6020831061357c57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161353f565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260405191909301819003812089519097508995509093508392850191508083835b6020831061361257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016135d5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822097825281019a909a525073ffffffffffffffffffffffffffffffffffffffff97909716968801969096525050606085015250506080909120919050565b600280546040517f190100000000000000000000000000000000000000000000000000000000000081529182015260228101919091526042902090565b6000612fbe611afd83613e23565b60008183106136ee578161260a565b5090919050565b6136fd614386565b6020810182905260a08301516080840151613719918491613909565b808252608084015160c0850151613731929190613909565b604082015260a083015160e084015161374b918491613909565b606082015292915050565b60018054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156137ff5780601f106137d4576101008083540402835291602001916137ff565b820191906000526020600020905b8154815290600101906020018083116137e257829003601f168201915b5050505050905061381f8461014001518560000151858560000151613a23565b6138388461016001518486600001518560200151613a23565b61385081856000015186604001518560400151613a23565b6127a3818486604001518560600151613a23565b6000828201838110156138a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061567d565b8091505b5092915050565b6000808315156138c157600091506138a7565b508282028284828115156138d157fe5b04146138a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061567d565b6000808311613944576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b61394f84848461427c565b15613438576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156ad565b60008083116139c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b6139cc848484614301565b15613a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156ad565b61344b613445613a1386856138ae565b613a1e866001612f7d565b613864565b600080600083118015613a6257508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b15613be5578551600310613aa2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061573d565b50506020848101517fffffffff00000000000000000000000000000000000000000000000000000000166000818152600b90925260409091205473ffffffffffffffffffffffffffffffffffffffff16801515613b2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156ed565b604051660fffffffffffe0603f885101168060840182017fa85e59e40000000000000000000000000000000000000000000000000000000083526080600484015273ffffffffffffffffffffffffffffffffffffffff8816602484015273ffffffffffffffffffffffffffffffffffffffff87166044840152856064840152608483015b81811015613bc757895181526020998a019901613baf565b61020084858403866000895af1801515613bdf573d85fd5b50505050505b505050505050565b805160009060ff16600314613c2e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061579d565b606083015173ffffffffffffffffffffffffffffffffffffffff1615613ca157606083015173ffffffffffffffffffffffffffffffffffffffff163314613ca1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157ad565b613ca96125df565b835190915073ffffffffffffffffffffffffffffffffffffffff808316911614613cff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061566d565b505050565b6000818152600560205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558281015183516101408501516101608601519351859473ffffffffffffffffffffffffffffffffffffffff9485169493909316927fdc47b3613d9fe400085f6dbdc99453462279057e6207385042827ed6b1a62cf792613d9f923392906154b7565b60405180910390a45050565b600081601401835110151515613ded576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061578d565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b6000808284811515613e1a57fe5b04949350505050565b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b90920192839052815160009384938493849391929182918401908083835b602083106140ab57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161406e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101408b0151805191995095509093508392850191508083835b6020831061414657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101614109565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101608b0151805191985095509093508392850191508083835b602083106141e157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016141a4565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909116921691909117905260405192018290039091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180516101408b018051610160909c0180519a84529881529288526101a0822091529890525050509190525090919050565b6000808084116142b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b8215806142c3575084155b156142d15760009150610a88565b838015156142db57fe5b85840990506142ea85846138ae565b6142f66103e8836138ae565b101595945050505050565b60008080841161433d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b821580614348575084155b156143565760009150610a88565b8380151561436057fe5b8584099050836143708583612f7d565b81151561437957fe5b0690506142ea85846138ae565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b610120604051908101604052806143c4614386565b81526020016143d1614386565b8152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b600061260a82356158b0565b6000601f8201831361441b57600080fd5b813561442e6144298261583f565b615818565b81815260209384019390925082018360005b8381101561446c578135860161445688826145bc565b8452506020928301929190910190600101614440565b5050505092915050565b6000601f8201831361448757600080fd5b81356144956144298261583f565b81815260209384019390925082018360005b8381101561446c57813586016144bd888261460b565b84525060209283019291909101906001016144a7565b6000601f820183136144e457600080fd5b81356144f26144298261583f565b9150818183526020840193506020810190508385602084028201111561451757600080fd5b60005b8381101561446c578161452d888261454f565b845250602092830192919091019060010161451a565b600061260a82356158c9565b600061260a82356158ce565b600061260a82356158d1565b600061260a82516158d1565b600080601f8301841361458557600080fd5b50813567ffffffffffffffff81111561459d57600080fd5b6020830191508360018202830111156145b557600080fd5b9250929050565b6000601f820183136145cd57600080fd5b81356145db61442982615860565b915080825260208301602083018583830111156145f757600080fd5b614602838284615907565b50505092915050565b6000610180828403121561461e57600080fd5b614629610180615818565b9050600061463784846143fe565b8252506020614648848483016143fe565b602083015250604061465c848285016143fe565b6040830152506060614670848285016143fe565b60608301525060806146848482850161454f565b60808301525060a06146988482850161454f565b60a08301525060c06146ac8482850161454f565b60c08301525060e06146c08482850161454f565b60e0830152506101006146d58482850161454f565b610100830152506101206146eb8482850161454f565b6101208301525061014082013567ffffffffffffffff81111561470d57600080fd5b614719848285016145bc565b6101408301525061016082013567ffffffffffffffff81111561473b57600080fd5b614747848285016145bc565b6101608301525092915050565b60006020828403121561476657600080fd5b600061344b84846143fe565b6000806040838503121561478557600080fd5b600061479185856143fe565b92505060206147a2858286016143fe565b9150509250929050565b600080604083850312156147bf57600080fd5b60006147cb85856143fe565b92505060206147a285828601614543565b6000602082840312156147ee57600080fd5b813567ffffffffffffffff81111561480557600080fd5b61344b84828501614476565b60008060006060848603121561482657600080fd5b833567ffffffffffffffff81111561483d57600080fd5b61484986828701614476565b935050602084013567ffffffffffffffff81111561486657600080fd5b614872868287016144d3565b925050604084013567ffffffffffffffff81111561488f57600080fd5b61489b8682870161440a565b9150509250925092565b6000806000606084860312156148ba57600080fd5b833567ffffffffffffffff8111156148d157600080fd5b6148dd86828701614476565b93505060206148728682870161454f565b60006020828403121561490057600080fd5b600061344b848461454f565b6000806040838503121561491f57600080fd5b6000614791858561454f565b6000806000806060858703121561494157600080fd5b600061494d878761454f565b945050602061495e878288016143fe565b935050604085013567ffffffffffffffff81111561497b57600080fd5b61498787828801614573565b95989497509550505050565b6000806000606084860312156149a857600080fd5b60006149b4868661454f565b93505060206149c5868287016143fe565b925050604084013567ffffffffffffffff8111156149e257600080fd5b61489b868287016145bc565b600060208284031215614a0057600080fd5b600061344b848461455b565b600060208284031215614a1e57600080fd5b600061344b8484614567565b600060208284031215614a3c57600080fd5b813567ffffffffffffffff811115614a5357600080fd5b61344b8482850161460b565b60008060008060808587031215614a7557600080fd5b843567ffffffffffffffff811115614a8c57600080fd5b614a988782880161460b565b945050602085013567ffffffffffffffff811115614ab557600080fd5b614ac18782880161460b565b935050604085013567ffffffffffffffff811115614ade57600080fd5b614aea878288016145bc565b925050606085013567ffffffffffffffff811115614b0757600080fd5b614b13878288016145bc565b91505092959194509250565b600080600060608486031215614b3457600080fd5b833567ffffffffffffffff811115614b4b57600080fd5b614b578682870161460b565b93505060206149c58682870161454f565b60008060008060008060808789031215614b8157600080fd5b6000614b8d898961454f565b9650506020614b9e89828a016143fe565b955050604087013567ffffffffffffffff811115614bbb57600080fd5b614bc789828a01614573565b9450945050606087013567ffffffffffffffff811115614be657600080fd5b614bf289828a01614573565b92509250509295509295509295565b614c0a816158b0565b82525050565b6000614c1b826158ac565b808452602084019350614c2d836158a6565b60005b82811015614c5d57614c438683516153e5565b614c4c826158a6565b606096909601959150600101614c30565b5093949350505050565b614c0a816158c9565b614c0a816158ce565b614c0a816158d1565b6000614c8d826158ac565b808452614ca1816020860160208601615913565b614caa8161593f565b9093016020019392505050565b614c0a816158fc565b601281527f4c454e4754485f36355f52455155495245440000000000000000000000000000602082015260400190565b600d81527f494e56414c49445f54414b455200000000000000000000000000000000000000602082015260400190565b600e81527f4f524445525f4f56455246494c4c000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f414c52454144595f455849535453000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601581527f5349474e41545552455f554e535550504f525445440000000000000000000000602082015260400190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601781527f494e56414c49445f4f524445525f5349474e4154555245000000000000000000602082015260400190565b600d81527f494e56414c49445f4d414b455200000000000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b600f81527f494e56414c49445f54585f484153480000000000000000000000000000000000602082015260400190565b601181527f494e56414c49445f5349474e4154555245000000000000000000000000000000602082015260400190565b600e81527f524f554e44494e475f4552524f52000000000000000000000000000000000000602082015260400190565b601081527f4641494c45445f455845435554494f4e00000000000000000000000000000000602082015260400190565b600d81527f54414b45525f4f56455250415900000000000000000000000000000000000000602082015260400190565b601481527f494e56414c49445f54414b45525f414d4f554e54000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f444f45535f4e4f545f4558495354000000000000602082015260400190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f5349474e41545552455f494c4c4547414c000000000000000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000602082015260400190565b601781527f494e56414c49445f4e45575f4f524445525f45504f4348000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f335f52455155495245440000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601281527f494e56414c49445f46494c4c5f50524943450000000000000000000000000000602082015260400190565b601281527f5245454e5452414e43595f494c4c4547414c0000000000000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4f524445525f554e46494c4c41424c4500000000000000000000000000000000602082015260400190565b600e81527f494e56414c49445f53454e444552000000000000000000000000000000000000602082015260400190565b601881527f4e454741544956455f5350524541445f52455155495245440000000000000000602082015260400190565b601481527f494e56414c49445f54585f5349474e4154555245000000000000000000000000602082015260400190565b601181527f4c454e4754485f305f5245515549524544000000000000000000000000000000602082015260400190565b805160808301906153738482614c70565b5060208201516153866020850182614c70565b5060408201516153996040850182614c70565b5060608201516127a36060850182614c70565b80516101208301906153be8482615362565b5060208201516153d16080850182615362565b5060408201516127a3610100850182614c70565b805160608301906153f6848261541c565b5060208201516154096020850182614c70565b5060408201516127a36040850182614c70565b614c0a816158f6565b60208101612fbe8284614c01565b6101008101615442828b614c01565b61544f602083018a614c01565b61545c6040830189614c70565b6154696060830188614c70565b6154766080830187614c70565b61548360a0830186614c70565b81810360c08301526154958185614c82565b905081810360e08301526154a98184614c82565b9a9950505050505050505050565b606081016154c58286614c01565b81810360208301526154d78185614c82565b905081810360408301526154eb8184614c82565b95945050505050565b6020808252810161260a8184614c10565b60208101612fbe8284614c67565b60208101612fbe8284614c70565b6060810161552f8286614c70565b61553c6020830185614c01565b81810360408301526154eb8184614c82565b6040810161555c8285614c70565b818103602083015261344b8184614c82565b6080810161557c8287614c70565b615589602083018661541c565b6155966040830185614c70565b6154eb6060830184614c70565b604081016155b18285614c79565b61260a6020830184614c01565b6020808252810161260a8184614c82565b60208101612fbe8284614cb7565b60208082528101612fbe81614cc0565b60208082528101612fbe81614cf0565b60208082528101612fbe81614d20565b60208082528101612fbe81614d50565b60208082528101612fbe81614d80565b60208082528101612fbe81614db0565b60208082528101612fbe81614e06565b60208082528101612fbe81614e36565b60208082528101612fbe81614e66565b60208082528101612fbe81614e96565b60208082528101612fbe81614ec6565b60208082528101612fbe81614ef6565b60208082528101612fbe81614f26565b60208082528101612fbe81614f56565b60208082528101612fbe81614f86565b60208082528101612fbe81614fb6565b60208082528101612fbe81614fe6565b60208082528101612fbe81615016565b60208082528101612fbe81615046565b60208082528101612fbe8161509c565b60208082528101612fbe816150cc565b60208082528101612fbe816150fc565b60208082528101612fbe8161512c565b60208082528101612fbe8161515c565b60208082528101612fbe8161518c565b60208082528101612fbe816151bc565b60208082528101612fbe816151ec565b60208082528101612fbe8161521c565b60208082528101612fbe81615272565b60208082528101612fbe816152a2565b60208082528101612fbe816152d2565b60208082528101612fbe81615302565b60208082528101612fbe81615332565b60808101612fbe8284615362565b6101208101612fbe82846153ac565b60608101612fbe82846153e5565b60405181810167ffffffffffffffff8111828210171561583757600080fd5b604052919050565b600067ffffffffffffffff82111561585657600080fd5b5060209081020190565b600067ffffffffffffffff82111561587757600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b60200190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b60ff1690565b6000612fbe826158b0565b82818337506000910152565b60005b8381101561592e578181015183820152602001615916565b838111156127a35750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820d41ee66f45c4d1637cb6e5f109447c6d5d7fef3204a685dc442151c0f029b7da6c6578706572696d656e74616cf50037",
- "storage": {
- "0x1458d05345aa0372fb580f207529f32cbb6e9242890d36a93225785d4496083e": "0x0000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48"
- }
- },
- "0x5409ed021d9299bf6814279a6a1411a7e866a631": {
- "balance": "0xac6bd1cc338c2000",
- "nonce": "22",
- "code": "0x",
- "storage": {}
- },
- "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x606060405236156100965763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde038114610098578063095ea7b31461014657806318160ddd1461018657806323b872dd146101a8578063313ce567146101ee57806370a082311461021457806395d89b411461024f578063a9059cbb146102fd578063dd62ed3e1461033d575bfe5b34156100a057fe5b6100a861037e565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014e57fe5b61017273ffffffffffffffffffffffffffffffffffffffff600435166024356103b5565b604080519115158252519081900360200190f35b341561018e57fe5b61019661042d565b60408051918252519081900360200190f35b34156101b057fe5b61017273ffffffffffffffffffffffffffffffffffffffff60043581169060243516604435610433565b604080519115158252519081900360200190f35b34156101f657fe5b6101fe6105d4565b6040805160ff9092168252519081900360200190f35b341561021c57fe5b61019673ffffffffffffffffffffffffffffffffffffffff600435166105d9565b60408051918252519081900360200190f35b341561025757fe5b6100a8610605565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561030557fe5b61017273ffffffffffffffffffffffffffffffffffffffff6004351660243561063c565b604080519115158252519081900360200190f35b341561034557fe5b61019673ffffffffffffffffffffffffffffffffffffffff60043581169060243516610727565b60408051918252519081900360200190f35b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906104835750828110155b80156104b6575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156105c65773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156105585773ffffffffffffffffffffffffffffffffffffffff808616600090815260016020908152604080832033909416835292905220805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506105cb565b600091505b5b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020545b919050565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff3316600090815260208190526040812054829010801590610699575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b156107185773ffffffffffffffffffffffffffffffffffffffff33811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3506001610427565b506000610427565b5b92915050565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600160209081526040808320938516835292905220545b929150505600a165627a7a723058201b5b70cf82a73dec658c2e60ab9a0f8e2ba01a74b66a6f5b0402f56d2ea0ffcf0029",
- "storage": {
- "0xd37b858806ebf992fe75c1dd1a61cc7625ea52328d19005ba6b8b62506ae5306": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- }
- },
- "config": {
- "chainId": 5,
- "supportedProtocolVersions": [
- 67,
- 66
- ],
- "homesteadBlock": 0,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "eip155Block": 0,
- "eip158Block": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 0,
- "petersburgBlock": 0,
- "istanbulBlock": 1561651,
- "berlinBlock": 4460644,
- "londonBlock": 5062605,
- "terminalTotalDifficulty": 10790000,
- "terminalTotalDifficultyPassed": true,
- "clique": {
- "period": 15,
- "epoch": 30000
- },
- "trustedCheckpoint": {
- "sectionIndex": 210,
- "sectionHead": "0xbb11eaf551a6c06f74a6c7bbfe1699cbf64b8f248b64691da916dd443176db2f",
- "chtRoot": "0x9934ae326d00d9c7de2e074c0e51689efb7fa7fcba18929ff4279c27259c45e6",
- "bloomRoot": "0x7fe3bd4fd45194aa8a5cfe5ac590edff1f870d3d98d3c310494e7f67613a87ff"
- },
- "trustedCheckpointOracle": {
- "address": "0x18ca0e045f0d772a851bc7e48357bcaab0a0795d",
- "signers": [
- "0x4769bcad07e3b938b7f43eb7d278bc7cb9effb38",
- "0x78d1ad571a1a09d60d9bbf25894b44e4c8859595",
- "0x286834935f4a8cfb4ff4c77d5770c2775ae2b0e7",
- "0xb86e2b0ab5a4b1373e40c51a7c712c70ba2f9f8e",
- "0x0df8fa387c602ae62559cc4afa4972a7045d6707"
- ],
- "threshold": 2
- }
- }
- },
- "context": {
- "number": "13536",
- "difficulty": "1",
- "timestamp": "1549153018",
- "gasLimit": "8000000",
- "miner": "0x0000000000000000000000000000000000000000",
- "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e"
- },
- "input": "0xf92e9e1684ee6b2800832c8c7f8080b92e4c60806040523480156200001157600080fd5b5060405162002d2c38038062002d2c83398101806040526200003791908101906200051d565b6000805433600160a060020a031991821617825560018054909116600160a060020a0386161790558251849084908490849081906200007e906004906020870190620003d0565b50825162000094906005906020860190620003d0565b50620000b0836010640100000000620019476200036f82021704565b9150620000cd846010640100000000620019476200036f82021704565b60028054600160a060020a03948516600160a060020a031991821617909155600380549285169290911691909117905550600154604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130181207f6070410800000000000000000000000000000000000000000000000000000000825291909216945063607041089350620001739250906004016200068e565b602060405180830381600087803b1580156200018e57600080fd5b505af1158015620001a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620001c99190810190620004f4565b9050600160a060020a038116151562000219576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021090620006b0565b60405180910390fd5b6002546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b39062000268908490600019906004016200066f565b602060405180830381600087803b1580156200028357600080fd5b505af115801562000298573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620002be9190810190620005a1565b506003546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b3906200030e908490600019906004016200066f565b602060405180830381600087803b1580156200032957600080fd5b505af11580156200033e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620003649190810190620005a1565b50505050506200077a565b600081601401835110151515620003b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000210906200069e565b506014818301810151910190600160a060020a03165b92915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200041357805160ff191683800117855562000443565b8280016001018555821562000443579182015b828111156200044357825182559160200191906001019062000426565b506200045192915062000455565b5090565b6200047291905b808211156200045157600081556001016200045c565b90565b600062000483825162000711565b9392505050565b600062000483825162000742565b6000601f82018313620004aa57600080fd5b8151620004c1620004bb82620006e9565b620006c2565b91508082526020830160208301858383011115620004de57600080fd5b620004eb83828462000747565b50505092915050565b6000602082840312156200050757600080fd5b600062000515848462000475565b949350505050565b6000806000606084860312156200053357600080fd5b600062000541868662000475565b93505060208401516001604060020a038111156200055e57600080fd5b6200056c8682870162000498565b92505060408401516001604060020a038111156200058957600080fd5b620005978682870162000498565b9150509250925092565b600060208284031215620005b457600080fd5b60006200051584846200048a565b620005cd8162000711565b82525050565b620005cd816200071d565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601881527f554e524547495354455245445f41535345545f50524f58590000000000000000602082015260400190565b620005cd8162000472565b604081016200067f8285620005c2565b62000483602083018462000664565b60208101620003ca8284620005d3565b60208082528101620003ca81620005de565b60208082528101620003ca8162000634565b6040518181016001604060020a0381118282101715620006e157600080fd5b604052919050565b60006001604060020a038211156200070057600080fd5b506020601f91909101601f19160190565b600160a060020a031690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b151590565b60005b83811015620007645781810151838201526020016200074a565b8381111562000774576000848401525b50505050565b6125a2806200078a6000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318978e8281146100c8578063630f1e6c146100f25780638da5cb5b146101125780639395525c14610134578063f2fde38b14610147575b60025473ffffffffffffffffffffffffffffffffffffffff1633146100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612388565b60405180910390fd5b005b6100db6100d6366004611df1565b610167565b6040516100e9929190612488565b60405180910390f35b3480156100fe57600080fd5b506100c661010d366004611eec565b6102f7565b34801561011e57600080fd5b50610127610388565b6040516100e99190612337565b6100db610142366004611d0b565b6103a4565b34801561015357600080fd5b506100c6610162366004611ce5565b61050a565b61016f6119fa565b6101776119fa565b6000806101826105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815261025c939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b50505050508c600081518110151561024157fe5b6020908102909101015161014001519063ffffffff61069616565b156102875761026c8b8b8b6107c3565b935061028084600001518560600151610ac1565b90506102ae565b6102928b8b8b610b03565b9350836060015191506102a68883896107c3565b845190935090505b6102c2846020015184602001518888610d15565b6102e98b60008151811015156102d457fe5b90602001906020020151610140015182610f29565b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610348576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b61038383838080601f01602080910402602001604051908101604052809392919081815260200183838082843750879450610f299350505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6103ac6119fa565b6103b46119fa565b60008060006103c16105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152610441939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b156104925761046a670de0b6b3a7640000610464670de0b6b3a76400008a611045565b3461108f565b92506104778b848c6110e7565b945061048b85600001518660600151610ac1565b90506104d6565b6104ad670d2f13f7789f0000670de0b6b3a76400003461108f565b92506104ba8b848c6110e7565b9450846060015191506104ce89838a6107c3565b855190945090505b6104ea856020015185602001518989610d15565b6104fc8b60008151811015156102d457fe5b505050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b73ffffffffffffffffffffffffffffffffffffffff8116156105b857600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600034116105f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612398565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b5050505050565b6000815183511480156107ba5750816040518082805190602001908083835b602083106106f257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016106b5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b6020831061078757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161074a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b90505b92915050565b6107cb6119fa565b60608060008060008060006107de6119fa565b8a15156107ea57610ab2565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561088e5780601f106108635761010080835404028352916020019161088e565b820191906000526020600020905b81548152906001019060200180831161087157829003601f168201915b505060058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152969e509194509250840190508282801561093d5780601f106109125761010080835404028352916020019161093d565b820191906000526020600020905b81548152906001019060200180831161092057829003601f168201915b50505050509650600095508b519450600093505b838514610a7857878c8581518110151561096757fe5b6020908102909101015161014001528b5187908d908690811061098657fe5b60209081029091010151610160015261099f8b87610ac1565b9250610a068c858151811015156109b257fe5b9060200190602002015160a00151610a008e878151811015156109d157fe5b90602001906020020151608001518f888151811015156109ed57fe5b9060200190602002015160e00151610ac1565b8561128b565b9150610a418c85815181101515610a1957fe5b90602001906020020151838c87815181101515610a3257fe5b906020019060200201516112e6565b9050610a4d898261135e565b610a5f89600001518a60600151610ac1565b95508a8610610a6d57610a78565b600190930192610951565b8a861015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b50505050505050509392505050565b600082821115610afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123b8565b50900390565b610b0b6119fa565b606080600080600080610b1c6119fa565b60008b6000815181101515610b2d57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929b5092909190830182828015610be55780601f10610bba57610100808354040283529160200191610be5565b820191906000526020600020905b815481529060010190602001808311610bc857829003601f168201915b505050505096508b519550600094505b848614610cdb57878c86815181101515610c0b57fe5b6020908102909101015161014001528b5187908d9087908110610c2a57fe5b6020908102909101015161016001528851610c46908c90610ac1565b9350610c898c86815181101515610c5957fe5b9060200190602002015160a001518d87815181101515610c7557fe5b90602001906020020151608001518661128b565b9250610cb58c86815181101515610c9c57fe5b90602001906020020151848c88815181101515610a3257fe5b9150610cc1898361135e565b5087518a8110610cd057610cdb565b600190940193610bf5565b8a811015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b600080808066b1a2bc2ec50000861115610d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612448565b610d658888611045565b935034841115610da1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123a8565b610dab3485610ac1565b9250610dc086670de0b6b3a76400008a61108f565b915082821115610dfc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612428565b6000831115610f1f576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90610e5b9086906004016124a4565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b505050506000821115610edb5760405173ffffffffffffffffffffffffffffffffffffffff86169083156108fc029084906000818181858888f19350505050158015610ed9573d6000803e3d6000fd5b505b610ee58383610ac1565b90506000811115610f1f57604051339082156108fc029083906000818181858888f19350505050158015610f1d573d6000803e3d6000fd5b505b5050505050505050565b6000610f3b838263ffffffff6113c016565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff0000000000000000000000000000000000000000000000000000000080831691161415610fab57610fa6838361142d565b610383565b604080517f455243373231546f6b656e28616464726573732c75696e7432353629000000008152905190819003601c0190207fffffffff000000000000000000000000000000000000000000000000000000008281169116141561101357610fa6838361161b565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123f8565b600082820183811015611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b8091505b5092915050565b60008083116110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d78584611703565b8461175e565b90505b9392505050565b6110ef6119fa565b60608060008060006110ff6119fa565b89600081518110151561110e57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929950929091908301828280156111c65780601f1061119b576101008083540402835291602001916111c6565b820191906000526020600020905b8154815290600101906020018083116111a957829003601f168201915b5050505050945089519350600092505b82841461127e57858a848151811015156111ec57fe5b602090810290910101516101400152895185908b908590811061120b57fe5b90602001906020020151610160018190525061122b898860200151610ac1565b91506112578a8481518110151561123e57fe5b90602001906020020151838a86815181101515610a3257fe5b9050611263878261135e565b602087015189116112735761127e565b6001909201916111d6565b5050505050509392505050565b60008083116112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d76112d68685611703565b6112e1866001610ac1565b611045565b6112ee6119fa565b606060006112fd868686611775565b600154815191935073ffffffffffffffffffffffffffffffffffffffff1691506080908390602082016000855af1801561135457825184526020830151602085015260408301516040850152606083015160608501525b5050509392505050565b8151815161136c9190611045565b8252602080830151908201516113829190611045565b60208301526040808301519082015161139b9190611045565b6040830152606080830151908201516113b49190611045565b60609092019190915250565b600081600401835110151515611402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612468565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b60008061144184601063ffffffff61194716565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812091935073ffffffffffffffffffffffffffffffffffffffff8416919061149f903390879060240161236d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b8381101561154357818101518382015260200161152b565b50505050905090810190601f1680156115705780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1925050508015156115bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b3d156115dc575060003d602014156115dc5760206000803e506000515b801515611615576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b50505050565b60008060018314611658576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612478565b61166984601063ffffffff61194716565b915061167c84602463ffffffff6119a816565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906116d590309033908690600401612345565b600060405180830381600087803b1580156116ef57600080fd5b505af1158015610f1f573d6000803e3d6000fd5b6000808315156117165760009150611088565b5082820282848281151561172657fe5b0414611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b600080828481151561176c57fe5b04949350505050565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b8181101561187c57835185526020948501949093019260010161185e565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b818110156118c55783518552602094850194909301926001016118a7565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b8181101561190d5783518552602094850194909301926001016118ef565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b600081601401835110151515611989576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612458565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006107ba83836000816020018351101515156119f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123c8565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006107ba8235612540565b6000601f82018313611a4057600080fd5b8135611a53611a4e826124d9565b6124b2565b81815260209384019390925082018360005b83811015611a915781358601611a7b8882611b41565b8452506020928301929190910190600101611a65565b5050505092915050565b6000601f82018313611aac57600080fd5b8135611aba611a4e826124d9565b81815260209384019390925082018360005b83811015611a915781358601611ae28882611b90565b8452506020928301929190910190600101611acc565b600080601f83018413611b0a57600080fd5b50813567ffffffffffffffff811115611b2257600080fd5b602083019150836001820283011115611b3a57600080fd5b9250929050565b6000601f82018313611b5257600080fd5b8135611b60611a4e826124fa565b91508082526020830160208301858383011115611b7c57600080fd5b611b8783828461255c565b50505092915050565b60006101808284031215611ba357600080fd5b611bae6101806124b2565b90506000611bbc8484611a23565b8252506020611bcd84848301611a23565b6020830152506040611be184828501611a23565b6040830152506060611bf584828501611a23565b6060830152506080611c0984828501611cd9565b60808301525060a0611c1d84828501611cd9565b60a08301525060c0611c3184828501611cd9565b60c08301525060e0611c4584828501611cd9565b60e083015250610100611c5a84828501611cd9565b61010083015250610120611c7084828501611cd9565b6101208301525061014082013567ffffffffffffffff811115611c9257600080fd5b611c9e84828501611b41565b6101408301525061016082013567ffffffffffffffff811115611cc057600080fd5b611ccc84828501611b41565b6101608301525092915050565b60006107ba8235612559565b600060208284031215611cf757600080fd5b6000611d038484611a23565b949350505050565b60008060008060008060c08789031215611d2457600080fd5b863567ffffffffffffffff811115611d3b57600080fd5b611d4789828a01611a9b565b965050602087013567ffffffffffffffff811115611d6457600080fd5b611d7089828a01611a2f565b955050604087013567ffffffffffffffff811115611d8d57600080fd5b611d9989828a01611a9b565b945050606087013567ffffffffffffffff811115611db657600080fd5b611dc289828a01611a2f565b9350506080611dd389828a01611cd9565b92505060a0611de489828a01611a23565b9150509295509295509295565b600080600080600080600060e0888a031215611e0c57600080fd5b873567ffffffffffffffff811115611e2357600080fd5b611e2f8a828b01611a9b565b9750506020611e408a828b01611cd9565b965050604088013567ffffffffffffffff811115611e5d57600080fd5b611e698a828b01611a2f565b955050606088013567ffffffffffffffff811115611e8657600080fd5b611e928a828b01611a9b565b945050608088013567ffffffffffffffff811115611eaf57600080fd5b611ebb8a828b01611a2f565b93505060a0611ecc8a828b01611cd9565b92505060c0611edd8a828b01611a23565b91505092959891949750929550565b600080600060408486031215611f0157600080fd5b833567ffffffffffffffff811115611f1857600080fd5b611f2486828701611af8565b93509350506020611f3786828701611cd9565b9150509250925092565b611f4a81612540565b82525050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b600d81527f4f564552534f4c445f5745544800000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601781527f554e535550504f525445445f41535345545f50524f5859000000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601a81527f494e53554646494349454e545f4554485f52454d41494e494e47000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b601881527f4645455f50455243454e544147455f544f4f5f4c415247450000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160808301906122f9848261232e565b50602082015161230c602085018261232e565b50604082015161231f604085018261232e565b50606082015161161560608501825b611f4a81612559565b602081016107bd8284611f41565b606081016123538286611f41565b6123606020830185611f41565b611d03604083018461232e565b6040810161237b8285611f41565b6110e0602083018461232e565b602080825281016107bd81611f50565b602080825281016107bd81611fa6565b602080825281016107bd81611fd6565b602080825281016107bd81612006565b602080825281016107bd81612036565b602080825281016107bd8161208c565b602080825281016107bd816120bc565b602080825281016107bd816120ec565b602080825281016107bd8161211c565b602080825281016107bd8161214c565b602080825281016107bd8161217c565b602080825281016107bd816121ac565b602080825281016107bd816121dc565b602080825281016107bd8161220c565b602080825281016107bd81612262565b602080825281016107bd816122b8565b610100810161249782856122e8565b6110e060808301846122e8565b602081016107bd828461232e565b60405181810167ffffffffffffffff811182821017156124d157600080fd5b604052919050565b600067ffffffffffffffff8211156124f057600080fd5b5060209081020190565b600067ffffffffffffffff82111561251157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b828183375060009101525600a265627a7a72305820d9f418f11e0f91f06f6f9d22924be0add925495eeb76a6388b5417adb505eeb36c6578706572696d656e74616cf5003700000000000000000000000048bacb9266a570d521063ef5dd96e61686dbe788000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082000000000000000000000000000000000000000000000000000000001ba0a7c6b0c9a5cb47eb4a8449556851a943353640d4fe93a64eb89eff56245c27f1a00e0d13877bfb8842dc394fd206d041b1f76be95a371eff128c8c34812a1b24c8",
- "result": [
- {
- "action": {
- "from": "0x5409ed021d9299bf6814279a6a1411a7e866a631",
- "gas": "0x2c8c7f",
- "init": "0x60806040523480156200001157600080fd5b5060405162002d2c38038062002d2c83398101806040526200003791908101906200051d565b6000805433600160a060020a031991821617825560018054909116600160a060020a0386161790558251849084908490849081906200007e906004906020870190620003d0565b50825162000094906005906020860190620003d0565b50620000b0836010640100000000620019476200036f82021704565b9150620000cd846010640100000000620019476200036f82021704565b60028054600160a060020a03948516600160a060020a031991821617909155600380549285169290911691909117905550600154604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130181207f6070410800000000000000000000000000000000000000000000000000000000825291909216945063607041089350620001739250906004016200068e565b602060405180830381600087803b1580156200018e57600080fd5b505af1158015620001a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620001c99190810190620004f4565b9050600160a060020a038116151562000219576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021090620006b0565b60405180910390fd5b6002546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b39062000268908490600019906004016200066f565b602060405180830381600087803b1580156200028357600080fd5b505af115801562000298573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620002be9190810190620005a1565b506003546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b3906200030e908490600019906004016200066f565b602060405180830381600087803b1580156200032957600080fd5b505af11580156200033e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620003649190810190620005a1565b50505050506200077a565b600081601401835110151515620003b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000210906200069e565b506014818301810151910190600160a060020a03165b92915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200041357805160ff191683800117855562000443565b8280016001018555821562000443579182015b828111156200044357825182559160200191906001019062000426565b506200045192915062000455565b5090565b6200047291905b808211156200045157600081556001016200045c565b90565b600062000483825162000711565b9392505050565b600062000483825162000742565b6000601f82018313620004aa57600080fd5b8151620004c1620004bb82620006e9565b620006c2565b91508082526020830160208301858383011115620004de57600080fd5b620004eb83828462000747565b50505092915050565b6000602082840312156200050757600080fd5b600062000515848462000475565b949350505050565b6000806000606084860312156200053357600080fd5b600062000541868662000475565b93505060208401516001604060020a038111156200055e57600080fd5b6200056c8682870162000498565b92505060408401516001604060020a038111156200058957600080fd5b620005978682870162000498565b9150509250925092565b600060208284031215620005b457600080fd5b60006200051584846200048a565b620005cd8162000711565b82525050565b620005cd816200071d565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601881527f554e524547495354455245445f41535345545f50524f58590000000000000000602082015260400190565b620005cd8162000472565b604081016200067f8285620005c2565b62000483602083018462000664565b60208101620003ca8284620005d3565b60208082528101620003ca81620005de565b60208082528101620003ca8162000634565b6040518181016001604060020a0381118282101715620006e157600080fd5b604052919050565b60006001604060020a038211156200070057600080fd5b506020601f91909101601f19160190565b600160a060020a031690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b151590565b60005b83811015620007645781810151838201526020016200074a565b8381111562000774576000848401525b50505050565b6125a2806200078a6000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318978e8281146100c8578063630f1e6c146100f25780638da5cb5b146101125780639395525c14610134578063f2fde38b14610147575b60025473ffffffffffffffffffffffffffffffffffffffff1633146100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612388565b60405180910390fd5b005b6100db6100d6366004611df1565b610167565b6040516100e9929190612488565b60405180910390f35b3480156100fe57600080fd5b506100c661010d366004611eec565b6102f7565b34801561011e57600080fd5b50610127610388565b6040516100e99190612337565b6100db610142366004611d0b565b6103a4565b34801561015357600080fd5b506100c6610162366004611ce5565b61050a565b61016f6119fa565b6101776119fa565b6000806101826105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815261025c939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b50505050508c600081518110151561024157fe5b6020908102909101015161014001519063ffffffff61069616565b156102875761026c8b8b8b6107c3565b935061028084600001518560600151610ac1565b90506102ae565b6102928b8b8b610b03565b9350836060015191506102a68883896107c3565b845190935090505b6102c2846020015184602001518888610d15565b6102e98b60008151811015156102d457fe5b90602001906020020151610140015182610f29565b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610348576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b61038383838080601f01602080910402602001604051908101604052809392919081815260200183838082843750879450610f299350505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6103ac6119fa565b6103b46119fa565b60008060006103c16105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152610441939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b156104925761046a670de0b6b3a7640000610464670de0b6b3a76400008a611045565b3461108f565b92506104778b848c6110e7565b945061048b85600001518660600151610ac1565b90506104d6565b6104ad670d2f13f7789f0000670de0b6b3a76400003461108f565b92506104ba8b848c6110e7565b9450846060015191506104ce89838a6107c3565b855190945090505b6104ea856020015185602001518989610d15565b6104fc8b60008151811015156102d457fe5b505050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b73ffffffffffffffffffffffffffffffffffffffff8116156105b857600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600034116105f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612398565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b5050505050565b6000815183511480156107ba5750816040518082805190602001908083835b602083106106f257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016106b5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b6020831061078757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161074a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b90505b92915050565b6107cb6119fa565b60608060008060008060006107de6119fa565b8a15156107ea57610ab2565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561088e5780601f106108635761010080835404028352916020019161088e565b820191906000526020600020905b81548152906001019060200180831161087157829003601f168201915b505060058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152969e509194509250840190508282801561093d5780601f106109125761010080835404028352916020019161093d565b820191906000526020600020905b81548152906001019060200180831161092057829003601f168201915b50505050509650600095508b519450600093505b838514610a7857878c8581518110151561096757fe5b6020908102909101015161014001528b5187908d908690811061098657fe5b60209081029091010151610160015261099f8b87610ac1565b9250610a068c858151811015156109b257fe5b9060200190602002015160a00151610a008e878151811015156109d157fe5b90602001906020020151608001518f888151811015156109ed57fe5b9060200190602002015160e00151610ac1565b8561128b565b9150610a418c85815181101515610a1957fe5b90602001906020020151838c87815181101515610a3257fe5b906020019060200201516112e6565b9050610a4d898261135e565b610a5f89600001518a60600151610ac1565b95508a8610610a6d57610a78565b600190930192610951565b8a861015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b50505050505050509392505050565b600082821115610afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123b8565b50900390565b610b0b6119fa565b606080600080600080610b1c6119fa565b60008b6000815181101515610b2d57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929b5092909190830182828015610be55780601f10610bba57610100808354040283529160200191610be5565b820191906000526020600020905b815481529060010190602001808311610bc857829003601f168201915b505050505096508b519550600094505b848614610cdb57878c86815181101515610c0b57fe5b6020908102909101015161014001528b5187908d9087908110610c2a57fe5b6020908102909101015161016001528851610c46908c90610ac1565b9350610c898c86815181101515610c5957fe5b9060200190602002015160a001518d87815181101515610c7557fe5b90602001906020020151608001518661128b565b9250610cb58c86815181101515610c9c57fe5b90602001906020020151848c88815181101515610a3257fe5b9150610cc1898361135e565b5087518a8110610cd057610cdb565b600190940193610bf5565b8a811015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b600080808066b1a2bc2ec50000861115610d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612448565b610d658888611045565b935034841115610da1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123a8565b610dab3485610ac1565b9250610dc086670de0b6b3a76400008a61108f565b915082821115610dfc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612428565b6000831115610f1f576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90610e5b9086906004016124a4565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b505050506000821115610edb5760405173ffffffffffffffffffffffffffffffffffffffff86169083156108fc029084906000818181858888f19350505050158015610ed9573d6000803e3d6000fd5b505b610ee58383610ac1565b90506000811115610f1f57604051339082156108fc029083906000818181858888f19350505050158015610f1d573d6000803e3d6000fd5b505b5050505050505050565b6000610f3b838263ffffffff6113c016565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff0000000000000000000000000000000000000000000000000000000080831691161415610fab57610fa6838361142d565b610383565b604080517f455243373231546f6b656e28616464726573732c75696e7432353629000000008152905190819003601c0190207fffffffff000000000000000000000000000000000000000000000000000000008281169116141561101357610fa6838361161b565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123f8565b600082820183811015611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b8091505b5092915050565b60008083116110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d78584611703565b8461175e565b90505b9392505050565b6110ef6119fa565b60608060008060006110ff6119fa565b89600081518110151561110e57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929950929091908301828280156111c65780601f1061119b576101008083540402835291602001916111c6565b820191906000526020600020905b8154815290600101906020018083116111a957829003601f168201915b5050505050945089519350600092505b82841461127e57858a848151811015156111ec57fe5b602090810290910101516101400152895185908b908590811061120b57fe5b90602001906020020151610160018190525061122b898860200151610ac1565b91506112578a8481518110151561123e57fe5b90602001906020020151838a86815181101515610a3257fe5b9050611263878261135e565b602087015189116112735761127e565b6001909201916111d6565b5050505050509392505050565b60008083116112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d76112d68685611703565b6112e1866001610ac1565b611045565b6112ee6119fa565b606060006112fd868686611775565b600154815191935073ffffffffffffffffffffffffffffffffffffffff1691506080908390602082016000855af1801561135457825184526020830151602085015260408301516040850152606083015160608501525b5050509392505050565b8151815161136c9190611045565b8252602080830151908201516113829190611045565b60208301526040808301519082015161139b9190611045565b6040830152606080830151908201516113b49190611045565b60609092019190915250565b600081600401835110151515611402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612468565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b60008061144184601063ffffffff61194716565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812091935073ffffffffffffffffffffffffffffffffffffffff8416919061149f903390879060240161236d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b8381101561154357818101518382015260200161152b565b50505050905090810190601f1680156115705780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1925050508015156115bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b3d156115dc575060003d602014156115dc5760206000803e506000515b801515611615576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b50505050565b60008060018314611658576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612478565b61166984601063ffffffff61194716565b915061167c84602463ffffffff6119a816565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906116d590309033908690600401612345565b600060405180830381600087803b1580156116ef57600080fd5b505af1158015610f1f573d6000803e3d6000fd5b6000808315156117165760009150611088565b5082820282848281151561172657fe5b0414611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b600080828481151561176c57fe5b04949350505050565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b8181101561187c57835185526020948501949093019260010161185e565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b818110156118c55783518552602094850194909301926001016118a7565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b8181101561190d5783518552602094850194909301926001016118ef565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b600081601401835110151515611989576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612458565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006107ba83836000816020018351101515156119f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123c8565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006107ba8235612540565b6000601f82018313611a4057600080fd5b8135611a53611a4e826124d9565b6124b2565b81815260209384019390925082018360005b83811015611a915781358601611a7b8882611b41565b8452506020928301929190910190600101611a65565b5050505092915050565b6000601f82018313611aac57600080fd5b8135611aba611a4e826124d9565b81815260209384019390925082018360005b83811015611a915781358601611ae28882611b90565b8452506020928301929190910190600101611acc565b600080601f83018413611b0a57600080fd5b50813567ffffffffffffffff811115611b2257600080fd5b602083019150836001820283011115611b3a57600080fd5b9250929050565b6000601f82018313611b5257600080fd5b8135611b60611a4e826124fa565b91508082526020830160208301858383011115611b7c57600080fd5b611b8783828461255c565b50505092915050565b60006101808284031215611ba357600080fd5b611bae6101806124b2565b90506000611bbc8484611a23565b8252506020611bcd84848301611a23565b6020830152506040611be184828501611a23565b6040830152506060611bf584828501611a23565b6060830152506080611c0984828501611cd9565b60808301525060a0611c1d84828501611cd9565b60a08301525060c0611c3184828501611cd9565b60c08301525060e0611c4584828501611cd9565b60e083015250610100611c5a84828501611cd9565b61010083015250610120611c7084828501611cd9565b6101208301525061014082013567ffffffffffffffff811115611c9257600080fd5b611c9e84828501611b41565b6101408301525061016082013567ffffffffffffffff811115611cc057600080fd5b611ccc84828501611b41565b6101608301525092915050565b60006107ba8235612559565b600060208284031215611cf757600080fd5b6000611d038484611a23565b949350505050565b60008060008060008060c08789031215611d2457600080fd5b863567ffffffffffffffff811115611d3b57600080fd5b611d4789828a01611a9b565b965050602087013567ffffffffffffffff811115611d6457600080fd5b611d7089828a01611a2f565b955050604087013567ffffffffffffffff811115611d8d57600080fd5b611d9989828a01611a9b565b945050606087013567ffffffffffffffff811115611db657600080fd5b611dc289828a01611a2f565b9350506080611dd389828a01611cd9565b92505060a0611de489828a01611a23565b9150509295509295509295565b600080600080600080600060e0888a031215611e0c57600080fd5b873567ffffffffffffffff811115611e2357600080fd5b611e2f8a828b01611a9b565b9750506020611e408a828b01611cd9565b965050604088013567ffffffffffffffff811115611e5d57600080fd5b611e698a828b01611a2f565b955050606088013567ffffffffffffffff811115611e8657600080fd5b611e928a828b01611a9b565b945050608088013567ffffffffffffffff811115611eaf57600080fd5b611ebb8a828b01611a2f565b93505060a0611ecc8a828b01611cd9565b92505060c0611edd8a828b01611a23565b91505092959891949750929550565b600080600060408486031215611f0157600080fd5b833567ffffffffffffffff811115611f1857600080fd5b611f2486828701611af8565b93509350506020611f3786828701611cd9565b9150509250925092565b611f4a81612540565b82525050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b600d81527f4f564552534f4c445f5745544800000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601781527f554e535550504f525445445f41535345545f50524f5859000000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601a81527f494e53554646494349454e545f4554485f52454d41494e494e47000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b601881527f4645455f50455243454e544147455f544f4f5f4c415247450000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160808301906122f9848261232e565b50602082015161230c602085018261232e565b50604082015161231f604085018261232e565b50606082015161161560608501825b611f4a81612559565b602081016107bd8284611f41565b606081016123538286611f41565b6123606020830185611f41565b611d03604083018461232e565b6040810161237b8285611f41565b6110e0602083018461232e565b602080825281016107bd81611f50565b602080825281016107bd81611fa6565b602080825281016107bd81611fd6565b602080825281016107bd81612006565b602080825281016107bd81612036565b602080825281016107bd8161208c565b602080825281016107bd816120bc565b602080825281016107bd816120ec565b602080825281016107bd8161211c565b602080825281016107bd8161214c565b602080825281016107bd8161217c565b602080825281016107bd816121ac565b602080825281016107bd816121dc565b602080825281016107bd8161220c565b602080825281016107bd81612262565b602080825281016107bd816122b8565b610100810161249782856122e8565b6110e060808301846122e8565b602081016107bd828461232e565b60405181810167ffffffffffffffff811182821017156124d157600080fd5b604052919050565b600067ffffffffffffffff8211156124f057600080fd5b5060209081020190565b600067ffffffffffffffff82111561251157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b828183375060009101525600a265627a7a72305820d9f418f11e0f91f06f6f9d22924be0add925495eeb76a6388b5417adb505eeb36c6578706572696d656e74616cf5003700000000000000000000000048bacb9266a570d521063ef5dd96e61686dbe788000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e808200000000000000000000000000000000000000000000000000000000",
- "value": "0x0"
- },
- "blockHash": "0x6456fbd35a3a69a1709c324fad114d68507d2c8ab391e9adb128f9734c8e4ae8",
- "blockNumber": 13536,
- "result": {
- "address": "0x6000eca38b8b5bba64986182fe2a69c57f6b5414",
- "code": "0x60806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318978e8281146100c8578063630f1e6c146100f25780638da5cb5b146101125780639395525c14610134578063f2fde38b14610147575b60025473ffffffffffffffffffffffffffffffffffffffff1633146100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612388565b60405180910390fd5b005b6100db6100d6366004611df1565b610167565b6040516100e9929190612488565b60405180910390f35b3480156100fe57600080fd5b506100c661010d366004611eec565b6102f7565b34801561011e57600080fd5b50610127610388565b6040516100e99190612337565b6100db610142366004611d0b565b6103a4565b34801561015357600080fd5b506100c6610162366004611ce5565b61050a565b61016f6119fa565b6101776119fa565b6000806101826105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815261025c939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b50505050508c600081518110151561024157fe5b6020908102909101015161014001519063ffffffff61069616565b156102875761026c8b8b8b6107c3565b935061028084600001518560600151610ac1565b90506102ae565b6102928b8b8b610b03565b9350836060015191506102a68883896107c3565b845190935090505b6102c2846020015184602001518888610d15565b6102e98b60008151811015156102d457fe5b90602001906020020151610140015182610f29565b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610348576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b61038383838080601f01602080910402602001604051908101604052809392919081815260200183838082843750879450610f299350505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6103ac6119fa565b6103b46119fa565b60008060006103c16105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152610441939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b156104925761046a670de0b6b3a7640000610464670de0b6b3a76400008a611045565b3461108f565b92506104778b848c6110e7565b945061048b85600001518660600151610ac1565b90506104d6565b6104ad670d2f13f7789f0000670de0b6b3a76400003461108f565b92506104ba8b848c6110e7565b9450846060015191506104ce89838a6107c3565b855190945090505b6104ea856020015185602001518989610d15565b6104fc8b60008151811015156102d457fe5b505050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b73ffffffffffffffffffffffffffffffffffffffff8116156105b857600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600034116105f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612398565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b5050505050565b6000815183511480156107ba5750816040518082805190602001908083835b602083106106f257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016106b5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b6020831061078757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161074a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b90505b92915050565b6107cb6119fa565b60608060008060008060006107de6119fa565b8a15156107ea57610ab2565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561088e5780601f106108635761010080835404028352916020019161088e565b820191906000526020600020905b81548152906001019060200180831161087157829003601f168201915b505060058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152969e509194509250840190508282801561093d5780601f106109125761010080835404028352916020019161093d565b820191906000526020600020905b81548152906001019060200180831161092057829003601f168201915b50505050509650600095508b519450600093505b838514610a7857878c8581518110151561096757fe5b6020908102909101015161014001528b5187908d908690811061098657fe5b60209081029091010151610160015261099f8b87610ac1565b9250610a068c858151811015156109b257fe5b9060200190602002015160a00151610a008e878151811015156109d157fe5b90602001906020020151608001518f888151811015156109ed57fe5b9060200190602002015160e00151610ac1565b8561128b565b9150610a418c85815181101515610a1957fe5b90602001906020020151838c87815181101515610a3257fe5b906020019060200201516112e6565b9050610a4d898261135e565b610a5f89600001518a60600151610ac1565b95508a8610610a6d57610a78565b600190930192610951565b8a861015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b50505050505050509392505050565b600082821115610afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123b8565b50900390565b610b0b6119fa565b606080600080600080610b1c6119fa565b60008b6000815181101515610b2d57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929b5092909190830182828015610be55780601f10610bba57610100808354040283529160200191610be5565b820191906000526020600020905b815481529060010190602001808311610bc857829003601f168201915b505050505096508b519550600094505b848614610cdb57878c86815181101515610c0b57fe5b6020908102909101015161014001528b5187908d9087908110610c2a57fe5b6020908102909101015161016001528851610c46908c90610ac1565b9350610c898c86815181101515610c5957fe5b9060200190602002015160a001518d87815181101515610c7557fe5b90602001906020020151608001518661128b565b9250610cb58c86815181101515610c9c57fe5b90602001906020020151848c88815181101515610a3257fe5b9150610cc1898361135e565b5087518a8110610cd057610cdb565b600190940193610bf5565b8a811015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b600080808066b1a2bc2ec50000861115610d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612448565b610d658888611045565b935034841115610da1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123a8565b610dab3485610ac1565b9250610dc086670de0b6b3a76400008a61108f565b915082821115610dfc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612428565b6000831115610f1f576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90610e5b9086906004016124a4565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b505050506000821115610edb5760405173ffffffffffffffffffffffffffffffffffffffff86169083156108fc029084906000818181858888f19350505050158015610ed9573d6000803e3d6000fd5b505b610ee58383610ac1565b90506000811115610f1f57604051339082156108fc029083906000818181858888f19350505050158015610f1d573d6000803e3d6000fd5b505b5050505050505050565b6000610f3b838263ffffffff6113c016565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff0000000000000000000000000000000000000000000000000000000080831691161415610fab57610fa6838361142d565b610383565b604080517f455243373231546f6b656e28616464726573732c75696e7432353629000000008152905190819003601c0190207fffffffff000000000000000000000000000000000000000000000000000000008281169116141561101357610fa6838361161b565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123f8565b600082820183811015611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b8091505b5092915050565b60008083116110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d78584611703565b8461175e565b90505b9392505050565b6110ef6119fa565b60608060008060006110ff6119fa565b89600081518110151561110e57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929950929091908301828280156111c65780601f1061119b576101008083540402835291602001916111c6565b820191906000526020600020905b8154815290600101906020018083116111a957829003601f168201915b5050505050945089519350600092505b82841461127e57858a848151811015156111ec57fe5b602090810290910101516101400152895185908b908590811061120b57fe5b90602001906020020151610160018190525061122b898860200151610ac1565b91506112578a8481518110151561123e57fe5b90602001906020020151838a86815181101515610a3257fe5b9050611263878261135e565b602087015189116112735761127e565b6001909201916111d6565b5050505050509392505050565b60008083116112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d76112d68685611703565b6112e1866001610ac1565b611045565b6112ee6119fa565b606060006112fd868686611775565b600154815191935073ffffffffffffffffffffffffffffffffffffffff1691506080908390602082016000855af1801561135457825184526020830151602085015260408301516040850152606083015160608501525b5050509392505050565b8151815161136c9190611045565b8252602080830151908201516113829190611045565b60208301526040808301519082015161139b9190611045565b6040830152606080830151908201516113b49190611045565b60609092019190915250565b600081600401835110151515611402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612468565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b60008061144184601063ffffffff61194716565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812091935073ffffffffffffffffffffffffffffffffffffffff8416919061149f903390879060240161236d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b8381101561154357818101518382015260200161152b565b50505050905090810190601f1680156115705780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1925050508015156115bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b3d156115dc575060003d602014156115dc5760206000803e506000515b801515611615576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b50505050565b60008060018314611658576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612478565b61166984601063ffffffff61194716565b915061167c84602463ffffffff6119a816565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906116d590309033908690600401612345565b600060405180830381600087803b1580156116ef57600080fd5b505af1158015610f1f573d6000803e3d6000fd5b6000808315156117165760009150611088565b5082820282848281151561172657fe5b0414611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b600080828481151561176c57fe5b04949350505050565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b8181101561187c57835185526020948501949093019260010161185e565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b818110156118c55783518552602094850194909301926001016118a7565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b8181101561190d5783518552602094850194909301926001016118ef565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b600081601401835110151515611989576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612458565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006107ba83836000816020018351101515156119f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123c8565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006107ba8235612540565b6000601f82018313611a4057600080fd5b8135611a53611a4e826124d9565b6124b2565b81815260209384019390925082018360005b83811015611a915781358601611a7b8882611b41565b8452506020928301929190910190600101611a65565b5050505092915050565b6000601f82018313611aac57600080fd5b8135611aba611a4e826124d9565b81815260209384019390925082018360005b83811015611a915781358601611ae28882611b90565b8452506020928301929190910190600101611acc565b600080601f83018413611b0a57600080fd5b50813567ffffffffffffffff811115611b2257600080fd5b602083019150836001820283011115611b3a57600080fd5b9250929050565b6000601f82018313611b5257600080fd5b8135611b60611a4e826124fa565b91508082526020830160208301858383011115611b7c57600080fd5b611b8783828461255c565b50505092915050565b60006101808284031215611ba357600080fd5b611bae6101806124b2565b90506000611bbc8484611a23565b8252506020611bcd84848301611a23565b6020830152506040611be184828501611a23565b6040830152506060611bf584828501611a23565b6060830152506080611c0984828501611cd9565b60808301525060a0611c1d84828501611cd9565b60a08301525060c0611c3184828501611cd9565b60c08301525060e0611c4584828501611cd9565b60e083015250610100611c5a84828501611cd9565b61010083015250610120611c7084828501611cd9565b6101208301525061014082013567ffffffffffffffff811115611c9257600080fd5b611c9e84828501611b41565b6101408301525061016082013567ffffffffffffffff811115611cc057600080fd5b611ccc84828501611b41565b6101608301525092915050565b60006107ba8235612559565b600060208284031215611cf757600080fd5b6000611d038484611a23565b949350505050565b60008060008060008060c08789031215611d2457600080fd5b863567ffffffffffffffff811115611d3b57600080fd5b611d4789828a01611a9b565b965050602087013567ffffffffffffffff811115611d6457600080fd5b611d7089828a01611a2f565b955050604087013567ffffffffffffffff811115611d8d57600080fd5b611d9989828a01611a9b565b945050606087013567ffffffffffffffff811115611db657600080fd5b611dc289828a01611a2f565b9350506080611dd389828a01611cd9565b92505060a0611de489828a01611a23565b9150509295509295509295565b600080600080600080600060e0888a031215611e0c57600080fd5b873567ffffffffffffffff811115611e2357600080fd5b611e2f8a828b01611a9b565b9750506020611e408a828b01611cd9565b965050604088013567ffffffffffffffff811115611e5d57600080fd5b611e698a828b01611a2f565b955050606088013567ffffffffffffffff811115611e8657600080fd5b611e928a828b01611a9b565b945050608088013567ffffffffffffffff811115611eaf57600080fd5b611ebb8a828b01611a2f565b93505060a0611ecc8a828b01611cd9565b92505060c0611edd8a828b01611a23565b91505092959891949750929550565b600080600060408486031215611f0157600080fd5b833567ffffffffffffffff811115611f1857600080fd5b611f2486828701611af8565b93509350506020611f3786828701611cd9565b9150509250925092565b611f4a81612540565b82525050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b600d81527f4f564552534f4c445f5745544800000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601781527f554e535550504f525445445f41535345545f50524f5859000000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601a81527f494e53554646494349454e545f4554485f52454d41494e494e47000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b601881527f4645455f50455243454e544147455f544f4f5f4c415247450000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160808301906122f9848261232e565b50602082015161230c602085018261232e565b50604082015161231f604085018261232e565b50606082015161161560608501825b611f4a81612559565b602081016107bd8284611f41565b606081016123538286611f41565b6123606020830185611f41565b611d03604083018461232e565b6040810161237b8285611f41565b6110e0602083018461232e565b602080825281016107bd81611f50565b602080825281016107bd81611fa6565b602080825281016107bd81611fd6565b602080825281016107bd81612006565b602080825281016107bd81612036565b602080825281016107bd8161208c565b602080825281016107bd816120bc565b602080825281016107bd816120ec565b602080825281016107bd8161211c565b602080825281016107bd8161214c565b602080825281016107bd8161217c565b602080825281016107bd816121ac565b602080825281016107bd816121dc565b602080825281016107bd8161220c565b602080825281016107bd81612262565b602080825281016107bd816122b8565b610100810161249782856122e8565b6110e060808301846122e8565b602081016107bd828461232e565b60405181810167ffffffffffffffff811182821017156124d157600080fd5b604052919050565b600067ffffffffffffffff8211156124f057600080fd5b5060209081020190565b600067ffffffffffffffff82111561251157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b828183375060009101525600a265627a7a72305820d9f418f11e0f91f06f6f9d22924be0add925495eeb76a6388b5417adb505eeb36c6578706572696d656e74616cf50037",
- "gasUsed": "0x2c8c7f"
- },
- "subtraces": 3,
- "traceAddress": [],
- "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e",
- "transactionPosition": 0,
- "type": "create"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x6000eca38b8b5bba64986182fe2a69c57f6b5414",
- "gas": "0x1dba84",
- "input": "0x60704108f47261b000000000000000000000000000000000000000000000000000000000",
- "to": "0x48bacb9266a570d521063ef5dd96e61686dbe788",
- "value": "0x0"
- },
- "blockHash": "0x6456fbd35a3a69a1709c324fad114d68507d2c8ab391e9adb128f9734c8e4ae8",
- "blockNumber": 13536,
- "result": {
- "gasUsed": "0x3d9",
- "output": "0x0000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48"
- },
- "subtraces": 0,
- "traceAddress": [
- 0
- ],
- "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e",
- "transactionPosition": 0,
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x6000eca38b8b5bba64986182fe2a69c57f6b5414",
- "gas": "0x1dad2e",
- "input": "0x095ea7b30000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
- "to": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082",
- "value": "0x0"
- },
- "blockHash": "0x6456fbd35a3a69a1709c324fad114d68507d2c8ab391e9adb128f9734c8e4ae8",
- "blockNumber": 13536,
- "result": {
- "gasUsed": "0x56c8",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 0,
- "traceAddress": [
- 1
- ],
- "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e",
- "transactionPosition": 0,
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x6000eca38b8b5bba64986182fe2a69c57f6b5414",
- "gas": "0x1d4ee1",
- "input": "0x095ea7b30000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
- "to": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c",
- "value": "0x0"
- },
- "blockHash": "0x6456fbd35a3a69a1709c324fad114d68507d2c8ab391e9adb128f9734c8e4ae8",
- "blockNumber": 13536,
- "result": {
- "gasUsed": "0x56ca",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 0,
- "traceAddress": [
- 2
- ],
- "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e",
- "transactionPosition": 0,
- "type": "call"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json
deleted file mode 100644
index bd6059faef..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json
+++ /dev/null
@@ -1,68 +0,0 @@
-{
- "context": {
- "difficulty": "3699098917",
- "gasLimit": "5258985",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "number": "2294631",
- "timestamp": "1513675366"
- },
- "genesis": {
- "alloc": {
- "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62": {
- "balance": "0x0",
- "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c68146102785780635a3b7e42146102b357806370a082311461034157806379cc67901461038e57806395d89b41146103e8578063a9059cbb14610476578063dd62ed3e146104b8575b600080fd5b34156100ca57600080fd5b6100d2610524565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061055d565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba6105ea565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105f0565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610910565b604051808260ff1660ff16815260200191505060405180910390f35b341561028357600080fd5b6102996004808035906020019091905050610915565b604051808215151515815260200191505060405180910390f35b34156102be57600080fd5b6102c6610a18565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103065780820151818401526020810190506102eb565b50505050905090810190601f1680156103335780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a51565b6040518082815260200191505060405180910390f35b341561039957600080fd5b6103ce600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a69565b604051808215151515815260200191505060405180910390f35b34156103f357600080fd5b6103fb610bf8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561043b578082015181840152602081019050610420565b50505050905090810190601f1680156104685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561048157600080fd5b6104b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610c31565b005b34156104c357600080fd5b61050e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e34565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f446f70616d696e6500000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60005481565b6000808373ffffffffffffffffffffffffffffffffffffffff161415151561061757600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561066557600080fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101515156106f157fe5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561077c57600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561096557600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b6040805190810160405280600981526020017f446f706d6e20302e32000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b600081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ab957600080fd5b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610b4457600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b6040805190810160405280600581526020017f444f504d4e00000000000000000000000000000000000000000000000000000081525081565b60008273ffffffffffffffffffffffffffffffffffffffff1614151515610c5757600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ca557600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110151515610d3157fe5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60026020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058206d93424f4e7b11929b8276a269038402c10c0ddf21800e999916ddd9dff4a7630029",
- "nonce": "1",
- "storage": {
- "0x296b66049cc4f9c8bf3d4f14752add261d1a980b39bdd194a7897baf39ac7579": "0x0000000000000000000000000000000000000000033b2e3c9fc9653f9e72b1e0"
- }
- },
- "0x94194bc2aaf494501d7880b61274a169f6502a54": {
- "balance": "0xea8c39a876d19888d",
- "code": "0x",
- "nonce": "265",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3699098917",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "5263953",
- "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408",
- "nonce": "0xd1bdb150f6fd170e",
- "number": "2294630",
- "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1",
- "timestamp": "1513675347",
- "totalDifficulty": "7160543502214733"
- },
- "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0x94194bc2aaf494501d7880b61274a169f6502a54",
- "gas": "0xca1d",
- "input": "0xa9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f9000",
- "to": "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62",
- "value": "0x0"
- },
- "blockNumber": 2294631,
- "error": "out of gas",
- "result": {},
- "subtraces": 0,
- "traceAddress": [],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json
deleted file mode 100644
index 8888d3e68a..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json
+++ /dev/null
@@ -1,71 +0,0 @@
-{
- "context": {
- "difficulty": "3699098917",
- "gasLimit": "5258985",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "number": "2294631",
- "timestamp": "1513675366"
- },
- "genesis": {
- "alloc": {
- "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62": {
- "balance": "0x0",
- "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c68146102785780635a3b7e42146102b357806370a082311461034157806379cc67901461038e57806395d89b41146103e8578063a9059cbb14610476578063dd62ed3e146104b8575b600080fd5b34156100ca57600080fd5b6100d2610524565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061055d565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba6105ea565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105f0565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610910565b604051808260ff1660ff16815260200191505060405180910390f35b341561028357600080fd5b6102996004808035906020019091905050610915565b604051808215151515815260200191505060405180910390f35b34156102be57600080fd5b6102c6610a18565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103065780820151818401526020810190506102eb565b50505050905090810190601f1680156103335780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a51565b6040518082815260200191505060405180910390f35b341561039957600080fd5b6103ce600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a69565b604051808215151515815260200191505060405180910390f35b34156103f357600080fd5b6103fb610bf8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561043b578082015181840152602081019050610420565b50505050905090810190601f1680156104685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561048157600080fd5b6104b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610c31565b005b34156104c357600080fd5b61050e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e34565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f446f70616d696e6500000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60005481565b6000808373ffffffffffffffffffffffffffffffffffffffff161415151561061757600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561066557600080fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101515156106f157fe5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561077c57600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561096557600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b6040805190810160405280600981526020017f446f706d6e20302e32000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b600081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ab957600080fd5b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610b4457600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b6040805190810160405280600581526020017f444f504d4e00000000000000000000000000000000000000000000000000000081525081565b60008273ffffffffffffffffffffffffffffffffffffffff1614151515610c5757600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ca557600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110151515610d3157fe5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60026020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058206d93424f4e7b11929b8276a269038402c10c0ddf21800e999916ddd9dff4a7630029",
- "nonce": "1",
- "storage": {
- "0x296b66049cc4f9c8bf3d4f14752add261d1a980b39bdd194a7897baf39ac7579": "0x0000000000000000000000000000000000000000033b2e3c9fc9653f9e72b1e0"
- }
- },
- "0x94194bc2aaf494501d7880b61274a169f6502a54": {
- "balance": "0xea8c39a876d19888d",
- "code": "0x",
- "nonce": "265",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3699098917",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "5263953",
- "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408",
- "nonce": "0xd1bdb150f6fd170e",
- "number": "2294630",
- "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1",
- "timestamp": "1513675347",
- "totalDifficulty": "7160543502214733"
- },
- "tracerConfig": {
- "convertParityErrors": true
- },
- "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0x94194bc2aaf494501d7880b61274a169f6502a54",
- "gas": "0xca1d",
- "input": "0xa9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f9000",
- "to": "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62",
- "value": "0x0"
- },
- "blockNumber": 2294631,
- "error": "Out of gas",
- "result": {},
- "subtraces": 0,
- "traceAddress": [],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json
deleted file mode 100644
index 62baf333b6..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json
+++ /dev/null
@@ -1,111 +0,0 @@
-{
- "genesis": {
- "difficulty": "1911202",
- "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578",
- "gasLimit": "7842876",
- "hash": "0x4d7bc82e0d56307094378e1a8fbfa6260986f621de95b5fe68a95248b3ba8efe",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "mixHash": "0xc102ad52677c391edab82cc895ca7a7e9fff3eed4fa966ecf7fb61ec1e84bb6b",
- "nonce": "0x39f5b074e3437f3f",
- "number": "553415",
- "stateRoot": "0x8f89e79109c19fa00e72b400502448540dc4773ad92dddd341dbba20c710a3b5",
- "timestamp": "1577396195",
- "totalDifficulty": "458361299240",
- "alloc": {
- "0x531f76bad925f6a925474996c7d738c1008045f6": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x6060604052361561008a576000357c01000000000000000000000000000000000000000000000000000000009004806301cb3b20146102bf57806329dcb0cf146102cc57806338af3eed146102ed5780636e66f6e9146103245780637a3a0e841461035b5780637b3e5e7b1461037c578063a035b1fe1461039d578063dc0d3dff146103be5761008a565b6102bd5b60003490506040604051908101604052803381526020018281526020015060066000506006600050805480919060010190908154818355818115116101365760020281600202836000526020600020918201910161013591906100ec565b808211156101315760006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160005060009055506001016100ec565b5090565b5b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff0219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b98a11336004600050548404604051837c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750505060405151507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf633826001604051808473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a15b50565b005b6102ca6004506104c8565b005b6102d760045061043a565b6040518082815260200191505060405180910390f35b6102f8600450610402565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61032f60045061044c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610366600450610428565b6040518082815260200191505060405180910390f35b610387600450610431565b6040518082815260200191505060405180910390f35b6103a8600450610443565b6040518082815260200191505060405180910390f35b6103cf600480359060200150610472565b604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016000505481565b60026000505481565b60036000505481565b60046000505481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60066000508181548110156100025790600052602060002090600202016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160005054905082565b6000600360005054421015156107d8576001600050546002600050541015156105cf57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000600260005054604051809050600060405180830381858888f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002600050546000604051808473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a161079d565b7fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf66000600b600060405180848152602001838152602001828152602001935050505060405180910390a1600090505b60066000505481101561079c57600660005081815481101561000257906000526020600020906002020160005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000600660005083815481101561000257906000526020600020906002020160005060010160005054604051809050600060405180830381858888f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6600660005082815481101561000257906000526020600020906002020160005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166006600050838154811015610002579060005260206000209060020201600050600101600050546000604051808473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a15b806001019050805061061e565b5b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b5056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000000b49180d443dc4ca6028de0031ac09337891fd8ce",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000"
- }
- },
- "0xb49180d443dc4ca6028de0031ac09337891fd8ce": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x193e9986e2e3f0c58988",
- "nonce": "2585",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "553416",
- "difficulty": "1909336",
- "timestamp": "1577396224",
- "gasLimit": "7835218",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf870820a1985e8d4a5100083040b2894531f76bad925f6a925474996c7d738c1008045f6880de0b6b3a76400008081a2a08693170f040d9501b831b404d9e40fba040c5aef4b8974aedc20b3844aea7c32a0476861058ff9b8030c58bcba8be320acc855e4694a633c493fb50fbdb9455489",
- "result": [
- {
- "type": "call",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "to": "0x531f76bad925f6a925474996c7d738c1008045f6",
- "value": "0xde0b6b3a7640000",
- "gas": "0x40b28",
- "input": "0x",
- "callType": "call"
- },
- "result": {
- "gasUsed": "0x19c3e",
- "output": "0x"
- },
- "traceAddress": [],
- "subtraces": 1,
- "transactionPosition": 5,
- "transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada",
- "blockNumber": 553416,
- "blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282",
- "time": "617.42µs"
- },
- {
- "type": "call",
- "action": {
- "from": "0x531f76bad925f6a925474996c7d738c1008045f6",
- "to": "0xb49180d443dc4ca6028de0031ac09337891fd8ce",
- "value": "0x0",
- "gas": "0x2164e",
- "input": "0x90b98a11000000000000000000000000877bd459c9b7d8576b44e59e09d076c25946f4430000000000000000000000000000000000000000000000000000000000000001",
- "callType": "call"
- },
- "result": {
- "gasUsed": "0x0",
- "output": "0x"
- },
- "traceAddress": [
- 0
- ],
- "subtraces": 0,
- "transactionPosition": 5,
- "transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada",
- "blockNumber": 553416,
- "blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json
deleted file mode 100644
index b0346d8603..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json
+++ /dev/null
@@ -1,68 +0,0 @@
-{
- "context": {
- "difficulty": "3665057456",
- "gasLimit": "5232723",
- "miner": "0xf4d8e706cfb25c0decbbdd4d2e2cc10c66376a3f",
- "number": "2294501",
- "timestamp": "1513673601"
- },
- "genesis": {
- "alloc": {
- "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9": {
- "balance": "0x2a3fc32bcc019283",
- "code": "0x",
- "nonce": "10",
- "storage": {}
- },
- "0xabbcd5b340c80b5f1c0545c04c987b87310296ae": {
- "balance": "0x0",
- "code": "0x606060405236156100755763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632d0335ab811461007a578063548db174146100ab5780637f649783146100fc578063b092145e1461014d578063c3f44c0a14610186578063c47cf5de14610203575b600080fd5b341561008557600080fd5b610099600160a060020a0360043516610270565b60405190815260200160405180910390f35b34156100b657600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061028f95505050505050565b005b341561010757600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061029e95505050505050565b005b341561015857600080fd5b610172600160a060020a03600435811690602435166102ad565b604051901515815260200160405180910390f35b341561019157600080fd5b6100fa6004803560ff1690602480359160443591606435600160a060020a0316919060a49060843590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965050509235600160a060020a031692506102cd915050565b005b341561020e57600080fd5b61025460046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061056a95505050505050565b604051600160a060020a03909116815260200160405180910390f35b600160a060020a0381166000908152602081905260409020545b919050565b61029a816000610594565b5b50565b61029a816001610594565b5b50565b600160209081526000928352604080842090915290825290205460ff1681565b60008080600160a060020a038416158061030d5750600160a060020a038085166000908152600160209081526040808320339094168352929052205460ff165b151561031857600080fd5b6103218561056a565b600160a060020a038116600090815260208190526040808220549295507f19000000000000000000000000000000000000000000000000000000000000009230918891908b908b90517fff000000000000000000000000000000000000000000000000000000000000008089168252871660018201526c01000000000000000000000000600160a060020a038088168202600284015286811682026016840152602a8301869052841602604a820152605e810182805190602001908083835b6020831061040057805182525b601f1990920191602091820191016103e0565b6001836020036101000a0380198251168184511617909252505050919091019850604097505050505050505051809103902091506001828a8a8a6040516000815260200160405260006040516020015260405193845260ff90921660208085019190915260408085019290925260608401929092526080909201915160208103908084039060008661646e5a03f1151561049957600080fd5b5050602060405103519050600160a060020a03838116908216146104bc57600080fd5b600160a060020a0380841660009081526020819052604090819020805460010190559087169086905180828051906020019080838360005b8381101561050d5780820151818401525b6020016104f4565b50505050905090810190601f16801561053a5780820380516001836020036101000a031916815260200191505b5091505060006040518083038160008661646e5a03f1915050151561055e57600080fd5b5b505050505050505050565b600060248251101561057e5750600061028a565b600160a060020a0360248301511690505b919050565b60005b825181101561060157600160a060020a033316600090815260016020526040812083918584815181106105c657fe5b90602001906020020151600160a060020a031681526020810191909152604001600020805460ff19169115159190911790555b600101610597565b5b5050505600a165627a7a723058200027e8b695e9d2dea9f3629519022a69f3a1d23055ce86406e686ea54f31ee9c0029",
- "nonce": "1",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3672229776",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "5227619",
- "hash": "0xa07b3d6c6bf63f5f981016db9f2d1d93033833f2c17e8bf7209e85f1faf08076",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x806e151ce2817be922e93e8d5921fa0f0d0fd213d6b2b9a3fa17458e74a163d0",
- "nonce": "0xbc5d43adc2c30c7d",
- "number": "2294500",
- "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d",
- "timestamp": "1513673552",
- "totalDifficulty": "7160066586979149"
- },
- "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9",
- "gas": "0x2dc6c0",
- "input": "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "to": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae",
- "value": "0x0"
- },
- "blockNumber": 2294501,
- "error": "execution reverted",
- "result": {
- "gasUsed": "0x719b"
- },
- "subtraces": 0,
- "traceAddress": [],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json
deleted file mode 100644
index 6759b05e52..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json
+++ /dev/null
@@ -1,74 +0,0 @@
-{
- "context": {
- "difficulty": "2",
- "gasLimit": "8000000",
- "miner": "0x0000000000000000000000000000000000000000",
- "number": "3212651",
- "timestamp": "1597246515"
- },
- "genesis": {
- "alloc": {
- "0xf58833cf0c791881b494eb79d461e08a1f043f52": {
- "balance": "0x0",
- "code": "0x608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063609ff1bd11610078578063609ff1bd146101af5780639e7b8d61146101cd578063a3ec138d14610211578063e2ba53f0146102ae576100a5565b80630121b93f146100aa578063013cf08b146100d85780632e4176cf146101215780635c19a95c1461016b575b600080fd5b6100d6600480360360208110156100c057600080fd5b81019080803590602001909291905050506102cc565b005b610104600480360360208110156100ee57600080fd5b8101908080359060200190929190505050610469565b604051808381526020018281526020019250505060405180910390f35b61012961049a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ad6004803603602081101561018157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104bf565b005b6101b76108db565b6040518082815260200191505060405180910390f35b61020f600480360360208110156101e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610952565b005b6102536004803603602081101561022757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b53565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b6102b6610bb0565b6040518082815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561038a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f486173206e6f20726967687420746f20766f746500000000000000000000000081525060200191505060405180910390fd5b8060010160009054906101000a900460ff161561040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f416c726561647920766f7465642e00000000000000000000000000000000000081525060200191505060405180910390fd5b60018160010160006101000a81548160ff02191690831515021790555081816002018190555080600001546002838154811061044757fe5b9060005260206000209060020201600101600082825401925050819055505050565b6002818154811061047657fe5b90600052602060002090600202016000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff1615610587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f596f7520616c726561647920766f7465642e000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e000081525060200191505060405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107cc57600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f466f756e64206c6f6f7020696e2064656c65676174696f6e2e0000000000000081525060200191505060405180910390fd5b61062a565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156108bf578160000154600282600201548154811061089c57fe5b9060005260206000209060020201600101600082825401925050819055506108d6565b816000015481600001600082825401925050819055505b505050565b6000806000905060008090505b60028054905081101561094d57816002828154811061090357fe5b9060005260206000209060020201600101541115610940576002818154811061092857fe5b90600052602060002090600202016001015491508092505b80806001019150506108e8565b505090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180610bde6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f54686520766f74657220616c726561647920766f7465642e000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414610b0957600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610bbc6108db565b81548110610bc657fe5b90600052602060002090600202016000015490509056fe4f6e6c79206368616972706572736f6e2063616e206769766520726967687420746f20766f74652ea26469706673582212201d282819f8f06fed792100d60a8b08809b081a34a1ecd225e83a4b41122165ed64736f6c63430006060033",
- "nonce": "1",
- "storage": {
- "0x6200beec95762de01ce05f2a0e58ce3299dbb53c68c9f3254a242121223cdf58": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1": {
- "balance": "0x57af9d6b3df812900",
- "code": "0x",
- "nonce": "6",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 0,
- "constantinopleBlock": 0,
- "petersburgBlock": 0,
- "IstanbulBlock": 1561651,
- "chainId": 5,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1",
- "gas": "0x2dc6c0",
- "input": "0x5c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf1",
- "to": "0xf58833cf0c791881b494eb79d461e08a1f043f52",
- "value": "0x0"
- },
- "blockNumber": 3212651,
- "error": "execution reverted",
- "result": {
- "gasUsed": "0x5940",
- "output": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000"
- },
- "subtraces": 0,
- "traceAddress": [],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json
deleted file mode 100644
index 74fd87cc6c..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json
+++ /dev/null
@@ -1,91 +0,0 @@
-{
- "genesis": {
- "difficulty": "4628640",
- "extraData": "0xd883010b05846765746888676f312e31342e33856c696e7578",
- "gasLimit": "9244120",
- "hash": "0x5a1f551897cc91265225b0453136ad8c7eef1c1c8b06139da4f2e6e710c1f4df",
- "miner": "0x73f26d124436b0791169d63a3af29c2ae47765a3",
- "mixHash": "0xd6735e63f8937fe0c5491e0d5836ec28467363be7ada5a2f979f9d107e2c831e",
- "nonce": "0x7c35e34d2e328d7d",
- "number": "1555145",
- "stateRoot": "0x565873b05f71b98595133e37a52d79c3476ce820c05ebedaddd35541b0e894a3",
- "timestamp": "1590793819",
- "totalDifficulty": "2241994078605",
- "alloc": {
- "0x119f569a45e9d0089d51d7f9529f5ea9bf5785e2": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x622e8fced69d43eb8d97",
- "nonce": "260140",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "1555146",
- "difficulty": "4630900",
- "timestamp": "1590793820",
- "gasLimit": "9253146",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf8628303f82c843b9aca0083019ecc80808e605a600053600160006001f0ff0081a2a077f539ae2a58746bbfa6370fc423f946870efa32753d697d3729d361a428623aa0384ef9a5650d6630f5c1ddef616bffa5fc72a95a9314361d0918de066aa4475a",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x19ecc",
- "init": "0x605a600053600160006001f0ff00"
- },
- "result": {
- "gasUsed": "0x102a1",
- "code": "0x",
- "address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca"
- },
- "traceAddress": [],
- "subtraces": 1,
- "transactionPosition": 14,
- "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
- "blockNumber": 1555146,
- "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e",
- "time": "187.145µs"
- },
- {
- "type": "suicide",
- "action": {
- "address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "balance": "0x0"
- },
- "result": null,
- "traceAddress": [
- 0
- ],
- "subtraces": 0,
- "transactionPosition": 14,
- "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79",
- "blockNumber": 1555146,
- "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json
deleted file mode 100644
index a7244e9747..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json
+++ /dev/null
@@ -1,97 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "gas": "0x15f90",
- "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "value": "0x0"
- },
- "blockNumber": 2289806,
- "result": {
- "gasUsed": "0x9751",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 1,
- "traceAddress": [],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "gas": "0x6d05",
- "input": "0x",
- "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "value": "0x6f05b59d3b20000"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x0",
- "output": "0x"
- },
- "subtraces": 0,
- "traceAddress": [0],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json
deleted file mode 100644
index 5fbdf55d22..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json
+++ /dev/null
@@ -1,100 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "tracerConfig": {
- "onlyTopCall": true
- },
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "gas": "0x15f90",
- "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "value": "0x0"
- },
- "blockNumber": 2289806,
- "result": {
- "gasUsed": "0x9751",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001"
- },
- "subtraces": 1,
- "traceAddress": [],
- "type": "call"
- },
- {
- "action": {
- "callType": "call",
- "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "gas": "0x6d05",
- "input": "0x",
- "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "value": "0x6f05b59d3b20000"
- },
- "blockNumber": 0,
- "result": {
- "gasUsed": "0x0",
- "output": "0x"
- },
- "subtraces": 0,
- "traceAddress": [0],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json
deleted file mode 100644
index 96060d5545..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "genesis": {
- "difficulty": "4673862",
- "extraData": "0xd683010b05846765746886676f312e3133856c696e7578",
- "gasLimit": "9471919",
- "hash": "0x7f072150c5905c214966e3432d418910badcdbe510aceaac295b1d7059cc0ffc",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "mixHash": "0x113ced8fedb939fdc862008da7bdddde726f997c0e6dfba0e55613994757b489",
- "nonce": "0x0f411a2e5552c5b7",
- "number": "1555284",
- "stateRoot": "0x9fe125b361b72d5479b24ad9be9964b74228c73a2dfb0065060a79b4a6dfaa1e",
- "timestamp": "1590795374",
- "totalDifficulty": "2242642335405",
- "alloc": {
- "0xe85df1413eebe1b191c26260e19783a274a6b041": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x6244c985ef1e48e84531",
- "nonce": "265775",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "1555285",
- "difficulty": "4676144",
- "timestamp": "1590795378",
- "gasLimit": "9481167",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf9014083040e2f843b9aca008301aab08080b8eb7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5547f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000037f05581a2a09db45e7846f193471f6d897fb6ff58b7ec41a9c6f63d10aca47d821c365981cba052ec320875625e16141a1a9e8b7993de863698fb699f93ae2cab26149bbb144f",
- "result": [
- {
- "type": "create",
- "action": {
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "value": "0x0",
- "gas": "0x1aab0",
- "init": "0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5547f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000037f055"
- },
- "error": "out of gas",
- "traceAddress": [],
- "subtraces": 0,
- "transactionPosition": 16,
- "transactionHash": "0x384487e5ae8d2997aece8e28403d393cb9752425e6de358891bed981c5af1c05",
- "blockNumber": 1555285,
- "blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f",
- "time": "665.278µs"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json
deleted file mode 100644
index 45ffbe2db9..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json
+++ /dev/null
@@ -1,83 +0,0 @@
-{
- "genesis": {
- "difficulty": "2028219",
- "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578",
- "gasLimit": "23481547",
- "hash": "0x3c06114e88c26b52decfe4e5f6d4d51cfaaea0317b646017fac32fadbe7df9f5",
- "miner": "0x2a1442b4fbabf7b5507c13ccf076a547abfaeb1b",
- "mixHash": "0x46108f74220c5ab23651f93912b14fea37ed1380d22e10639a1f5651c98cb949",
- "nonce": "0x426a5267e0b636fe",
- "number": "567687",
- "stateRoot": "0x7b4b193fe73ef87101c7c325954681861cc240c299d03459784b2b11c9c522ae",
- "timestamp": "1577578008",
- "totalDifficulty": "485254950048",
- "alloc": {
- "0x8521f13dd5e4bc3dab3cf0f01a195a5af899e851": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x608060405260043610610251576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806301ffc9a7146102565780630519ce79146102c857806306fdde031461031f578063095ea7b3146103af5780630a0f81681461040a5780631155dfe51461046157806318160ddd1461048c5780631b57cd44146104b7578063200b1e641461050657806327d7874c146105cb5780632ba73c151461061c5780633108e4d71461066d578063317676bf146106bc5780633f4ba83a1461071557806342842e0e1461072c57806346cb96fa146107a75780634e0a3379146107f65780635501d42d146108475780635c975abb146108a05780635fd8c710146108cf5780636352211e146108e65780636af04a571461096157806370a08231146109b85780637158798814610a1d5780637866928014610a6e5780638456cb5914610ae95780638462151c14610b0057806385ac788214610ba657806395787d2614610c2c57806395d89b4114610c6e57806396b5d99214610cfe578063990581b614610d795780639db797f014610e2d578063ab8f933a14610e80578063ad84202814610eab578063b047fb5014610ed6578063b355752214610f2d578063b9db15b414610f7c578063bc4006f514610fd2578063ca083be214611029578063cdd22c9314611082578063cec21acb146110d1578063e078d8b114611136578063e17b25af14611182578063e52ab74b146111d3578063f010432314611222578063fac9c51f1461129d578063fdb33429146112ec578063fffb147914611367575b600080fd5b34801561026257600080fd5b506102ae6004803603602081101561027957600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690602001909291905050506113e2565b604051808215151515815260200191505060405180910390f35b3480156102d457600080fd5b506102dd6116cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561032b57600080fd5b506103346116f1565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610374578082015181840152602081019050610359565b50505050905090810190601f1680156103a15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103bb57600080fd5b50610408600480360360408110156103d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061172a565b005b34801561041657600080fd5b5061041f6117c4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561046d57600080fd5b506104766117e9565b6040518082815260200191505060405180910390f35b34801561049857600080fd5b506104a16117f6565b6040518082815260200191505060405180910390f35b3480156104c357600080fd5b506104f0600480360360208110156104da57600080fd5b8101908080359060200190929190505050611806565b6040518082815260200191505060405180910390f35b34801561051257600080fd5b506105b5600480360360a081101561052957600080fd5b81019080803590602001909291908035906020019064010000000081111561055057600080fd5b82018360208201111561056257600080fd5b8035906020019184600183028401116401000000008311171561058457600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919050505061181e565b6040518082815260200191505060405180910390f35b3480156105d757600080fd5b5061061a600480360360208110156105ee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611cac565b005b34801561062857600080fd5b5061066b6004803603602081101561063f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d86565b005b34801561067957600080fd5b506106a66004803603602081101561069057600080fd5b8101908080359060200190929190505050611e61565b6040518082815260200191505060405180910390f35b3480156106c857600080fd5b506106ff600480360360408110156106df57600080fd5b810190808035906020019092919080359060200190929190505050611e79565b6040518082815260200191505060405180910390f35b34801561072157600080fd5b5061072a611ea9565b005b34801561073857600080fd5b506107a56004803603606081101561074f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611f86565b005b3480156107b357600080fd5b506107e0600480360360208110156107ca57600080fd5b8101908080359060200190929190505050612053565b6040518082815260200191505060405180910390f35b34801561080257600080fd5b506108456004803603602081101561081957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061206b565b005b34801561085357600080fd5b5061088a6004803603604081101561086a57600080fd5b810190808035906020019092919080359060200190929190505050612146565b6040518082815260200191505060405180910390f35b3480156108ac57600080fd5b506108b5612176565b604051808215151515815260200191505060405180910390f35b3480156108db57600080fd5b506108e4612189565b005b3480156108f257600080fd5b5061091f6004803603602081101561090957600080fd5b810190808035906020019092919050505061226d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561096d57600080fd5b506109766122e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156109c457600080fd5b50610a07600480360360208110156109db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061230c565b6040518082815260200191505060405180910390f35b348015610a2957600080fd5b50610a6c60048036036020811015610a4057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612355565b005b348015610a7a57600080fd5b50610aa760048036036020811015610a9157600080fd5b8101908080359060200190929190505050612472565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610af557600080fd5b50610afe6124a5565b005b348015610b0c57600080fd5b50610b4f60048036036020811015610b2357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125e9565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610b92578082015181840152602081019050610b77565b505050509050019250505060405180910390f35b348015610bb257600080fd5b50610c16600480360360c0811015610bc957600080fd5b810190808035906020019092919080359060200190929190803515159060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050612737565b6040518082815260200191505060405180910390f35b610c5860048036036020811015610c4257600080fd5b8101908080359060200190929190505050612c0c565b6040518082815260200191505060405180910390f35b348015610c7a57600080fd5b50610c8361304b565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610cc3578082015181840152602081019050610ca8565b50505050905090810190601f168015610cf05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610d0a57600080fd5b50610d3760048036036020811015610d2157600080fd5b8101908080359060200190929190505050613084565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610d8557600080fd5b50610db260048036036020811015610d9c57600080fd5b81019080803590602001909291905050506130b7565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df2578082015181840152602081019050610dd7565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610e3957600080fd5b50610e6660048036036020811015610e5057600080fd5b810190808035906020019092919050505061317b565b604051808215151515815260200191505060405180910390f35b348015610e8c57600080fd5b50610e956131b3565b6040518082815260200191505060405180910390f35b348015610eb757600080fd5b50610ec06131b9565b6040518082815260200191505060405180910390f35b348015610ee257600080fd5b50610eeb6131bf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610f3957600080fd5b50610f6660048036036020811015610f5057600080fd5b81019080803590602001909291905050506131e5565b6040518082815260200191505060405180910390f35b348015610f8857600080fd5b50610fb560048036036020811015610f9f57600080fd5b81019080803590602001909291905050506131fd565b604051808381526020018281526020019250505060405180910390f35b348015610fde57600080fd5b50610fe7613235565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561103557600080fd5b5061106c6004803603604081101561104c57600080fd5b81019080803590602001909291908035906020019092919050505061325b565b6040518082815260200191505060405180910390f35b34801561108e57600080fd5b506110bb600480360360208110156110a557600080fd5b810190808035906020019092919050505061328b565b6040518082815260200191505060405180910390f35b3480156110dd57600080fd5b50611120600480360360208110156110f457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132ab565b6040518082815260200191505060405180910390f35b61116c6004803603604081101561114c57600080fd5b8101908080359060200190929190803590602001909291905050506132c3565b6040518082815260200191505060405180910390f35b34801561118e57600080fd5b506111d1600480360360208110156111a557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506134ee565b005b3480156111df57600080fd5b5061120c600480360360208110156111f657600080fd5b810190808035906020019092919050505061358d565b6040518082815260200191505060405180910390f35b34801561122e57600080fd5b5061125b6004803603602081101561124557600080fd5b81019080803590602001909291905050506135ad565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156112a957600080fd5b506112d6600480360360208110156112c057600080fd5b81019080803590602001909291905050506135e0565b6040518082815260200191505060405180910390f35b3480156112f857600080fd5b506113256004803603602081101561130f57600080fd5b81019080803590602001909291905050506135f8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561137357600080fd5b506113a06004803603602081101561138a57600080fd5b810190808035906020019092919050505061362b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600060405180807f737570706f727473496e74657266616365286279746573342900000000000000815250601901905060405180910390207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611610575060405180807f746f6b656e734f664f776e6572286164647265737329000000000000000000008152506016019050604051809103902060405180807f736166655472616e7366657246726f6d28616464726573732c6164647265737381526020017f2c75696e743235362900000000000000000000000000000000000000000000008152506029019050604051809103902060405180807f617070726f766528616464726573732c75696e743235362900000000000000008152506018019050604051809103902060405180807f6f776e65724f662875696e7432353629000000000000000000000000000000008152506010019050604051809103902060405180807f62616c616e63654f6628616464726573732900000000000000000000000000008152506012019050604051809103902060405180807f746f74616c537570706c79282900000000000000000000000000000000000000815250600d019050604051809103902018181818187bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806116c4575060405180807f73796d626f6c28290000000000000000000000000000000000000000000000008152506008019050604051809103902060405180807f6e616d652829000000000000000000000000000000000000000000000000000081525060060190506040518091039020187bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600781526020017f426974766965770000000000000000000000000000000000000000000000000081525081565b600260149054906101000a900460ff1615151561174657600080fd5b611750338261365e565b151561175b57600080fd5b61176581836136ca565b808273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600480549050905090565b6000600160048054905003905090565b60166020528060005260406000206000915090505481565b600085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506101006000825111801561187a575080825111155b151561188557600080fd5b33896005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156118f557600080fd5b6000878760405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000600e6000838152602001908152602001600020541415156119b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f5369676e617475726520416c726561647920557365640000000000000000000081525060200191505060405180910390fd5b600560008d815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660018d60405160200180828152602001915050604051602081830303815290604052805190602001208b8b8b60405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611a80573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16141515611aac57600080fd5b611ab4613a21565b6020604051908101604052808d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815250905060006001600a839080600181540180825580915050906001820390600052602060002001600090919290919091506000820151816000019080519060200190611b54929190613a35565b5050500390508063ffffffff1681141515611b6e57600080fd5b7fe819187a0cf517f3c23c7bd6e6b11a3aec56ec3f2784dc69ac56ebac668748ee3382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a133600b600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508d600c600083815260200190815260200160002081905550600860008f81526020019081526020016000208190806001815401808255809150509060018203906000526020600020016000909192909190915055508d600e600085815260200190815260200160002081905550809750505050505050509695505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611d0757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611d4357600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611de157600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611e1d57600080fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60116020528060005260406000206000915090505481565b600860205281600052604060002081815481101515611e9457fe5b90600052602060002001600091509150505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f0457600080fd5b600260149054906101000a900460ff161515611f1f57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16601860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515611f7c57600080fd5b611f84613720565b565b600260149054906101000a900460ff16151515611fa257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515611fde57600080fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561201957600080fd5b61202333826137b3565b151561202e57600080fd5b612038838261365e565b151561204357600080fd5b61204e83838361381f565b505050565b600e6020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156120c657600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561210257600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600d6020528160005260406000208181548110151561216157fe5b90600052602060002001600091509150505481565b600260149054906101000a900460ff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156121e557600080fd5b60003073ffffffffffffffffffffffffffffffffffffffff16319050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015612269573d6000803e3d6000fd5b5050565b60006005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156122e157600080fd5b919050565b601860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156123b057600080fd5b600260149054906101000a900460ff1615156123cb57600080fd5b80601860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa44619930581604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600b6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061254d57506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b806125a55750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156125b057600080fd5b600260149054906101000a900460ff161515156125cc57600080fd5b6001600260146101000a81548160ff021916908315150217905550565b606060006125f68361230c565b9050600081141561263a5760006040519080825280602002602001820160405280156126315781602001602082028038833980820191505090505b50915050612732565b60608160405190808252806020026020018201604052801561266b5781602001602082028038833980820191505090505b50905060006126786117f6565b905060008090506000600190505b8281111515612729578673ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561271c5780848381518110151561270557fe5b906020019060200201818152505081806001019250505b8080600101915050612686565b83955050505050505b919050565b600033876005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156127a957600080fd5b60008585604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120905060008911156128715788601260008381526020019081526020016000205414151515612870576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f5369676e617475726520416c726561647920557365640000000000000000000081525060200191505060405180910390fd5b5b600560008b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660018b604051602001808281526020019150506040516020818303038152906040528051906020012089898960405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561293e573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614151561296a57600080fd5b6000339050600073ffffffffffffffffffffffffffffffffffffffff16600b60008c815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515156129de57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600b60008c815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515612a4c57600080fd5b612a54613ab5565b6020604051908101604052808b1515815250905060006001600f8390806001815401808255809150509060018203906000526020600020016000909192909190915060008201518160000160006101000a81548160ff02191690831515021790555050500390508063ffffffff1681141515612acf57600080fd5b7fa10f25ef783c24056e27eb55eb6c0ac1c4863cd5eab7e657cd067926b3dce0648382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1826010600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600d60008d81526020019081526020016000208190806001815401808255809150509060018203906000526020600020016000909192909190915055508b60116000838152602001908152602001600020819055508b60126000868152602001908152602001600020819055508096505050505050509695505050505050565b600034601354808210151515612c2157600080fd5b60003390506000600b600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612c9a57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff16600b600088815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515612d0857600080fd5b612d10613acb565b602060405190810160405280348152509050600060016014839080600181540180825580915050906001820390600052602060002001600090919290919091506000820151816000015550500390508063ffffffff1681141515612d7357600080fd5b836015600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508760166000838152602001908152602001600020819055506000606434604602811515612dee57fe5b0490506000600d60008b815260200190815260200160002080549050823403811515612e1657fe5b049050600b60008b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015612e92573d6000803e3d6000fd5b5060008090505b600d60008c815260200190815260200160002080549050811015612fcf5760106000600d60008e815260200190815260200160002083815481101515612edb57fe5b9060005260206000200154815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015612f5a573d6000803e3d6000fd5b5060176000858152602001908152602001600020600d60008d815260200190815260200160002082815481101515612f8e57fe5b906000526020600020015490806001815401808255809150509060018203906000526020600020016000909192909190915055508080600101915050612e99565b507f6ea1e5e03071ff9bad53b614eafcc00d29db646e9c351fcc00d45a4118d7c51a8684604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a18298505050505050505050919050565b6040805190810160405280600281526020017f425600000000000000000000000000000000000000000000000000000000000081525081565b60056020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606000600a838154811015156130ca57fe5b906000526020600020019050806000018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561316e5780601f106131435761010080835404028352916020019161316e565b820191906000526020600020905b81548152906001019060200180831161315157829003601f168201915b5050505050915050919050565b600080600f8381548110151561318d57fe5b9060005260206000200190508060000160009054906101000a900460ff16915050919050565b60035481565b60135481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60126020528060005260406000206000915090505481565b600080600060048481548110151561321157fe5b90600052602060002090600202019050806000015492508060010154915050915091565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60176020528160005260406000208181548110151561327657fe5b90600052602060002001600091509150505481565b600060086000838152602001908152602001600020805490509050919050565b60066020528060005260406000206000915090505481565b6000346003548082101515156132d857600080fd5b8460007f01000000000000000000000000000000000000000000000000000000000000000281600060208110151561330c57fe5b1a7f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415151561335e57600080fd5b8460007f01000000000000000000000000000000000000000000000000000000000000000281600060208110151561339257fe5b1a7f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141515156133e457600080fd5b60003390506133f1613adf565b60408051908101604052808a81526020018981525090506000600160048390806001815401808255809150509060018203906000526020600020906002020160009091929091909150600082015181600001556020820151816001015550500390508063ffffffff168114151561346757600080fd5b7f982bb66d9aa60573bc0a2066122e1466ecbc4c179a5e7c1c5b589345008ce69a8382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a16134de6000848361381f565b8097505050505050505092915050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561354957600080fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600d6000838152602001908152602001600020805490509050919050565b60156020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c6020528060005260406000206000915090505481565b60076020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60106020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008273ffffffffffffffffffffffffffffffffffffffff166005600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905092915050565b806007600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561377b57600080fd5b600260149054906101000a900460ff16151561379657600080fd5b6000600260146101000a81548160ff021916908315150217905550565b60008273ffffffffffffffffffffffffffffffffffffffff166007600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905092915050565b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906001019190505550816005600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151561397d57600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906001900391905055506007600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b7f70a295484349ac4c2073cdca8ba026869fff31e0d35e268f820e44c9d25f4a2e838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505050565b602060405190810160405280606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613a7657805160ff1916838001178555613aa4565b82800160010185558215613aa4579182015b82811115613aa3578251825591602001919060010190613a88565b5b509050613ab19190613aff565b5090565b6020604051908101604052806000151581525090565b602060405190810160405280600081525090565b604080519081016040528060008019168152602001600080191681525090565b613b2191905b80821115613b1d576000816000905550600101613b05565b5090565b9056fea165627a7a72305820b73bf81476c95567782e45ebae5220573d46c55a9004c11243c470bc91f2d26d0029",
- "storage": {
- "0x05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xa54c2b4154b4f221d71d6d5bc0ec905c931a021bb6fb138fc0495bb0373e2276": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x0000000000000000000000000000000000000001": {
- "balance": "0x0",
- "nonce": "0",
- "code": "0x",
- "storage": {}
- },
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0xcec3d4daf44926cc41e",
- "nonce": "147795",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "567688",
- "difficulty": "2028219",
- "timestamp": "1577578023",
- "gasLimit": "23504477",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf9018f8302415385746a52880083048196948521f13dd5e4bc3dab3cf0f01a195a5af899e85180b90124200b1e64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001b9af799918107e9a339eba0584b8b60b35aae6f087c74f6bfc00c9301849b204d094ed65e09c76c2597f5516f9440aad2921e50dde096e7caaa65a536d4d9265e00000000000000000000000000000000000000000000000000000000000000504269747669657720697320616e20616d617a696e6720776562736974652e20596f752073686f756c6420646566696e6974656c792061646420796f75722070726f6475637420746f2069742e20e282bf0000000000000000000000000000000081a2a0686e4a69e1fa6cac6b4f751a3935ca5a371d720c34d3a7136988aa017a528ed5a07d993e607b665c24557d0eae166c21fe744e618ed3430902ac6206c63a331dc0",
- "result": [
- {
- "action": {
- "author": "0x0000000000000000000000000000000000000000",
- "address": "0x0000000000000000000000000000000000000000",
- "balance": "0x0",
- "callType": "call",
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "gas": "0x48196",
- "input": "0x200b1e64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001b9af799918107e9a339eba0584b8b60b35aae6f087c74f6bfc00c9301849b204d094ed65e09c76c2597f5516f9440aad2921e50dde096e7caaa65a536d4d9265e00000000000000000000000000000000000000000000000000000000000000504269747669657720697320616e20616d617a696e6720776562736974652e20596f752073686f756c6420646566696e6974656c792061646420796f75722070726f6475637420746f2069742e20e282bf00000000000000000000000000000000",
- "refundAddress": "0x0000000000000000000000000000000000000000",
- "to": "0x8521f13dd5e4bc3dab3cf0f01a195a5af899e851",
- "value": "0x0"
- },
- "error": "execution reverted",
- "result": {
- "gasUsed": "0x947c"
- },
- "subtraces": 0,
- "traceAddress": [],
- "type": "call"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json
deleted file mode 100644
index 16d43767d5..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json
+++ /dev/null
@@ -1,92 +0,0 @@
-{
- "genesis": {
- "number": "553153",
- "hash": "0x88bde20840880a1f3fba92121912a3cc0d3b26d76e4d914fbd85fc2e43da3b3f",
- "nonce": "0x7be554ffe4b82fc2",
- "mixHash": "0xf73d2ff3c16599c3b8a24b9ebde6c09583b5ee3f747d3cd37845d564f4c8d87a",
- "stateRoot": "0x40b5f53d610108947688a04fb68838ff9c0aa0dd6e54156b682537192171ff5c",
- "miner": "0x774c398d763161f55b66a646f17edda4addad2ca",
- "difficulty": "1928226",
- "totalDifficulty": "457857582215",
- "extraData": "0xd983010907846765746888676f312e31332e358664617277696e",
- "gasLimit": "7999473",
- "timestamp": "1577392669",
- "alloc": {
- "0x877bd459c9b7d8576b44e59e09d076c25946f443": {
- "balance": "0x19bb4ac611ca7a1fc881",
- "nonce": "701",
- "code": "0x",
- "storage": {}
- },
- "0x8ee79c5b3f6e1d214d2c4fcf7ea4092a32e26e91": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000877bd459c9b7d8576b44e59e09d076c25946f443"
- }
- }
- },
- "config": {
- "chainId": 63,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 0,
- "eip158Block": 0,
- "ethash": {},
- "homesteadBlock": 0,
- "byzantiumBlock": 0,
- "constantinopleBlock": 301243,
- "petersburgBlock": 999983,
- "istanbulBlock": 999983
- }
- },
- "context": {
- "number": "553154",
- "difficulty": "1929167",
- "timestamp": "1577392670",
- "gasLimit": "8000000",
- "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "input": "0xf86c8202bd850ee6b280008344aa20948ee79c5b3f6e1d214d2c4fcf7ea4092a32e26e91808441c0e1b581a2a03f95ca5cdf7fd727630341c4c6aa1b64ccd9949bd9ecc72cfdd7ce17a2013a69a06d34795ef7fb0108a6dbee4ae0a1bdc48dcd2a4ee53bb6a33d45515af07bb9a8",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443",
- "gas": "0x44aa20",
- "input": "0x41c0e1b5",
- "to": "0x8ee79c5b3f6e1d214d2c4fcf7ea4092a32e26e91",
- "value": "0x0"
- },
- "blockHash": "0xf641c3b0f82b07cd3a528adb9927dd83eeb4f1682e2bd523ed36888e0d82c9a9",
- "blockNumber": 553154,
- "result": {
- "gasUsed": "0x347a",
- "output": "0x"
- },
- "subtraces": 1,
- "traceAddress": [],
- "transactionHash": "0x6af0a5c3188ffacae4d340d4a17e14fdb5a54187683a80ef241bde248189882b",
- "transactionPosition": 15,
- "type": "call"
- },
- {
- "action": {
- "address": "0x8ee79c5b3f6e1d214d2c4fcf7ea4092a32e26e91",
- "balance": "0x0",
- "refundAddress": "0x877bd459c9b7d8576b44e59e09d076c25946f443"
- },
- "blockHash": "0xf641c3b0f82b07cd3a528adb9927dd83eeb4f1682e2bd523ed36888e0d82c9a9",
- "blockNumber": 553154,
- "subtraces": 0,
- "traceAddress": [
- 0
- ],
- "transactionHash": "0x6af0a5c3188ffacae4d340d4a17e14fdb5a54187683a80ef241bde248189882b",
- "transactionPosition": 15,
- "type": "suicide"
- }
- ]
-}
\ No newline at end of file
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json
deleted file mode 100644
index a001178a42..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "context": {
- "difficulty": "117009631",
- "gasLimit": "4712388",
- "miner": "0x294e5d6c39a36ce38af1dca70c1060f78dee8070",
- "number": "25009",
- "timestamp": "1479891666"
- },
- "genesis": {
- "alloc": {
- "0x70c9217d814985faef62b124420f8dfbddd96433": {
- "balance": "0x4ecd70668f5d854a",
- "code": "0x",
- "nonce": "1638",
- "storage": {}
- },
- "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": {
- "balance": "0x0",
- "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000061a9",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433"
- }
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "117066792",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712388",
- "hash": "0xe23e8d4562a1045b70cbc99fefb20c101a8f0fc8559a80d65fea8896e2f1d46e",
- "miner": "0x71842f946b98800fe6feb49f0ae4e253259031c9",
- "mixHash": "0x0aada9d6e93dd4db0d09c0488dc0a048fca2ccdc1f3fc7b83ba2a8d393a3a4ff",
- "nonce": "0x70849d5838dee2e9",
- "number": "25008",
- "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b",
- "timestamp": "1479891641",
- "totalDifficulty": "1896347038589"
- },
- "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750",
- "result": [
- {
- "action": {
- "callType": "call",
- "from": "0x70c9217d814985faef62b124420f8dfbddd96433",
- "gas": "0x3d090",
- "input": "0x51a34eb8000000000000000000000000000000000000000000000027fad02094277c0000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "value": "0x0"
- },
- "blockNumber": 25009,
- "error": "invalid jump destination",
- "result": {},
- "subtraces": 0,
- "traceAddress": [],
- "type": "call"
- }
- ]
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json
deleted file mode 100644
index df0b2872b4..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "context": {
- "difficulty": "3755480783",
- "gasLimit": "5401723",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "number": "2294702",
- "timestamp": "1513676146"
- },
- "genesis": {
- "alloc": {
- "0x13e4acefe6a6700604929946e70e6443e4e73447": {
- "balance": "0xcf3e0938579f000",
- "code": "0x",
- "nonce": "9",
- "storage": {}
- },
- "0x7dc9c9730689ff0b0fd506c67db815f12d90a448": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3757315409",
- "extraData": "0x566961425443",
- "gasLimit": "5406414",
- "hash": "0xae107f592eebdd9ff8d6ba00363676096e6afb0e1007a7d3d0af88173077378d",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "mixHash": "0xc927aa05a38bc3de864e95c33b3ae559d3f39c4ccd51cef6f113f9c50ba0caf1",
- "nonce": "0x93363bbd2c95f410",
- "number": "2294701",
- "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c",
- "timestamp": "1513676127",
- "totalDifficulty": "7160808139332585"
- },
- "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f",
- "result": {
- "from": "0x13e4acefe6a6700604929946e70e6443e4e73447",
- "gas": "0x897be",
- "gasUsed": "0x897be",
- "input": "0x606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a11",
- "output": "0x606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029",
- "to": "0x7dc9c9730689ff0b0fd506c67db815f12d90a448",
- "type": "CREATE",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json
deleted file mode 100644
index 80fc0b0ada..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json
+++ /dev/null
@@ -1,415 +0,0 @@
-{
- "context": {
- "difficulty": "117066904",
- "gasLimit": "4712384",
- "miner": "0x1977c248e1014cc103929dd7f154199c916e39ec",
- "number": "25001",
- "timestamp": "1479891545"
- },
- "genesis": {
- "alloc": {
- "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38": {
- "balance": "0x0",
- "code": "0x606060405236156100825760e060020a600035046302d05d3f811461008a5780630accce061461009c5780631ab9075a146100c757806331ed274614610102578063645a3b7214610133578063772fdae314610155578063a7f4377914610180578063ae5f80801461019e578063c9bded21146101ea578063f905c15a14610231575b61023a610002565b61023c600054600160a060020a031681565b61023a600435602435604435606435608435600254600160a060020a03166000141561024657610002565b61023a600435600254600160a060020a03166000148015906100f8575060025433600160a060020a03908116911614155b156102f457610002565b61023a60043560243560443560643560843560a43560c435600254600160a060020a03166000141561031657610002565b61023a600435602435600254600160a060020a0316600014156103d057610002565b61023a600435602435604435606435608435600254600160a060020a03166000141561046157610002565b61023a60025433600160a060020a0390811691161461051657610002565b61023a6004356024356044356060828152600160a060020a0382169060ff8516907fa6c2f0913db6f79ff0a4365762c61718973b3413d6e40382e704782a9a5099f690602090a3505050565b61023a600435602435600160a060020a038116606090815260ff8316907fee6348a7ec70f74e3d6cba55a53e9f9110d180d7698e9117fc466ae29a43e34790602090a25050565b61023c60035481565b005b6060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061029d57610002565b60408051858152602081018390528151600160a060020a03858116939087169260ff8a16927f5a690ecd0cb15c1c1fd6b6f8a32df0d4f56cb41a54fea7e94020f013595de796929181900390910190a45050505050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061036d57610002565b6040805186815260208101869052808201859052606081018490529051600160a060020a03831691889160ff8b16917fd65d9ddafbad8824e2bbd6f56cc9f4ac27ba60737035c10a321ea2f681c94d47919081900360800190a450505050505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061042757610002565b60408051828152905183917fa9c6cbc4bd352a6940479f6d802a1001550581858b310d7f68f7bea51218cda6919081900360200190a25050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104b857610002565b80600160a060020a031684600160a060020a03168660ff167f69bdaf789251e1d3a0151259c0c715315496a7404bce9fd0b714674685c2cab78686604051808381526020018281526020019250505060405180910390a45050505050565b600254600160a060020a0316ff",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0x2cccf5e0538493c235d1c5ef6580f77d99e91396": {
- "balance": "0x0",
- "code": "0x606060405236156100775760e060020a600035046302d05d3f811461007f57806313bc6d4b146100915780633688a877146100b95780635188f9961461012f5780637eadc976146101545780638ad79680146101d3578063a43e04d814610238578063a7f437791461025e578063e16c7d981461027c575b61029f610002565b6102a1600054600160a060020a031681565b6102be600435600160a060020a03811660009081526002602052604090205460ff165b919050565b6102d26004356040805160208181018352600080835284815260038252835190849020805460026001821615610100026000190190911604601f8101849004840283018401909552848252929390929183018282801561037d5780601f106103525761010080835404028352916020019161037d565b61029f6004356024356000805433600160a060020a039081169116146104a957610002565b61034060043560008181526001602090815260408083205481517ff905c15a0000000000000000000000000000000000000000000000000000000081529151600160a060020a03909116928392839263f905c15a92600483810193919291829003018189876161da5a03f1156100025750506040515195945050505050565b60408051602060248035600481810135601f810185900485028601850190965285855261029f9581359591946044949293909201918190840183828082843750949650505050505050600054600160a060020a0390811633909116146104f657610002565b61029f6004355b600080548190600160a060020a0390811633909116146105a457610002565b61029f60005433600160a060020a0390811691161461072957610002565b6102a1600435600081815260016020526040902054600160a060020a03166100b4565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103325780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b505050505090506100b4565b506000828152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a038581168086526002909352818520805460ff191690941790935580517f1ab9075a0000000000000000000000000000000000000000000000000000000081523090931660048401525184939192631ab9075a926024828101939192829003018183876161da5a03f11561000257505060408051602081018690528082019290925243606083015260808083526003908301527f414444000000000000000000000000000000000000000000000000000000000060a0830152517f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d39181900360c00190a15b505050565b600083815260016020526040902054600160a060020a03838116911614156104d0576104a4565b600083815260016020526040812054600160a060020a031614610389576103898361023f565b600082815260036020908152604082208054845182855293839020919360026001831615610100026000190190921691909104601f90810184900483019391929186019083901061056a57805160ff19168380011785555b5061059a9291505b808211156105a05760008155600101610556565b8280016001018555821561054e579182015b8281111561054e57825182600050559160200191906001019061057c565b50505050565b5090565b600083815260016020526040812054600160a060020a031614156105c757610002565b50506000818152600160205260408082205481517fa7f437790000000000000000000000000000000000000000000000000000000081529151600160a060020a0391909116928392839263a7f4377992600483810193919291829003018183876161da5a03f11561000257505050600160005060008460001916815260200190815260200160002060006101000a815490600160a060020a0302191690556002600050600083600160a060020a0316815260200190815260200160002060006101000a81549060ff02191690557f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d383834360405180806020018560001916815260200184600160a060020a03168152602001838152602001828103825260038152602001807f44454c000000000000000000000000000000000000000000000000000000000081526020015060200194505050505060405180910390a1505050565b600054600160a060020a0316ff",
- "nonce": "1",
- "storage": {
- "0x0684ac65a9fa32414dda56996f4183597d695987fdb82b145d722743891a6fe8": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "0x1cd76f78169a420d99346e3501dd3e541622c38a226f9b63e01cfebc69879dc7": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "0x8e54a4494fe5da016bfc01363f4f6cdc91013bb5434bd2a4a3359f13a23afa2f": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf",
- "0x94edf7f600ba56655fd65fca1f1424334ce369326c1dc3e53151dcd1ad06bc13": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xbbee47108b275f55f98482c6800f6372165e88b0330d3f5dae6419df4734366c": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "0xd38c0c4e84de118cfdcc775130155d83b8bbaaf23dc7f3c83a626b10473213bd": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xfb3aa5c655c2ec9d40609401f88d505d1da61afaa550e36ef5da0509ada257ba": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113"
- }
- },
- "0x3e9286eafa2db8101246c2131c09b49080d00690": {
- "balance": "0x0",
- "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063056d4470146100e957806316c66cc61461010c5780631ab9075a146101935780633ae1005c146101ce57806358541662146101fe5780635ed61af014610231578063644e3b791461025457806384dbac3b146102db578063949ae479146102fd5780639859387b14610321578063a7f4377914610340578063ab03fc261461035e578063e8161b7814610385578063e964d4e114610395578063f905c15a146103a5578063f92eb774146103ae575b6103be610002565b6103c0600054600160a060020a031681565b6103be6004356002546000908190600160a060020a031681141561040357610002565b6103dd60043560006108365b6040805160025460e360020a631c2d8fb30282527f636f6e747261637464620000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435600254600160a060020a03166000148015906101c4575060025433600160a060020a03908116911614155b1561088d57610002565b6103be600435602435604435606435600254600090819081908190600160a060020a03168114156108af57610002565b6103c0600435602435604435606435608435600254600090819081908190600160a060020a03168114156110e857610002565b6103be6004356002546000908190600160a060020a03168114156115ec57610002565b6103c06004356000611b635b6040805160025460e360020a631c2d8fb30282527f6d61726b6574646200000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435602435600254600160a060020a031660001415611bb557610002565b6103be600435602435600254600090600160a060020a0316811415611d2e57610002565b6103be600435600254600160a060020a031660001415611fc657610002565b6103be60025433600160a060020a0390811691161461207e57610002565b6103be600435602435604435600254600090600160a060020a031681141561208c57610002565b6103dd60043560006124b8610260565b6103c0600435600061250a610118565b6103f160035481565b6103f16004356000612561610260565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061046557610002565b8291506104e55b6040805160025460e360020a631c2d8fb30282527f63706f6f6c00000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f115610002575050604051519150505b90565b600160a060020a031663b2206e6d83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fb2206e6d0000000000000000000000000000000000000000000000000000000082526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f11561000257505060405151915061059b90506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f115610002575050506107355b6040805160025460e360020a631c2d8fb30282527f6c6f676d6772000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b50826120ee5b6040805160025460e360020a631c2d8fb30282527f6163636f756e7463746c0000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316630accce06600684600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150866040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050505050565b600160a060020a03166316c66cc6836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519150505b919050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061091157610002565b87935061091c610260565b600160a060020a031663bdbdb08685600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fbdbdb0860000000000000000000000000000000000000000000000000000000082526004820152602481018a905290516044808301935060209282900301816000876161da5a03f1156100025750506040515193506109ca90506106ba565b600160a060020a03166381982a7a8885876040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610a3661046c565b600160a060020a03166308636bdb85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517f08636bdb000000000000000000000000000000000000000000000000000000008252600482015260248101889052604481019290925251606482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919450600160a060020a03871692506314baa1b6916024828101926000929190829003018183876161da5a03f11561000257505050610b3561046c565b600160a060020a0316630a3b6ede85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038d16602482015290516044808301935060209282900301816000876161da5a03f115610002575050604051519150610bd590506106ba565b600160a060020a031663d5b205ce87838b6040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610c41610118565b600160a060020a031663988db79c888a6040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050610ca5610260565b600160a060020a031663f4f2821b896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610d6f5b6040805160025460e360020a631c2d8fb30282527f747261646564620000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316635f539d69896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610dc2610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928e9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610ec5610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928d9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610fc8610639565b600160a060020a031663645a3b7285600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151905061101e610260565b600160a060020a031663f92eb77488600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f115610002575050505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061114a57610002565b604051600254600160a060020a0316908a908a908a908a908a90611579806125b38339018087600160a060020a0316815260200186600160a060020a03168152602001856000191681526020018481526020018381526020018281526020019650505050505050604051809103906000f092506111c5610118565b600160a060020a031663b9858a288a856040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611229610260565b600160a060020a0316635188f99689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611288610260565b600160a060020a031663bdbdb08689896040518360e060020a0281526004018083600019168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750506040515192506112e590506106ba565b600160a060020a03166346d88e7d8a858a6040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506000604051808303816000876161da5a03f115610002575050506113516106ba565b600160a060020a03166381982a7a8a84866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050506113bd61046c565b600160a060020a0316632b58469689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f1156100025750505061141c61046c565b600160a060020a03166308636bdb8984866040518460e060020a028152600401808460001916815260200183815260200182600160a060020a0316815260200193505050506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919350600160a060020a03861692506314baa1b6916024828101926000929190829003018183876161da5a03f115610002575050506114d3610639565b6040805160e160020a630566670302815260016004820152602481018b9052600160a060020a0386811660448301528c811660648301526000608483018190529251931692630accce069260a480840193919291829003018183876161da5a03f11561000257505050611544610639565b600160a060020a031663645a3b728961155b610260565b600160a060020a031663f92eb7748c6040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448084019360009350829003018183876161da5a03f1156100025750939a9950505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061164e57610002565b82915061165961046c565b600160a060020a0316630a3b6ede83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f1156100025750506040515191506116f990506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f1156100025750505061179b6106ba565b600160a060020a031663d653078983600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517ff1ff78a0000000000000000000000000000000000000000000000000000000008252915191929163f1ff78a09160048181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f1156100025750505061189f610260565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506118f2610118565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050611945610639565b600160a060020a0316630accce06600484600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da44689181870191602091908190038801816000876161da5a03f115610002575050506040518051906020015060006040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050611a48610639565b600160a060020a031663645a3b7283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611a9e610260565b600160a060020a031663f92eb77486600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b600160a060020a03166381738c59836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611c1757610002565b611c1f610260565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060405151159050611c7457610002565b611c7c610260565b600160a060020a0316632243118a836040518260e060020a02815260040180826000191681526020019150506000604051808303816000876161da5a03f11561000257505050611cca610639565b600160a060020a031663ae5f8080600184846040518460e060020a028152600401808481526020018360001916815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611d9057610002565b5081611d9a610260565b600160a060020a031663581d5d6084846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505050611df5610639565b600160a060020a0316630accce06600283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630566670302825260048201949094526024810193909352600160a060020a038816604484015260006064840181905260848401819052905160a4808501949293509091829003018183876161da5a03f11561000257505050611eab610639565b600160a060020a031663645a3b7282600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611f01610260565b600160a060020a031663f92eb77485600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061202857610002565b612030610118565b600160a060020a0316639859387b826040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505050565b600254600160a060020a0316ff5b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f11561000257505060405151151590506106b457610002565b600160a060020a031663d65307898383600160a060020a031663f1ff78a06040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fd6530789000000000000000000000000000000000000000000000000000000008252600160a060020a039485166004830152602482015292891660448401525160648381019360009350829003018183876161da5a03f115610002575050506121a5610118565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506121f8610cf4565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505061224b610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d028252915191928a9290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f1156100025750505080600160a060020a031663ea71b02d6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a031660001490506124b25761239f610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fea71b02d000000000000000000000000000000000000000000000000000000008252915191928a92909163ea71b02d91600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f115610002575050505b50505050565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663213fe2b7836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663f92eb774836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f115610002575050604051519150610888905056606060405260405160c08061157983396101206040819052825160805160a051935160e0516101005160008054600160a060020a03199081163317909155600180546005805484168817905560048a90556006869055600b8590556008849055909116861760a060020a60ff02191690554360038190556002558686526101408390526101608190529396929594919390929091600160a060020a033016917f76885d242fb71c6f74a7e717416e42eff4d96faf54f6de75c6a0a6bbd8890c6b91a230600160a060020a03167fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff600b600050546040518082815260200191505060405180910390a250505050505061145e8061011b6000396000f3606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "16",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0x70c9217d814985faef62b124420f8dfbddd96433": {
- "balance": "0x4ef436dcbda6cd4a",
- "code": "0x",
- "nonce": "1634",
- "storage": {}
- },
- "0x7986bad81f4cbd9317f5a46861437dae58d69113": {
- "balance": "0x0",
- "code": "0x6060604052361561008d5760e060020a600035046302d05d3f811461009557806316c66cc6146100a75780631ab9075a146100d7578063213fe2b7146101125780639859387b1461013f578063988db79c1461015e578063a7f4377914610180578063b9858a281461019e578063c8e40fbf146101c0578063f4f2821b146101e8578063f905c15a14610209575b610212610002565b610214600054600160a060020a031681565b600160a060020a0360043581811660009081526005602052604081205461023193168114610257575060016101e3565b610212600435600254600160a060020a0316600014801590610108575060025433600160a060020a03908116911614155b1561025f57610002565b610214600435600160a060020a03811660009081526004602052604081205460ff16151561027557610002565b610212600435600254600160a060020a03166000141561029b57610002565b610212600435602435600254600160a060020a03166000141561050457610002565b61021260025433600160a060020a0390811691161461056757610002565b610212600435602435600254600160a060020a03166000141561057557610002565b610231600435600160a060020a03811660009081526004602052604090205460ff165b919050565b610212600435600254600090600160a060020a031681141561072057610002565b61024560035481565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060006101e3565b60028054600160a060020a031916821790555b50565b50600160a060020a038181166000908152600460205260409020546101009004166101e3565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506102fe57610002565b600160a060020a03811660009081526004602052604090205460ff161515610272576040516104028061092e833901809050604051809103906000f06004600050600083600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600083600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555050565b600160a060020a03821660009081526004602052604090205460ff1615156104725760405161040280610d30833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a03811660009081526006602052604090208054600160a060020a031916831790555b5050565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506103b957610002565b600254600160a060020a0316ff5b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506105d857610002565b600160a060020a03821660009081526004602052604090205460ff1615156106915760405161040280611132833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a031660009081526005602052604090208054600160a060020a0319169091179055565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f115610002575050604051511515905061078357610002565b50600160a060020a0381811660009081526005602090815260408083205490931680835260049091529190205460ff161561080f576040600081812054825160e260020a632e72bafd028152600160a060020a03868116600483015293516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260056020526040812054909116146108545760406000908120600160a060020a0384169091528054600160a060020a03191690555b50600160a060020a0381811660009081526006602090815260408083205490931680835260049091529190205460ff16156108e657600160a060020a038181166000908152604080518183205460e260020a632e72bafd028252868516600483015291516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260066020526040812054909116146105005760406000908120600160a060020a0384169091528054600160a060020a0319169055505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056",
- "nonce": "7",
- "storage": {
- "0xffc4df2d4f3d2cffad590bed6296406ab7926ca9e74784f74a95191fa069a174": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433"
- }
- },
- "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f": {
- "balance": "0x0",
- "code": "0x606060405236156100ae5760e060020a600035046302d05d3f81146100b65780631ab9075a146100c85780632b68bb2d146101035780634cc927d7146101c557806351a34eb81461028e57806356ccb6f0146103545780635928d37f1461041d578063599efa6b146104e9578063759297bb146105b2578063771d50e11461067e578063a7f4377914610740578063f905c15a1461075e578063f92eb77414610767578063febf661214610836575b610902610002565b610904600054600160a060020a031681565b610902600435600254600160a060020a03166000148015906100f9575060025433600160a060020a03908116911614155b1561092057610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061094257610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610a0d57610002565b61090260043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ae957610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610bbc57610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610c9657610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610de057610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ebb57610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f9e57610002565b61090260025433600160a060020a0390811691161461106957610002565b61090e60035481565b61090e60043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750506040805180517ff92eb774000000000000000000000000000000000000000000000000000000008252600482018790529151919350600160a060020a038416925063f92eb774916024828101926020929190829003018188876161da5a03f11561000257505060405151949350505050565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061107757610002565b005b6060908152602090f35b60408051918252519081900360200190f35b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5ed61af000000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152925190959286169350635ed61af092602483810193919291829003018183876161da5a03f115610002575050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fab03fc2600000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015260248301899052808816604484015292519095928616935063ab03fc2692606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f949ae47900000000000000000000000000000000000000000000000000000000825233600160a060020a0390811660048401526024830188905292519095928616935063949ae47992604483810193919291829003018183876161da5a03f11561000257505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f46d88e7d000000000000000000000000000000000000000000000000000000008252600160a060020a0380891660048401523381166024840152604483018890529251909592861693506346d88e7d92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5315cdde00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a16602484015260448301889052925190959286169350635315cdde92606483810193919291829003018183876161da5a03f115610002575050604080517f5928d37f00000000000000000000000000000000000000000000000000000000815233600160a060020a03908116600483015287166024820152604481018690529051635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fe68e401c00000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015280891660248401526044830188905292519095928616935063e68e401c92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5152f381000000000000000000000000000000000000000000000000000000008252600160a060020a03808a1660048401528089166024840152604483018890523381166064840152925190959286169350635152f38192608483810193919291829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f056d447000000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015292519095928616935063056d447092602483810193919291829003018183876161da5a03f115610002575050505050565b600254600160a060020a0316ff5b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f3ae1005c00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a166024840152808916604484015260648301889052925190959286169350633ae1005c92608483810193919291829003018183876161da5a03f11561000257505050505050505056",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396"
- }
- },
- "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": {
- "balance": "0x0",
- "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000006195",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000008ac7230489e80000",
- "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000"
- }
- },
- "0xcf00ffd997ad14939736f026006498e3f099baaf": {
- "balance": "0x0",
- "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063031e7f5d146100e95780631ab9075a1461010b5780632243118a1461014657806327aad68a1461016557806338a699a4146101da5780635188f996146101f8578063581d5d601461021e57806381738c5914610246578063977da54014610269578063a07421ce14610288578063a7f43779146102be578063bdbdb086146102dc578063e1c7111914610303578063f4f2821b14610325578063f905c15a1461034a578063f92eb77414610353575b610387610002565b610389600054600160a060020a031681565b610387600435602435600254600160a060020a0316600014156103a857610002565b610387600435600254600160a060020a031660001480159061013c575060025433600160a060020a03908116911614155b1561042957610002565b610387600435600254600160a060020a03166000141561044b57610002565b6102ac60043560008181526004602081815260408320547f524d81d3000000000000000000000000000000000000000000000000000000006060908152610100909104600160a060020a031692839263524d81d3926064928188876161da5a03f1156100025750506040515192506103819050565b61039c60043560008181526004602052604090205460ff165b919050565b6103876004356024356002546000908190600160a060020a031681141561079457610002565b61038760043560243560025460009081908190600160a060020a031681141561080457610002565b61038960043560008181526004602052604081205460ff1615156109e357610002565b610387600435600254600160a060020a0316600014156109fb57610002565b600435600090815260096020526040902054670de0b6b3a764000090810360243502045b60408051918252519081900360200190f35b61038760025433600160a060020a03908116911614610a9257610002565b600435600090815260086020526040902054670de0b6b3a7640000602435909102046102ac565b610387600435602435600254600160a060020a031660001415610aa057610002565b61038760043560025460009081908190600160a060020a0316811415610b3657610002565b6102ac60035481565b6102ac600435600081815260076020908152604080832054600690925290912054670de0b6b3a76400000204805b50919050565b005b600160a060020a03166060908152602090f35b15156060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506103fe57610002565b60008281526004602052604090205460ff16151561041b57610002565b600860205260406000205550565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104a157610002565b604080516000838152600460205291909120805460ff1916600117905561040280610de2833901809050604051809103906000f0600460005060008360001916815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555066470de4df8200006008600050600083600019168152602001908152602001600020600050819055506703782dace9d9000060096000506000836000191681526020019081526020016000206000508190555050565b600460005060008560001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151821415905061060057838152600660209081526040808320839055600790915281208190555b81600160a060020a0316630a3b0a4f846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050600160a060020a038316808252600560209081526040808420879055805160e160020a6364a81ff102815290518694670de0b6b3a7640000949363c9503fe29360048181019492939183900301908290876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008660001916815260200190815260200160002060008282825054019250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000866000191681526020019081526020016000206000828282505401925050819055505b50505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f11561000257505060405151151590506107e957610002565b8381526004602052604081205460ff16151561056657610002565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f115610002575050604051511515905061085957610002565b849250670de0b6b3a764000083600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575060408051805160e160020a6364a81ff102825291519189028590049650600481810192602092909190829003018188876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b9391600481810192602092909190829003018189876161da5a03f115610002575050506040518051906020015002049050806006600050600085600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750604080518051855260208681528286208054989098039097557f2e94420f00000000000000000000000000000000000000000000000000000000815290518896600483810193919291829003018187876161da5a03f115610002575050604080515183526020939093525020805490910190555050505050565b60409020546101009004600160a060020a03166101f3565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610a5157610002565b60008181526004602052604090205460ff161515610a6e57610002565b6040600020805474ffffffffffffffffffffffffffffffffffffffffff1916905550565b600254600160a060020a0316ff5b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610af657610002565b60008281526004602052604090205460ff161515610b1357610002565b670de0b6b3a7640000811115610b2857610002565b600960205260406000205550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f1156100025750506040515115159050610b8b57610002565b600160a060020a038416815260056020908152604080832054808452600490925282205490935060ff161515610bc057610002565b600460005060008460001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663b9caebf4856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506005600050600085600160a060020a0316815260200190815260200160002060005060009055839050600082600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519190911115905061078e57670de0b6b3a764000081600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008560001916815260200190815260200160002060008282825054039250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000856000191681526020019081526020016000206000828282505403925050819055505050505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056",
- "nonce": "3",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x3571d73f14f31a1463bd0a2f92f7fde1653d4e1ead7aedf4b0a5df02f16092ab": "0x0000000000000000000000000000000000000000000007d634e4c55188be0000",
- "0x4e64fe2d1b72d95a0a31945cc6e4f4e524ac5ad56d6bd44a85ec7bc9cc0462c0": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000"
- }
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "117124093",
- "extraData": "0xd5830105008650617269747986312e31322e31826d61",
- "gasLimit": "4707788",
- "hash": "0xad325e4c49145fb7a4058a68ac741cc8607a71114e23fc88083c7e881dd653e7",
- "miner": "0x00714b9ac97fd6bd9325a059a70c9b9fa94ce050",
- "mixHash": "0x0af918f65cb4af04b608fc1f14a849707696986a0e7049e97ef3981808bcc65f",
- "nonce": "0x38dee147326a8d40",
- "number": "25000",
- "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b",
- "timestamp": "1479891517",
- "totalDifficulty": "1895410389427"
- },
- "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065",
- "result": {
- "calls": [
- {
- "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "gas": "0x31217",
- "gasUsed": "0x334",
- "input": "0xe16c7d98636f6e7472616374617069000000000000000000000000000000000000000000",
- "output": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x2a68d",
- "gasUsed": "0x334",
- "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x23ac9",
- "gasUsed": "0x334",
- "input": "0xe16c7d98636f6e7472616374646200000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x23366",
- "gasUsed": "0x273",
- "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x7986bad81f4cbd9317f5a46861437dae58d69113",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x29f35",
- "gasUsed": "0xf8d",
- "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x28a9e",
- "gasUsed": "0x334",
- "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x21d79",
- "gasUsed": "0x24d",
- "input": "0x13bc6d4b000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x2165b",
- "gasUsed": "0x334",
- "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000",
- "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1a8e8",
- "gasUsed": "0x24d",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1a2c6",
- "gasUsed": "0x3cb",
- "input": "0xc9503fe2",
- "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x19b72",
- "gasUsed": "0x3cb",
- "input": "0xc9503fe2",
- "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x19428",
- "gasUsed": "0x305",
- "input": "0x6f265b93",
- "output": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x18d45",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "gas": "0x1734e",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x20ee1",
- "gasUsed": "0x5374",
- "input": "0x581d5d60000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000",
- "output": "0x",
- "to": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1b6c1",
- "gasUsed": "0x334",
- "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1af69",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "gas": "0x143a5",
- "gasUsed": "0x24d",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1a91d",
- "gasUsed": "0x12fa",
- "input": "0x0accce0600000000000000000000000000000000000000000000000000000000000000025842545553440000000000000000000000000000000000000000000000000000000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x",
- "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x19177",
- "gasUsed": "0x334",
- "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x18a22",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x18341",
- "gasUsed": "0x334",
- "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000",
- "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x17bec",
- "gasUsed": "0x229",
- "input": "0x2e94420f",
- "output": "0x5842545553440000000000000000000000000000000000000000000000000000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x1764e",
- "gasUsed": "0x45c",
- "input": "0xf92eb7745842545553440000000000000000000000000000000000000000000000000000",
- "output": "0x00000000000000000000000000000000000000000000002816d180e30c390000",
- "to": "0xcf00ffd997ad14939736f026006498e3f099baaf",
- "type": "CALL",
- "value": "0x0"
- },
- {
- "calls": [
- {
- "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "gas": "0x108ba",
- "gasUsed": "0x24d",
- "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "gas": "0x16e62",
- "gasUsed": "0xebb",
- "input": "0x645a3b72584254555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002816d180e30c390000",
- "output": "0x",
- "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "gas": "0x283b9",
- "gasUsed": "0xc51c",
- "input": "0x949ae479000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000",
- "output": "0x",
- "to": "0x3e9286eafa2db8101246c2131c09b49080d00690",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "gas": "0x30b4a",
- "gasUsed": "0xedb7",
- "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000",
- "output": "0x",
- "to": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0x70c9217d814985faef62b124420f8dfbddd96433",
- "gas": "0x3d090",
- "gasUsed": "0x1810b",
- "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000",
- "output": "0x",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json
deleted file mode 100644
index 2cd28bacc4..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json
+++ /dev/null
@@ -1,97 +0,0 @@
-{
- "context": {
- "difficulty": "31927752",
- "gasLimit": "4707788",
- "miner": "0x5659922ce141eedbc2733678f9806c77b4eebee8",
- "number": "11495",
- "timestamp": "1479735917"
- },
- "genesis": {
- "alloc": {
- "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff": {
- "balance": "0x0",
- "code": "0x606060405236156100825760e060020a60003504630a0313a981146100875780630a3b0a4f146101095780630cd40fea1461021257806329092d0e1461021f5780634cd06a5f146103295780635dbe47e8146103395780637a9e5410146103d9578063825db5f7146103e6578063a820b44d146103f3578063efa52fb31461047a575b610002565b34610002576104fc600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a26333556e849091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f415610002575050604051519150505b919050565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f21ce24d4000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926321ce24d49260448082019391829003018186803b156100025760325a03f415610002575050505b50565b3461000257610512600181565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f89489a87000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926389489a879260448082019391829003018186803b156100025760325a03f4156100025750505061020f565b3461000257610528600435610403565b34610002576104fc600435604080516000602091820181905282517f7d65837a00000000000000000000000000000000000000000000000000000000815260048101829052600160a060020a0385166024820152925190927342b02b5deeb78f34cd5ac896473b63e6c99a71a292637d65837a92604480840193829003018186803b156100025760325a03f4156100025750506040515191506101049050565b3461000257610512600c81565b3461000257610512600081565b3461000257610528600061055660005b600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263685a1f3c9091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b346100025761053a600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263f775b6b59091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b604080519115158252519081900360200190f35b005b6040805160ff9092168252519081900360200190f35b60408051918252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b90509056",
- "nonce": "1",
- "storage": {
- "0x4d140b25abf3c71052885c66f73ce07cff141c1afabffdaf5cba04d625b7ebcc": "0x0000000000000000000000000000000000000000000000000000000000000001"
- }
- },
- "0x269296dddce321a6bcbaa2f0181127593d732cba": {
- "balance": "0x0",
- "code": "0x606060405236156101275760e060020a60003504630cd40fea811461012c578063173825d9146101395780631849cb5a146101c7578063285791371461030f5780632a58b3301461033f5780632cb0d48a146103565780632f54bf6e1461036a578063332b9f061461039d5780633ca8b002146103c55780633df4ddf4146103d557806341c0e1b5146103f457806347799da81461040557806362a51eee1461042457806366907d13146104575780637065cb48146104825780637a9e541014610496578063825db5f7146104a3578063949d225d146104b0578063a51687df146104c7578063b4da4e37146104e6578063b4e6850b146104ff578063bd7474ca14610541578063e75623d814610541578063e9938e1114610555578063f5d241d314610643575b610002565b3461000257610682600181565b34610002576106986004356106ff335b60006001600a9054906101000a9004600160a060020a0316600160a060020a0316635dbe47e8836000604051602001526040518260e060020a0281526004018082600160a060020a03168152602001915050602060405180830381600087803b156100025760325a03f1156100025750506040515191506103989050565b3461000257604080516101008082018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a0360043581168752600586529589902089519788018a528054808816808a52605060020a91829004600160a060020a0316978a01889052600183015463ffffffff8082169d8c018e905264010000000082048116988c01899052604060020a90910416958a018690526002830154948a01859052600390920154808916938a01849052049096169690970186905293969495949293604080516001605060020a03998a16815297891660208901529590971686860152600160a060020a03909316606086015263ffffffff9182166080860152811660a08501521660c083015260e08201929092529051908190036101000190f35b346100025761069a60043560018054600091829160ff60f060020a909104161515141561063d5761072833610376565b34610002576106ae6004546001605060020a031681565b34610002576106986004356108b333610149565b346100025761069a6004355b600160a060020a03811660009081526002602052604090205460ff1615156001145b919050565b34610002576106986001805460ff60f060020a9091041615151415610913576108ed33610376565b346100025761069a600435610149565b34610002576106ae6003546001605060020a03605060020a9091041681565b346100025761069861091533610149565b34610002576106ae6003546001605060020a0360a060020a9091041681565b346100025761069a60043560243560018054600091829160ff60f060020a909104161515141561095e5761092633610376565b34610002576106986004356001805460ff60f060020a909104161515141561072557610a8b33610376565b3461000257610698600435610aa533610149565b3461000257610682600c81565b3461000257610682600081565b34610002576106ae6003546001605060020a031681565b34610002576106ca600154600160a060020a03605060020a9091041681565b346100025761069a60015460ff60f060020a9091041681565b346100025761069a60043560243560443560643560843560a43560c43560018054600091829160ff60f060020a9091041615151415610b5857610ad233610376565b3461000257610698600435610bd633610149565b34610002576106e6600435604080516101008181018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a03808b168752600586529589902089519788018a5280548088168952600160a060020a03605060020a918290041696890196909652600181015463ffffffff8082169b8a019b909b5264010000000081048b1695890195909552604060020a90940490981691860182905260028301549086015260039091015480841696850196909652940416918101919091525b50919050565b346100025761069a60043560243560443560643560843560a43560018054600091829160ff60f060020a9091041615151415610c8e57610bfb33610376565b6040805160ff9092168252519081900360200190f35b005b604080519115158252519081900360200190f35b604080516001605060020a039092168252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b6040805163ffffffff9092168252519081900360200190f35b1561012757600160a060020a0381166000908152600260205260409020805460ff191690555b50565b1561063d57506001605060020a0380831660009081526005602052604090208054909116151561075b576000915061063d565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610817905b8051600354600090819060016001605060020a0390911611610c995760038054605060020a60f060020a0319169055610ddf565b600380546001605060020a031981166000196001605060020a03928316011782558416600090815260056020526040812080547fffff000000000000000000000000000000000000000000000000000000000000168155600181810180546bffffffffffffffffffffffff191690556002820192909255909101805473ffffffffffffffffffffffffffffffffffffffff19169055915061063d565b1561012757600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a8302179055610725565b1561091357600480546001605060020a031981166001605060020a039091166001011790555b565b156101275733600160a060020a0316ff5b1561095e57506001605060020a03808416600090815260056020526040902080549091161515610965576000915061095e565b600191505b5092915050565b60038101546001605060020a0384811691161415610986576001915061095e565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610a12906107e3565b61095983825b80546003546001605060020a0391821691600091161515610de55760038054605060020a60a060020a031916605060020a84021760a060020a69ffffffffffffffffffff02191660a060020a84021781558301805473ffffffffffffffffffffffffffffffffffffffff19169055610ddf565b1561072557600480546001605060020a0319168217905550565b1561012757600160a060020a0381166000908152600260205260409020805460ff19166001179055610725565b15610b5857506001605060020a038088166000908152600560205260409020805490911615610b645760009150610b58565b6004546001605060020a0390811690891610610b3057600480546001605060020a03191660018a011790555b6003805460016001605060020a03821681016001605060020a03199092169190911790915591505b50979650505050505050565b80546001605060020a0319168817605060020a60f060020a031916605060020a880217815560018101805463ffffffff1916871767ffffffff0000000019166401000000008702176bffffffff00000000000000001916604060020a860217905560028101839055610b048982610a18565b156101275760018054605060020a60f060020a031916605060020a8302179055610725565b15610c8e57506001605060020a03808816600090815260056020526040902080549091161515610c2e5760009150610c8e565b8054605060020a60f060020a031916605060020a88021781556001808201805463ffffffff1916881767ffffffff0000000019166401000000008802176bffffffff00000000000000001916604060020a87021790556002820184905591505b509695505050505050565b6003546001605060020a03848116605060020a909204161415610d095760e084015160038054605060020a928302605060020a60a060020a031990911617808255919091046001605060020a031660009081526005602052604090200180546001605060020a0319169055610ddf565b6003546001605060020a0384811660a060020a909204161415610d825760c08401516003805460a060020a92830260a060020a69ffffffffffffffffffff021990911617808255919091046001605060020a03166000908152600560205260409020018054605060020a60a060020a0319169055610ddf565b505060c082015160e08301516001605060020a0380831660009081526005602052604080822060039081018054605060020a60a060020a031916605060020a8702179055928416825290200180546001605060020a031916831790555b50505050565b6001605060020a0384161515610e6457600380546001605060020a03605060020a9182900481166000908152600560205260409020830180546001605060020a0319908116871790915583548785018054918590049093168402605060020a60a060020a03199182161790911690915582549185029116179055610ddf565b506001605060020a038381166000908152600560205260409020600390810180549185018054605060020a60a060020a0319908116605060020a94859004909516808502959095176001605060020a0319168817909155815416918402919091179055801515610ef4576003805460a060020a69ffffffffffffffffffff02191660a060020a8402179055610ddf565b6003808401546001605060020a03605060020a9091041660009081526005602052604090200180546001605060020a031916831790555050505056",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000113204f5d64c28326fd7bd05fd4ea855302d7f2ff00000000000000000000"
- }
- },
- "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2": {
- "balance": "0x0",
- "code": "0x6504032353da7150606060405236156100695760e060020a60003504631bf7509d811461006e57806321ce24d41461008157806333556e84146100ec578063685a1f3c146101035780637d65837a1461011757806389489a8714610140578063f775b6b5146101fc575b610007565b61023460043560006100fd82600061010d565b610246600435602435600160a060020a03811660009081526020839052604081205415156102cb57826001016000508054806001018281815481835581811511610278576000838152602090206102789181019083015b808211156102d057600081556001016100d8565b610248600435602435600182015481105b92915050565b6102346004356024355b60018101906100fd565b610248600435602435600160a060020a03811660009081526020839052604090205415156100fd565b61024660043560243580600160a060020a031632600160a060020a03161415156101f857600160a060020a038116600090815260208390526040902054156101f857600160a060020a038116600090815260208390526040902054600183018054909160001901908110156100075760009182526020808320909101805473ffffffffffffffffffffffffffffffffffffffff19169055600160a060020a038316825283905260408120556002820180546000190190555b5050565b61025c60043560243560008260010160005082815481101561000757600091825260209091200154600160a060020a03169392505050565b60408051918252519081900360200190f35b005b604080519115158252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b50505060009283526020808420909201805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a0385168352908590526040909120819055600284018054600101905590505b505050565b509056",
- "nonce": "1",
- "storage": {}
- },
- "0xa529806c67cc6486d4d62024471772f47f6fd672": {
- "balance": "0x67820e39ac8fe9800",
- "code": "0x",
- "nonce": "68",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "31912170",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712388",
- "hash": "0x0855914bdc581bccdc62591fd438498386ffb59ea4d5361ed5c3702e26e2c72f",
- "miner": "0x334391aa808257952a462d1475562ee2106a6c90",
- "mixHash": "0x64bb70b8ca883cadb8fbbda2c70a861612407864089ed87b98e5de20acceada6",
- "nonce": "0x684129f283aaef18",
- "number": "11494",
- "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10",
- "timestamp": "1479735912",
- "totalDifficulty": "90744064339"
- },
- "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115",
- "result": {
- "calls": [
- {
- "calls": [
- {
- "from": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff",
- "gas": "0x2bf459",
- "gasUsed": "0x2aa",
- "input": "0x7d65837a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2",
- "type": "DELEGATECALL"
- }
- ],
- "from": "0x269296dddce321a6bcbaa2f0181127593d732cba",
- "gas": "0x2cae73",
- "gasUsed": "0xa9d",
- "input": "0x5dbe47e8000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "from": "0xa529806c67cc6486d4d62024471772f47f6fd672",
- "gas": "0x2dc6c0",
- "gasUsed": "0xbd55",
- "input": "0x7065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e",
- "output": "0x",
- "to": "0x269296dddce321a6bcbaa2f0181127593d732cba",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json
deleted file mode 100644
index 07fda21d4b..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json
+++ /dev/null
@@ -1,77 +0,0 @@
-{
- "context": {
- "difficulty": "3451177886",
- "gasLimit": "4709286",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2290744",
- "timestamp": "1513616439"
- },
- "genesis": {
- "alloc": {
- "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a": {
- "balance": "0x0",
- "code": "0x606060405263ffffffff60e060020a6000350416633b91f50681146100505780635bb47808146100715780635f51fca01461008c578063bc7647a9146100ad578063f1bd0d7a146100c8575b610000565b346100005761006f600160a060020a03600435811690602435166100e9565b005b346100005761006f600160a060020a0360043516610152565b005b346100005761006f600160a060020a036004358116906024351661019c565b005b346100005761006f600160a060020a03600435166101fa565b005b346100005761006f600160a060020a0360043581169060243516610db8565b005b600160a060020a038083166000908152602081905260408120549091908116903316811461011657610000565b839150600160a060020a038316151561012d573392505b6101378284610e2e565b6101418284610db8565b61014a826101fa565b5b5b50505050565b600154600160a060020a03908116903316811461016e57610000565b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0384161790555b5b5050565b600254600160a060020a0390811690331681146101b857610000565b600160a060020a038381166000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff19169184169190911790555b5b505050565b6040805160e260020a631a481fc102815260016024820181905260026044830152606482015262093a8060848201819052600060a4830181905260c06004840152601e60c48401527f736574456e7469747953746174757328616464726573732c75696e743829000060e484015292519091600160a060020a038516916369207f049161010480820192879290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526000602482018190526001604483015260606004830152602360648301527f626567696e506f6c6c28616464726573732c75696e7436342c626f6f6c2c626f60848301527f6f6c29000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f61646453746f636b28616464726573732c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f697373756553746f636b2875696e74382c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602160648301527f6772616e7453746f636b2875696e74382c75696e743235362c61646472657373608483015260f860020a60290260a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f115610000575050604080517f010555b8000000000000000000000000000000000000000000000000000000008152600160a060020a03338116602483015260006044830181905260606004840152603c60648401527f6772616e7456657374656453746f636b2875696e74382c75696e743235362c6160848401527f6464726573732c75696e7436342c75696e7436342c75696e743634290000000060a48401529251908716935063010555b89260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601260c48201527f626567696e53616c65286164647265737329000000000000000000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601a60648301527f7472616e7366657253616c6546756e64732875696e743235362900000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152602d60c48201527f7365744163636f756e74696e6753657474696e67732875696e743235362c756960e48201527f6e7436342c75696e7432353629000000000000000000000000000000000000006101048201529051600160a060020a03861692506369207f04916101248082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152603460648301527f637265617465526563757272696e6752657761726428616464726573732c756960848301527f6e743235362c75696e7436342c737472696e672900000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601b60648301527f72656d6f7665526563757272696e675265776172642875696e7429000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602360648301527f697373756552657761726428616464726573732c75696e743235362c7374726960848301527f6e6729000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f61737369676e53746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f72656d6f766553746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260026024808301919091526003604483015260006064830181905267ffffffffffffffff8616608484015260ff871660a484015260c0600484015260c48301919091527f7365744164647265737342796c617728737472696e672c616464726573732c6260e48301527f6f6f6c29000000000000000000000000000000000000000000000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152602160c48301527f73657453746174757342796c617728737472696e672c75696e74382c626f6f6c60e483015260f860020a6029026101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152603860c48301527f736574566f74696e6742796c617728737472696e672c75696e743235362c756960e48301527f6e743235362c626f6f6c2c75696e7436342c75696e74382900000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f115610000575050505b505050565b604080517f225553a4000000000000000000000000000000000000000000000000000000008152600160a060020a0383811660048301526002602483015291519184169163225553a49160448082019260009290919082900301818387803b156100005760325a03f115610000575050505b5050565b600082604051611fd280610f488339600160a060020a03909216910190815260405190819003602001906000f0801561000057905082600160a060020a03166308b027418260016040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b156100005760325a03f115610000575050604080517fa14e3ee300000000000000000000000000000000000000000000000000000000815260006004820181905260016024830152600160a060020a0386811660448401529251928716935063a14e3ee39260648084019382900301818387803b156100005760325a03f115610000575050505b5050505600606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029a165627a7a723058200e78a5f7e0f91739035d0fbf5eca02f79377210b722f63431f29a22e2880b3bd0029",
- "nonce": "789",
- "storage": {
- "0xfe9ec0542a1c009be8b1f3acf43af97100ffff42eb736850fb038fa1151ad4d9": "0x000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8"
- }
- },
- "0x5cb4a6b902fcb21588c86c3517e797b07cdaadb9": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- },
- "0xe4a13bc304682a903e9472f469c33801dd18d9e8": {
- "balance": "0x33c763c929f62c4f",
- "code": "0x",
- "nonce": "14",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3451177886",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4713874",
- "hash": "0x5d52a672417cd1269bf4f7095e25dcbf837747bba908cd5ef809dc1bd06144b5",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x01a12845ed546b94a038a7a03e8df8d7952024ed41ccb3db7a7ade4abc290ce1",
- "nonce": "0x28c446f1cb9748c1",
- "number": "2290743",
- "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708",
- "timestamp": "1513616414",
- "totalDifficulty": "7146523769022564"
- },
- "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281",
- "result": {
- "calls": [
- {
- "error": "internal failure",
- "from": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a",
- "gas": "0x39ff0",
- "gasUsed": "0x39ff0",
- "input": "0x606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182",
- "type": "CREATE",
- "value": "0x0"
- }
- ],
- "error": "invalid jump destination",
- "from": "0xe4a13bc304682a903e9472f469c33801dd18d9e8",
- "gas": "0x493e0",
- "gasUsed": "0x493e0",
- "input": "0x3b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8",
- "to": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json
deleted file mode 100644
index 16e4136230..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json
+++ /dev/null
@@ -1,72 +0,0 @@
-{
- "genesis": {
- "difficulty": "117067574",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712380",
- "hash": "0xe05db05eeb3f288041ecb10a787df121c0ed69499355716e17c307de313a4486",
- "miner": "0x0c062b329265c965deef1eede55183b3acb8f611",
- "mixHash": "0xb669ae39118a53d2c65fd3b1e1d3850dd3f8c6842030698ed846a2762d68b61d",
- "nonce": "0x2b469722b8e28c45",
- "number": "24973",
- "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369",
- "timestamp": "1479891145",
- "totalDifficulty": "1892250259406",
- "alloc": {
- "0x6c06b16512b332e6cd8293a2974872674716ce18": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d146036575b6000565b34600057604e60048080359060200190919050506050565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f19350505050505b5056",
- "storage": {}
- },
- "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31": {
- "balance": "0x229ebbb36c3e0f20",
- "nonce": "3",
- "code": "0x",
- "storage": {}
- }
- },
- "config": {
- "chainId": 3,
- "homesteadBlock": 0,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "byzantiumBlock": 1700000,
- "constantinopleBlock": 4230000,
- "petersburgBlock": 4939394,
- "istanbulBlock": 6485846,
- "muirGlacierBlock": 7117117,
- "ethash": {}
- }
- },
- "context": {
- "number": "24974",
- "difficulty": "117067574",
- "timestamp": "1479891162",
- "gasLimit": "4712388",
- "miner": "0xc822ef32e6d26e170b70cf761e204c1806265914"
- },
- "input": "0xf889038504a81557008301f97e946c06b16512b332e6cd8293a2974872674716ce1880a42e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b1600002aa0e2a6558040c5d72bc59f2fb62a38993a314c849cd22fb393018d2c5af3112095a01bdb6d7ba32263ccc2ecc880d38c49d9f0c5a72d8b7908e3122b31356d349745",
- "result": {
- "type": "CALL",
- "from": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
- "to": "0x6c06b16512b332e6cd8293a2974872674716ce18",
- "value": "0x0",
- "gas": "0x1f97e",
- "gasUsed": "0x72de",
- "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000",
- "output": "0x",
- "calls": [
- {
- "type": "CALL",
- "from": "0x6c06b16512b332e6cd8293a2974872674716ce18",
- "to": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31",
- "value": "0x14d1120d7b160000",
- "error": "internal failure",
- "input": "0x"
- }
- ]
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json
deleted file mode 100644
index a023ed6d9b..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json
+++ /dev/null
@@ -1,81 +0,0 @@
-{
- "context": {
- "difficulty": "3956606365",
- "gasLimit": "5413248",
- "miner": "0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d",
- "number": "2295104",
- "timestamp": "1513681256"
- },
- "genesis": {
- "alloc": {
- "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76": {
- "balance": "0x0",
- "code": "0x60606040526004361061015e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680625b4487146101a257806311df9995146101cb578063278ecde11461022057806330adce0e146102435780633197cbb61461026c5780634bb278f3146102955780636103d70b146102aa57806363a599a4146102bf5780636a2d1cb8146102d457806375f12b21146102fd57806378e979251461032a578063801db9cc1461035357806386d1a69f1461037c5780638da5cb5b146103915780638ef26a71146103e65780639890220b1461040f5780639b39caef14610424578063b85dfb801461044d578063be9a6555146104a1578063ccb07cef146104b6578063d06c91e4146104e3578063d669e1d414610538578063df40503c14610561578063e2982c2114610576578063f02e030d146105c3578063f2fde38b146105d8578063f3283fba14610611575b600060149054906101000a900460ff1615151561017a57600080fd5b60075442108061018b575060085442115b15151561019757600080fd5b6101a03361064a565b005b34156101ad57600080fd5b6101b5610925565b6040518082815260200191505060405180910390f35b34156101d657600080fd5b6101de61092b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561022b57600080fd5b6102416004808035906020019091905050610951565b005b341561024e57600080fd5b610256610c48565b6040518082815260200191505060405180910390f35b341561027757600080fd5b61027f610c4e565b6040518082815260200191505060405180910390f35b34156102a057600080fd5b6102a8610c54565b005b34156102b557600080fd5b6102bd610f3e565b005b34156102ca57600080fd5b6102d261105d565b005b34156102df57600080fd5b6102e76110d5565b6040518082815260200191505060405180910390f35b341561030857600080fd5b6103106110e1565b604051808215151515815260200191505060405180910390f35b341561033557600080fd5b61033d6110f4565b6040518082815260200191505060405180910390f35b341561035e57600080fd5b6103666110fa565b6040518082815260200191505060405180910390f35b341561038757600080fd5b61038f611104565b005b341561039c57600080fd5b6103a4611196565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f157600080fd5b6103f96111bb565b6040518082815260200191505060405180910390f35b341561041a57600080fd5b6104226111c1565b005b341561042f57600080fd5b610437611296565b6040518082815260200191505060405180910390f35b341561045857600080fd5b610484600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061129c565b604051808381526020018281526020019250505060405180910390f35b34156104ac57600080fd5b6104b46112c0565b005b34156104c157600080fd5b6104c9611341565b604051808215151515815260200191505060405180910390f35b34156104ee57600080fd5b6104f6611354565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561054357600080fd5b61054b61137a565b6040518082815260200191505060405180910390f35b341561056c57600080fd5b610574611385565b005b341561058157600080fd5b6105ad600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506116c3565b6040518082815260200191505060405180910390f35b34156105ce57600080fd5b6105d66116db565b005b34156105e357600080fd5b61060f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611829565b005b341561061c57600080fd5b610648600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118fe565b005b600080670de0b6b3a7640000341015151561066457600080fd5b61069b610696670de0b6b3a7640000610688610258346119d990919063ffffffff16565b611a0c90919063ffffffff16565b611a27565b9150660221b262dd80006106ba60065484611a7e90919063ffffffff16565b111515156106c757600080fd5b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156107d557600080fd5b6102c65a03f115156107e657600080fd5b5050506040518051905050610808828260010154611a7e90919063ffffffff16565b8160010181905550610827348260000154611a7e90919063ffffffff16565b816000018190555061084434600554611a7e90919063ffffffff16565b60058190555061085f82600654611a7e90919063ffffffff16565b6006819055503373ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c836040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e8583600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060085442108061096b5750651b48eb57e00060065410155b15151561097757600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154821415156109c757600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515610ac857600080fd5b6102c65a03f11515610ad957600080fd5b5050506040518051905050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68836000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610b7d57600080fd5b6102c65a03f11515610b8e57600080fd5b505050604051805190501515610ba357600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506000811115610c4457610c433382611a9c565b5b5050565b60055481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cb157600080fd5b600854421015610cd357660221b262dd8000600654141515610cd257600080fd5b5b651b48eb57e000600654108015610cf057506213c6806008540142105b151515610cfc57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501515610d7557600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610e3a57600080fd5b6102c65a03f11515610e4b57600080fd5b5050506040518051905090506000811115610f2057600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610ef957600080fd5b6102c65a03f11515610f0a57600080fd5b505050604051805190501515610f1f57600080fd5b5b6001600960006101000a81548160ff02191690831515021790555050565b600080339150600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114151515610f9657600080fd5b803073ffffffffffffffffffffffffffffffffffffffff163110151515610fbc57600080fd5b610fd181600254611b5090919063ffffffff16565b6002819055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561105957fe5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110b857600080fd5b6001600060146101000a81548160ff021916908315150217905550565b670de0b6b3a764000081565b600060149054906101000a900460ff1681565b60075481565b651b48eb57e00081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561115f57600080fd5b600060149054906101000a900460ff16151561117a57600080fd5b60008060146101000a81548160ff021916908315150217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561121c57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561129457600080fd5b565b61025881565b600a6020528060005260406000206000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561131b57600080fd5b600060075414151561132c57600080fd5b4260078190555062278d004201600881905550565b600960009054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b660221b262dd800081565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113e557600080fd5b600654660221b262dd800003925061142b670de0b6b3a764000061141c610258670de0b6b3a76400006119d990919063ffffffff16565b81151561142557fe5b04611a27565b915081831115151561143c57600080fd5b600a60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561158c57600080fd5b6102c65a03f1151561159d57600080fd5b50505060405180519050506115bf838260010154611a7e90919063ffffffff16565b81600101819055506115dc83600654611a7e90919063ffffffff16565b6006819055503073ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c846040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e856000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60016020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561173657600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f2fde38b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b151561181357600080fd5b6102c65a03f1151561182457600080fd5b505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415156118fb57806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561195957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561199557600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080828402905060008414806119fa57508284828115156119f757fe5b04145b1515611a0257fe5b8091505092915050565b6000808284811515611a1a57fe5b0490508091505092915050565b6000611a416202a300600754611a7e90919063ffffffff16565b421015611a7557611a6e611a5f600584611a0c90919063ffffffff16565b83611a7e90919063ffffffff16565b9050611a79565b8190505b919050565b6000808284019050838110151515611a9257fe5b8091505092915050565b611aee81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611a7e90919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b4681600254611a7e90919063ffffffff16565b6002819055505050565b6000828211151515611b5e57fe5b8183039050929150505600a165627a7a72305820ec0d82a406896ccf20989b3d6e650abe4dc104e400837f1f58e67ef499493ae90029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008d69d00910d0b2afb2a99ed6c16c8129fa8e1751",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000e819f024b41358d2c08e3a868a5c5dd0566078d4",
- "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000000000000000000000000000000000000005a388981",
- "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000005a3b38e6"
- }
- },
- "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826": {
- "balance": "0x2a2dd979a35cf000",
- "code": "0x",
- "nonce": "0",
- "storage": {}
- },
- "0xe819f024b41358d2c08e3a868a5c5dd0566078d4": {
- "balance": "0x0",
- "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c681461027257806370a08231146102ad5780638da5cb5b146102fa57806395d89b411461034f578063a9059cbb146103dd578063dd62ed3e14610437578063f2fde38b146104a3575b600080fd5b34156100ca57600080fd5b6100d26104dc565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610515565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba61069c565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106a2565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610952565b6040518082815260200191505060405180910390f35b341561027d57600080fd5b6102936004808035906020019091905050610957565b604051808215151515815260200191505060405180910390f35b34156102b857600080fd5b6102e4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610abe565b6040518082815260200191505060405180910390f35b341561030557600080fd5b61030d610b07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561035a57600080fd5b610362610b2d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103e857600080fd5b61041d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b66565b604051808215151515815260200191505060405180910390f35b341561044257600080fd5b61048d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d01565b6040518082815260200191505060405180910390f35b34156104ae57600080fd5b6104da600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d88565b005b6040805190810160405280600b81526020017f416c6c436f6465436f696e00000000000000000000000000000000000000000081525081565b6000808214806105a157506000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15156105ac57600080fd5b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905061077683600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061080b83600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108618382610e7d90919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b600681565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109b557600080fd5b610a0782600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610a5f82600054610e7d90919063ffffffff16565b60008190555060003373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600481526020017f414c4c430000000000000000000000000000000000000000000000000000000081525081565b6000610bba82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c4f82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610de457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515610e5c5780600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000808284019050838110151515610e7357fe5b8091505092915050565b6000828211151515610e8b57fe5b8183039050929150505600a165627a7a7230582059f3ea3df0b054e9ab711f37969684ba83fe38f255ffe2c8d850d951121c51100029",
- "nonce": "1",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3956606365",
- "extraData": "0x566961425443",
- "gasLimit": "5418523",
- "hash": "0x6f37eb930a25da673ea1bb80fd9e32ddac19cdf7cd4bb2eac62cc13598624077",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "mixHash": "0x10971cde68c587c750c23b8589ae868ce82c2c646636b97e7d9856470c5297c7",
- "nonce": "0x810f923ff4b450a1",
- "number": "2295103",
- "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e",
- "timestamp": "1513681246",
- "totalDifficulty": "7162347056825919"
- },
- "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea",
- "result": {
- "calls": [
- {
- "error": "invalid opcode: INVALID",
- "from": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76",
- "gas": "0x75fe3",
- "gasUsed": "0x75fe3",
- "input": "0xa9059cbb000000000000000000000000d4fcab9f0a6dc0493af47c864f6f17a8a5e2e82600000000000000000000000000000000000000000000000000000000000002f4",
- "to": "0xe819f024b41358d2c08e3a868a5c5dd0566078d4",
- "type": "CALL",
- "value": "0x0"
- }
- ],
- "error": "execution reverted",
- "from": "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826",
- "gas": "0x7dfa6",
- "gasUsed": "0x7c1c8",
- "input": "0x",
- "to": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76",
- "type": "CALL",
- "value": "0xe92596fd6290000"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json
deleted file mode 100644
index 333bdd038c..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
- "context": {
- "difficulty": "3699098917",
- "gasLimit": "5258985",
- "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511",
- "number": "2294631",
- "timestamp": "1513675366"
- },
- "genesis": {
- "alloc": {
- "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62": {
- "balance": "0x0",
- "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c68146102785780635a3b7e42146102b357806370a082311461034157806379cc67901461038e57806395d89b41146103e8578063a9059cbb14610476578063dd62ed3e146104b8575b600080fd5b34156100ca57600080fd5b6100d2610524565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061055d565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba6105ea565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105f0565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610910565b604051808260ff1660ff16815260200191505060405180910390f35b341561028357600080fd5b6102996004808035906020019091905050610915565b604051808215151515815260200191505060405180910390f35b34156102be57600080fd5b6102c6610a18565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103065780820151818401526020810190506102eb565b50505050905090810190601f1680156103335780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a51565b6040518082815260200191505060405180910390f35b341561039957600080fd5b6103ce600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a69565b604051808215151515815260200191505060405180910390f35b34156103f357600080fd5b6103fb610bf8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561043b578082015181840152602081019050610420565b50505050905090810190601f1680156104685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561048157600080fd5b6104b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610c31565b005b34156104c357600080fd5b61050e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e34565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f446f70616d696e6500000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60005481565b6000808373ffffffffffffffffffffffffffffffffffffffff161415151561061757600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561066557600080fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101515156106f157fe5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561077c57600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561096557600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b6040805190810160405280600981526020017f446f706d6e20302e32000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b600081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ab957600080fd5b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610b4457600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b6040805190810160405280600581526020017f444f504d4e00000000000000000000000000000000000000000000000000000081525081565b60008273ffffffffffffffffffffffffffffffffffffffff1614151515610c5757600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ca557600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110151515610d3157fe5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60026020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058206d93424f4e7b11929b8276a269038402c10c0ddf21800e999916ddd9dff4a7630029",
- "nonce": "1",
- "storage": {
- "0x296b66049cc4f9c8bf3d4f14752add261d1a980b39bdd194a7897baf39ac7579": "0x0000000000000000000000000000000000000000033b2e3c9fc9653f9e72b1e0"
- }
- },
- "0x94194bc2aaf494501d7880b61274a169f6502a54": {
- "balance": "0xea8c39a876d19888d",
- "code": "0x",
- "nonce": "265",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3699098917",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "5263953",
- "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408",
- "nonce": "0xd1bdb150f6fd170e",
- "number": "2294630",
- "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1",
- "timestamp": "1513675347",
- "totalDifficulty": "7160543502214733"
- },
- "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956",
- "result": {
- "error": "out of gas",
- "from": "0x94194bc2aaf494501d7880b61274a169f6502a54",
- "gas": "0xca1d",
- "gasUsed": "0xca1d",
- "input": "0xa9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f9000",
- "to": "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json
deleted file mode 100644
index 3207a298a9..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "context": {
- "difficulty": "3665057456",
- "gasLimit": "5232723",
- "miner": "0xf4d8e706cfb25c0decbbdd4d2e2cc10c66376a3f",
- "number": "2294501",
- "timestamp": "1513673601"
- },
- "genesis": {
- "alloc": {
- "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9": {
- "balance": "0x2a3fc32bcc019283",
- "code": "0x",
- "nonce": "10",
- "storage": {}
- },
- "0xabbcd5b340c80b5f1c0545c04c987b87310296ae": {
- "balance": "0x0",
- "code": "0x606060405236156100755763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632d0335ab811461007a578063548db174146100ab5780637f649783146100fc578063b092145e1461014d578063c3f44c0a14610186578063c47cf5de14610203575b600080fd5b341561008557600080fd5b610099600160a060020a0360043516610270565b60405190815260200160405180910390f35b34156100b657600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061028f95505050505050565b005b341561010757600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061029e95505050505050565b005b341561015857600080fd5b610172600160a060020a03600435811690602435166102ad565b604051901515815260200160405180910390f35b341561019157600080fd5b6100fa6004803560ff1690602480359160443591606435600160a060020a0316919060a49060843590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965050509235600160a060020a031692506102cd915050565b005b341561020e57600080fd5b61025460046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061056a95505050505050565b604051600160a060020a03909116815260200160405180910390f35b600160a060020a0381166000908152602081905260409020545b919050565b61029a816000610594565b5b50565b61029a816001610594565b5b50565b600160209081526000928352604080842090915290825290205460ff1681565b60008080600160a060020a038416158061030d5750600160a060020a038085166000908152600160209081526040808320339094168352929052205460ff165b151561031857600080fd5b6103218561056a565b600160a060020a038116600090815260208190526040808220549295507f19000000000000000000000000000000000000000000000000000000000000009230918891908b908b90517fff000000000000000000000000000000000000000000000000000000000000008089168252871660018201526c01000000000000000000000000600160a060020a038088168202600284015286811682026016840152602a8301869052841602604a820152605e810182805190602001908083835b6020831061040057805182525b601f1990920191602091820191016103e0565b6001836020036101000a0380198251168184511617909252505050919091019850604097505050505050505051809103902091506001828a8a8a6040516000815260200160405260006040516020015260405193845260ff90921660208085019190915260408085019290925260608401929092526080909201915160208103908084039060008661646e5a03f1151561049957600080fd5b5050602060405103519050600160a060020a03838116908216146104bc57600080fd5b600160a060020a0380841660009081526020819052604090819020805460010190559087169086905180828051906020019080838360005b8381101561050d5780820151818401525b6020016104f4565b50505050905090810190601f16801561053a5780820380516001836020036101000a031916815260200191505b5091505060006040518083038160008661646e5a03f1915050151561055e57600080fd5b5b505050505050505050565b600060248251101561057e5750600061028a565b600160a060020a0360248301511690505b919050565b60005b825181101561060157600160a060020a033316600090815260016020526040812083918584815181106105c657fe5b90602001906020020151600160a060020a031681526020810191909152604001600020805460ff19169115159190911790555b600101610597565b5b5050505600a165627a7a723058200027e8b695e9d2dea9f3629519022a69f3a1d23055ce86406e686ea54f31ee9c0029",
- "nonce": "1",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3672229776",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "5227619",
- "hash": "0xa07b3d6c6bf63f5f981016db9f2d1d93033833f2c17e8bf7209e85f1faf08076",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0x806e151ce2817be922e93e8d5921fa0f0d0fd213d6b2b9a3fa17458e74a163d0",
- "nonce": "0xbc5d43adc2c30c7d",
- "number": "2294500",
- "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d",
- "timestamp": "1513673552",
- "totalDifficulty": "7160066586979149"
- },
- "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a",
- "result": {
- "error": "execution reverted",
- "from": "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9",
- "gas": "0x2dc6c0",
- "gasUsed": "0x719b",
- "input": "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "to": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json
deleted file mode 100644
index 5c7e5629e9..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json
+++ /dev/null
@@ -1,64 +0,0 @@
-{
- "context": {
- "difficulty": "2",
- "gasLimit": "8000000",
- "miner": "0x0000000000000000000000000000000000000000",
- "number": "3212651",
- "timestamp": "1597246515"
- },
- "genesis": {
- "alloc": {
- "0xf58833cf0c791881b494eb79d461e08a1f043f52": {
- "balance": "0x0",
- "code": "0x608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063609ff1bd11610078578063609ff1bd146101af5780639e7b8d61146101cd578063a3ec138d14610211578063e2ba53f0146102ae576100a5565b80630121b93f146100aa578063013cf08b146100d85780632e4176cf146101215780635c19a95c1461016b575b600080fd5b6100d6600480360360208110156100c057600080fd5b81019080803590602001909291905050506102cc565b005b610104600480360360208110156100ee57600080fd5b8101908080359060200190929190505050610469565b604051808381526020018281526020019250505060405180910390f35b61012961049a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ad6004803603602081101561018157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104bf565b005b6101b76108db565b6040518082815260200191505060405180910390f35b61020f600480360360208110156101e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610952565b005b6102536004803603602081101561022757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b53565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b6102b6610bb0565b6040518082815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561038a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f486173206e6f20726967687420746f20766f746500000000000000000000000081525060200191505060405180910390fd5b8060010160009054906101000a900460ff161561040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f416c726561647920766f7465642e00000000000000000000000000000000000081525060200191505060405180910390fd5b60018160010160006101000a81548160ff02191690831515021790555081816002018190555080600001546002838154811061044757fe5b9060005260206000209060020201600101600082825401925050819055505050565b6002818154811061047657fe5b90600052602060002090600202016000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff1615610587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f596f7520616c726561647920766f7465642e000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e000081525060200191505060405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107cc57600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f466f756e64206c6f6f7020696e2064656c65676174696f6e2e0000000000000081525060200191505060405180910390fd5b61062a565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156108bf578160000154600282600201548154811061089c57fe5b9060005260206000209060020201600101600082825401925050819055506108d6565b816000015481600001600082825401925050819055505b505050565b6000806000905060008090505b60028054905081101561094d57816002828154811061090357fe5b9060005260206000209060020201600101541115610940576002818154811061092857fe5b90600052602060002090600202016001015491508092505b80806001019150506108e8565b505090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180610bde6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f54686520766f74657220616c726561647920766f7465642e000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414610b0957600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610bbc6108db565b81548110610bc657fe5b90600052602060002090600202016000015490509056fe4f6e6c79206368616972706572736f6e2063616e206769766520726967687420746f20766f74652ea26469706673582212201d282819f8f06fed792100d60a8b08809b081a34a1ecd225e83a4b41122165ed64736f6c63430006060033",
- "nonce": "1",
- "storage": {
- "0x6200beec95762de01ce05f2a0e58ce3299dbb53c68c9f3254a242121223cdf58": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1": {
- "balance": "0x57af9d6b3df812900",
- "code": "0x",
- "nonce": "6",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 0,
- "constantinopleBlock": 0,
- "petersburgBlock": 0,
- "IstanbulBlock":1561651,
- "chainId": 5,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294",
- "result": {
- "error": "execution reverted",
- "from": "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1",
- "gas": "0x2dc6c0",
- "gasUsed": "0x5940",
- "input": "0x5c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf1",
- "to": "0xf58833cf0c791881b494eb79d461e08a1f043f52",
- "type": "CALL",
- "value": "0x0",
- "output": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json
deleted file mode 100644
index 11b23a990e..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json
+++ /dev/null
@@ -1,73 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x61deadff",
- "nonce": "1",
- "storage": {}
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "result": {
- "calls": [
- {
- "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "input": "0x",
- "to": "0x000000000000000000000000000000000000dEaD",
- "type": "SELFDESTRUCT",
- "value": "0x4d87094125a369d9bd5"
- }
- ],
- "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "gas": "0x15f90",
- "gasUsed": "0x6fcb",
- "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "output": "0x",
- "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json
deleted file mode 100644
index 37723f17dd..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json
+++ /dev/null
@@ -1,78 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "result": {
- "calls": [
- {
- "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "input": "0x",
- "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "type": "CALL",
- "value": "0x6f05b59d3b20000"
- }
- ],
- "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "gas": "0x15f90",
- "gasUsed": "0x9751",
- "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json
deleted file mode 100644
index 499b449a6e..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json
+++ /dev/null
@@ -1,62 +0,0 @@
-{
- "context": {
- "difficulty": "117009631",
- "gasLimit": "4712388",
- "miner": "0x294e5d6c39a36ce38af1dca70c1060f78dee8070",
- "number": "25009",
- "timestamp": "1479891666"
- },
- "genesis": {
- "alloc": {
- "0x70c9217d814985faef62b124420f8dfbddd96433": {
- "balance": "0x4ecd70668f5d854a",
- "code": "0x",
- "nonce": "1638",
- "storage": {}
- },
- "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": {
- "balance": "0x0",
- "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000061a9",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433"
- }
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "117066792",
- "extraData": "0xd783010502846765746887676f312e372e33856c696e7578",
- "gasLimit": "4712388",
- "hash": "0xe23e8d4562a1045b70cbc99fefb20c101a8f0fc8559a80d65fea8896e2f1d46e",
- "miner": "0x71842f946b98800fe6feb49f0ae4e253259031c9",
- "mixHash": "0x0aada9d6e93dd4db0d09c0488dc0a048fca2ccdc1f3fc7b83ba2a8d393a3a4ff",
- "nonce": "0x70849d5838dee2e9",
- "number": "25008",
- "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b",
- "timestamp": "1479891641",
- "totalDifficulty": "1896347038589"
- },
- "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750",
- "result": {
- "error": "invalid jump destination",
- "from": "0x70c9217d814985faef62b124420f8dfbddd96433",
- "gas": "0x3d090",
- "gasUsed": "0x3d090",
- "input": "0x51a34eb8000000000000000000000000000000000000000000000027fad02094277c0000",
- "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b",
- "type": "CALL",
- "value": "0x0"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json
deleted file mode 100644
index dbece7229d..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json
+++ /dev/null
@@ -1,117 +0,0 @@
-{
- "genesis": {
- "difficulty": "11934798510088",
- "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773",
- "gasLimit": "3141592",
- "hash": "0xfc543a4a551afbd4a6c5d6d49041371e6bb58b1108c12aaec7f487ce656bb97f",
- "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
- "mixHash": "0xa6a1e67fc68da76b8d9cc3ce1c45d5e1f4bbd96b5dcfddbe0017d7fa99903ead",
- "nonce": "0x5f00c600268b4659",
- "number": "995200",
- "stateRoot": "0x3579328470dd2aef5b9da69f5480cbe0d375e653b530ab3c1aee0da5e1ff4c94",
- "timestamp": "1455322761",
- "totalDifficulty": "7077231809278509672",
- "alloc": {
- "0x200edd17f30485a8735878661960cd7a9a95733f": {
- "balance": "0x0",
- "code": "0x3660008037602060003660003473273930d21e01ee25e4c219b63259d214872220a261235a5a03f21560015760206000f3",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "0x0000000000000000000000000000000000000000000000000000000000000104": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf04": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf05": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf06": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xa611e7c895a426c0477bc9e280db9c3b1e456dc6310ffcf23926ef5186c1facc": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c410e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c410f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c4110": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x273930d21e01ee25e4c219b63259d214872220a2": {
- "balance": "0x0",
- "code": "0x606060405236156100da5760e060020a6000350463173825d9811461012c5780632f54bf6e146101875780634123cb6b146101af57806352375093146101b857806354fd4d50146101c25780635c52c2f5146101cc578063659010e7146101fd5780637065cb4814610207578063746c91711461023b578063797af62714610244578063b20d30a914610257578063b61d27f61461028b578063b75c7dc6146102ac578063ba51a6df146102db578063c2cf73261461030f578063cbf0b0c01461034d578063f00d4b5d14610381578063f1736d86146103ba575b6103c4600034111561012a5760408051600160a060020a033216815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b6103c46004356000600036436040518084848082843750505090910190815260405190819003602001902090506106c9815b600160a060020a03321660009081526101026020526040812054818082811415610c3f57610d97565b6103c66004355b600160a060020a03811660009081526101026020526040812054115b919050565b6103c660015481565b6103c66101075481565b6103c66101085481565b6103c46000364360405180848480828437505050909101908152604051908190036020019020905061081a8161015e565b6103c66101065481565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506106418161015e565b6103c660005481565b6103c66004355b600081610a7d8161015e565b6103c46004356000364360405180848480828437505050909101908152604051908190036020019020905061080e8161015e565b6103c66004803590602480359160443591820191013560006108393261018e565b6103c4600435600160a060020a033216600090815261010260205260408120549080828114156103d857610457565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506107888161015e565b6103c6600435602435600082815261010360209081526040808320600160a060020a038516845261010290925282205482818114156107e157610805565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506108288161015e565b6103c46004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104e28161015e565b6103c66101055481565b005b60408051918252519081900360200190f35b50506000828152610103602052604081206001810154600284900a9290831611156104575780546001828101805492909101835590839003905560408051600160a060020a03321681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b50505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a1505b505050565b15610457576104f08361018e565b156104fb57506104dd565b600160a060020a03841660009081526101026020526040812054925082141561052457506104dd565b61045d5b6101045460005b81811015610ee457610104805461010991600091849081101561000257600080516020610f9f83398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f6992601f9290920104810190610a65565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561063c5761064f8261018e565b1561065a575061063e565b610662610528565b60015460fa90106106775761067561068c565b505b60015460fa90106105a2575061063e565b6107465b600060015b600154811015610a79575b600154811080156106bc5750600281610100811015610002570154600014155b15610d9f5760010161069c565b156104dd57600160a060020a0383166000908152610102602052604081205492508214156106f7575061063c565b6001600160005054036000600050541115610712575061063c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610688610528565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561063c5760015482111561079d575061063e565b60008290556107aa610528565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001820154600282900a908116600014156108005760009350610805565b600193505b50505092915050565b1561063c575061010555565b1561063e5760006101065550565b1561063c5781600160a060020a0316ff5b15610a555761084d846000610e793261018e565b15610909577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00432858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a5592505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061093990508161024b565b15801561095c575060008181526101096020526040812054600160a060020a0316145b15610a555760008181526101096020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a5d579182015b82811115610a5d5782358260005055916020019190600101906109b1565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328132868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b506109cf9291505b80821115610a795760008155600101610a65565b5090565b15610c2c5760008381526101096020526040812054600160a060020a031614610c2c5760408051600091909120805460018201546002929092018054600160a060020a0392909216939091819083908015610afd57820191906000526020600020905b815481529060010190602001808311610ae057829003601f168201915b505091505060006040518083038185876185025a03f150505060008481526101096020908152604080519281902080546001820154600160a060020a033281811688529587018b905293860181905292166060850181905260a06080860181815260029390930180549187018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a975094958a959293909160c083019084908015610bcf57820191906000526020600020905b815481529060010190602001808311610bb257829003601f168201915b5050965050505050505060405180910390a160008381526101096020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c3292601f9290920104810190610a65565b50919050565b50505060019150506101aa565b60008581526101036020526040812080549093501415610cc7576000805483556001838101919091556101048054918201808255828015829011610c9657818360005260206000209182019101610c969190610a65565b50505060028301819055610104805487929081101561000257600091909152600080516020610f9f83398151915201555b506001810154600283900a90811660001415610d975760408051600160a060020a03321681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1815460019011610d84576000858152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f9f8339815191529290920181905580825560018083018290556002909201559450610d979050565b8154600019018255600182018054821790555b505050919050565b5b60018054118015610dc257506001546002906101008110156100025701546000145b15610dd65760018054600019019055610da0565b60015481108015610df95750600154600290610100811015610002570154600014155b8015610e1357506002816101008110156100025701546000145b15610e7457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b610691565b156101aa5761010754610e8f5b62015180420490565b1115610ea857600061010655610ea3610e86565b610107555b6101065480830110801590610ec65750610106546101055490830111155b15610edc575061010680548201905560016101aa565b5060006101aa565b61063c6101045460005b81811015610f745761010480548290811015610002576000918252600080516020610f9f833981519152015414610f6157610104805461010391600091849081101561000257600080516020610f9f83398151915201548252506020919091526040812081815560018101829055600201555b600101610eee565b50505060010161052f565b61010480546000808355919091526104dd90600080516020610f9f83398151915290810190610a6556004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe"
- },
- "0x4f5777744b500616697cb655dcb02ee6cd51deb5": {
- "balance": "0xb0983f1b83eec290",
- "nonce": "2"
- },
- "0xf8b483dba2c3b7176a3da549ad41a48bb3121069": {
- "balance": "0x16969a0ba2c2d384d07",
- "nonce": "67521"
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "995201",
- "difficulty": "11940626048551",
- "timestamp": "1455322773",
- "gasLimit": "3141592",
- "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069"
- },
- "input": "0xf89102850a954d522e8303308594200edd17f30485a8735878661960cd7a9a95733f888ac7230489e80000a4ba51a6df00000000000000000000000000000000000000000000000000000000000000001ca04f2cc45b96f965296382b2e9b657e90808301d5179035a5d91a2de7b912def20a056e19271ea4e19e4e034f38e925e312beed4d300c267160eeb2f565c42deb578",
- "tracerConfig": {
- "withLog": true
- },
- "result": {
- "from": "0x4f5777744b500616697cb655dcb02ee6cd51deb5",
- "gas": "0x33085",
- "gasUsed": "0x1a9e5",
- "to": "0x200edd17f30485a8735878661960cd7a9a95733f",
- "input": "0xba51a6df0000000000000000000000000000000000000000000000000000000000000000",
- "output": "0xba51a6df00000000000000000000000000000000000000000000000000000000",
- "calls": [
- {
- "from": "0x200edd17f30485a8735878661960cd7a9a95733f",
- "gas": "0x2c263",
- "gasUsed": "0x1b0e4",
- "to": "0x273930d21e01ee25e4c219b63259d214872220a2",
- "input": "0xba51a6df0000000000000000000000000000000000000000000000000000000000000000",
- "logs": [
- {
- "address": "0x200edd17f30485a8735878661960cd7a9a95733f",
- "topics": [
- "0xe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda"
- ],
- "data": "0x0000000000000000000000004f5777744b500616697cb655dcb02ee6cd51deb5be96016bb57376da7a6d296e0a405ee1501778227dfa604df0a81cb1ae018598",
- "position": "0x0"
- },
- {
- "address": "0x200edd17f30485a8735878661960cd7a9a95733f",
- "topics": [
- "0xacbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x0"
- }
- ],
- "value": "0x8ac7230489e80000",
- "type": "CALLCODE"
- }
- ],
- "value": "0x8ac7230489e80000",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json
deleted file mode 100644
index 2b03dbb8dd..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json
+++ /dev/null
@@ -1,413 +0,0 @@
-{
- "genesis": {
- "difficulty": "80344740444880",
- "extraData": "0x7777772e62772e636f6d",
- "gasLimit": "1498600",
- "hash": "0xf5d85a80bdbc5d28a16b8eb0d1b9dd18316ddc3655c7d5c901b67acdb7700037",
- "miner": "0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1",
- "mixHash": "0x433ae590edf0e7ba9aac698bb7d3be2300e3e79d175db13528ff3e79a3f93910",
- "nonce": "0x084adce0020c6fd8",
- "number": "2340152",
- "stateRoot": "0x38295a2634c9c62d48bcbf2ef2ae83768b9055c1f5e6469d17a5d1bcb052072e",
- "timestamp": "1475034708",
- "totalDifficulty": "66488249547380413902",
- "alloc": {
- "0x01e60b511fced1eb2b5b40991eb1dfd171a6df42": {
- "balance": "0x0",
- "code": "0x6060604052361561008d5760e060020a600035046306fdde03811461008f578063095ea7b3146100a557806318160ddd1461012457806323b872dd1461012f578063313ce567146101dc578063475a9fa9146101f057806370a0823114610215578063721a37d21461024357806395d89b411461008f578063a9059cbb14610268578063dd62ed3e146102e7575b005b61031d6040805160208101909152600081525b90565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db63c6605267600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b6102316003546100a2565b61038b60043560243560443560008054604080517fa00bfa1100000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038781166024830152868116604483015260648201869052929092166084830152517319ee743d2e356d5f0e4d97cc09b96d06e933d0db9163a00bfa119160a482810192602092919082900301818660325a03f4156100025750506040515195945050505050565b604080516000815290519081900360200190f35b61038b6004356024356000805433600160a060020a0390811691161461039f57610002565b600160a060020a03600435166000908152600160205260409020545b60408051918252519081900360200190f35b61038b6004356024356000805433600160a060020a039081169116146103ce57610002565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db6388d5fecb600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b610231600435602435600160a060020a038281166000908152600260209081526040808320938516835292905220545b92915050565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561037d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b604080519115158252519081900360200190f35b50600160a060020a03821660009081526001602081905260409091208054830190556003805483019055610317565b600160a060020a038316600090815260016020526040902054821161040a57506040600020805482900390556003805482900390556001610317565b50600061031756",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000012098a4651fb262f7",
- "0xfae22198212900725daa5db635d1fda7b0fa195adaabdc806a7267959c3d8ae4": "0x00000000000000000000000000000000000000000000000026cbcbc35aaa62f7"
- }
- },
- "0x19ee743d2e356d5f0e4d97cc09b96d06e933d0db": {
- "balance": "0x0",
- "code": "0x6503060000000050606060405260e060020a600035046388d5fecb811461003c578063a00bfa11146100e3578063c6605267146102dc575b610007565b610356600435602435604435600160a060020a0333166000908152602084905260408120548290108015906100715750600082115b1561036a57600160a060020a0333811660008181526020878152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161034f565b610356600435602435604435606435608435600160a060020a03841660009081526020869052604081205483901080159061011e5750600083115b80156101bb5750600160a060020a0385811660009081526001880160209081526040808320339094168352929052205483901015806101bb575081600160a060020a0316631934d55a86336040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506020604051808303816000876161da5a03f1156100075750506040515190505b1561037257600160a060020a038481166000908152602088815260408083208054880190558884168084528184208054899003905581517f1934d55a00000000000000000000000000000000000000000000000000000000815260048101919091523385166024820152905193861693631934d55a936044838101949383900301908290876161da5a03f115610007575050604051511515905061028957600160a060020a038581166000908152600188016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3506001610376565b610356600435602435604435600160a060020a033381166000818152600186016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b9392505050565b604080519115158252519081900360200190f35b50600061034f565b5060005b9594505050505056"
- },
- "0x3de712784baf97260455ae25fb74f574ec9c1add": {
- "balance": "0x23c8352f33854625",
- "nonce": "80"
- },
- "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd": {
- "balance": "0x0",
- "nonce": "29",
- "code": "0x606060405236156100cf5760e060020a600035046307d5b82681146100d157806315e812ad146101775780631934d55a1461018d5780631d007f5f146101c65780631f0c1e0c146101ee5780633983d5c41461022b5780634025b29314610243578063428d64bd1461030f578063481b659d146104b557806357bcccb6146104f45780638c172fa21461052f5780639ba5b4e9146105ea578063a4a7cf5c146106ca578063b11e3b82146106ed578063c51cf179146107a6578063d6911046146107c2578063eff6be2f146109cb575b005b6109f2600435602435600082815260016020908152604080832060049081015482517f23b872dd00000000000000000000000000000000000000000000000000000000815233600160a060020a0390811693820193909352308316602482015260448101879052925185948594859493909316926323b872dd9260648281019392829003018187876161da5a03f1156100025750506040515115159050610a6d57610002565b6004545b60408051918252519081900360200190f35b6109f2600435602435600160a060020a0382811660009081526003602090815260408083209385168352929052205460ff165b92915050565b6109f2600435600080546101009004600160a060020a039081163390911614610be757610002565b610a066004356024356000828152600160205260408120600901805483908110156100025750815260209020810154600160a060020a03166101c0565b61017b6004355b600454620f4240908202045b919050565b6109f26004356024356000805b600084815260016020526040902060090154811015610c13576040600090812090859052600160205260090180548290811015610002576000918252604080516020808520909301547f721a37d2000000000000000000000000000000000000000000000000000000008252600160a060020a03338116600484015260248301899052925192169363721a37d293604483810194919391929183900301908290876161da5a03f1156100025750506040515115159050610c8d57610002565b604080516024803560048181013560208181028087018201909752818652610a2396833596939560449501929182919085019084908082843750949650505050505050604080516020818101835260008083528351918201909352828152909190819081905b8551831015610c9f57600091505b600160005060008785815181101561000257602090810290910181015182528101919091526040016000206009015460ff831610156104a957600060016000506000888681518110156100025760209081029091018101518252810191909152604001600020600901805460ff85169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231896040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191909111159050610f59576001600050600087858151811015610002576020908102909101810151825281019190915260400160002060090154909301600201925b60019290920191610375565b6109f260043533600160a060020a039081166000908152600360209081526040808320938516835292905220805460ff1916600190811790915561023e565b6109f260043533600160a060020a039081166000908152600360209081526040808320938516835292905220805460ff19169055600161023e565b60048035600090815260016020818152604092839020600981015481548551968301546002840154600385015460088601546005870154600688015499880154600790980154958c52600160a060020a03888116998d019990995260a060020a90970460ff90811615158c8c015260608c019390935260808b019190915260a08a019490945290851660c08901529290931660e087015261010086019390935216151561012084015261014083015251908190036101600190f35b60408051600480358082013560208181028086018201909652818552610a23959394602494909385019291829190850190849080828437509496505050505050506040805160208181018352600080835283519182019093528281529091908190815b8551831015610f93576000600260005060008886815181101561000257602090810290910181015182528101919091526040016000205411156106be576002600050600087858151811015610002576020908102909101810151825281019190915260400160002054909301600201925b6001929092019161064d565b61017b6004356000805481908190819081908190819060ff161561115757610002565b6040805160e4356004818101356020818102808601820190965281855261017b95833595602480359660443596606435966084359660a4359660c4359693956101049501929182919085019084908082843750949650505050505050600080808080808d81148061076657508c801561076657508a8c12155b80610774575060028a60ff16105b80610788575087600160a060020a03166000145b8061079c575088600160a060020a03166000145b1561177157611760565b61017b600435600454620f42409081039082020481900361023e565b60408051600480358082013560208181028086018201909652818552610a23959394602494909385019291829190850190849080828437509496505093359350506044359150506064356040805160208181018352600080835283519182019093528281529091908190815b8851831015611cee576000600102600160005060008b8681518110156100025760209081029091018101518252810191909152604001600020541180156108c7575087600160a060020a0316600014806108c7575087600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060050154600160a060020a0316145b8015610925575086600160a060020a031660001480610925575086600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060040154600160a060020a0316145b8015610983575085600160a060020a031660001480610983575085600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060010154600160a060020a0316145b156109bf57600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060090154909301600c01925b6001929092019161082e565b6109f26004356000805433600160a060020a03908116610100909204161461234c57610002565b604080519115158252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600302600f01f1509050019250505060405180910390f35b610a7685610232565b92508285039150600083118015610b00575060008681526001602090815260408083206004908101548251855460e060020a63a9059cbb0282526101009004600160a060020a039081169382019390935260248101899052925191169363a9059cbb936044848101949193929183900301908290876161da5a03f115610002575050604051511590505b15610b0a57610002565b5060005b60008681526001602052604090206009015460ff82161015610bd35760406000908120908790526001602052600901805460ff831690811015610002576000918252604080516020808520909301547f475a9fa9000000000000000000000000000000000000000000000000000000008252600160a060020a03338116600484015260248301889052925192169363475a9fa993604483810194919391929183900301908290876161da5a03f1156100025750506040515115159050610bdf57610002565b50600195945050505050565b600101610b0e565b506000805474ffffffffffffffffffffffffffffffffffffffff0019166101008302179055600161023e565b6000848152600160209081526040808320600490810154825160e060020a63a9059cbb028152600160a060020a033381169382019390935260248101899052925191169363a9059cbb936044848101949193929183900301908290876161da5a03f1156100025750506040515115159050610c9557610002565b600101610250565b5060019392505050565b83604051805910610cad5750595b908082528060200260200182016040528015610cc4575b506000945084935090505b8551831015610f6557600091505b600160005060008785815181101561000257602090810290910181015182528101919091526040016000206009015460ff83161015610f7b57600060016000506000888681518110156100025760209081029091018101518252810191909152604001600020600901805460ff85169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231896040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191909111159050610f8757858381518110156100025790602001906020020151600190048185815181101561000257602090810290910101528551600190600090889086908110156100025760209081029091018101518252810191909152604001600020600901548151829060018701908110156100025760209081029091010152600091505b600160005060008785815181101561000257602090810290910181015182528101919091526040016000206009015460ff83161015610f6f5760016000506000878581518110156100025760209081029091018101518252810191909152604001600020600901805460ff84169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231886040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051518251909150829060ff8516870160020190811015610002576020908102909101015260019190910190610e49565b60019190910190610383565b9695505050505050565b6002820160ff16909301925b60019290920191610ccf565b60019190910190610cdd565b83604051805910610fa15750595b908082528060200260200182016040528015610fb8575b506000945084935091505b85518310156111125760006002600050600088868151811015610002576020908102909101810151825281019190915260400160002054111561114b578583815181101561000257906020019060200201516001900482858151811015610002576020908102909101015285516002906000908890869081101561000257602090810290910181015182528101919091526040016000205482518390600187019081101561000257602090810290910101525060005b600260005060008785815181101561000257602090810290910181015182528101919091526040016000205481101561111b5760026000506000878581518110156100025760209081029091018101518252810191909152604001600020805482908110156100025760009182526020909120015482518390868401600201908110156100025760209081029091010152600101611079565b50949350505050565b60026000506000878581518110156100025750506020858102890181015182528290526040902054909401909301925b60019290920191610fc3565b6000805460ff191660019081178255898252602052604090206007015460ff1615156112e85760406000818120600581015483516006909201547f5101770200000000000000000000000000000000000000000000000000000000835260048301529251600160a060020a0393909316926351017702926024838101936020939290839003909101908290876161da5a03f115610002575050604051511515905061120457611338611347565b6000888152600160209081526040808320815160058201546006909201547f5d1a3b8200000000000000000000000000000000000000000000000000000000825260048201529151600160a060020a039190911693635d1a3b82936024808501949193929183900301908290876161da5a03f1156100025750505060405180519060200150600160005060008a600019168152602001908152602001600020600050600801600050819055506001600160005060008a60001916815260200190815260200160002060005060070160006101000a81548160ff021916908302179055505b6000888152600160208190526040909120015460a060020a900460ff16156113535760406000908120908990526001602052600281015460089091015412156115435760009450611598565b8596505b505050505050919050565b6113345b6000805460ff19169055565b6000888152600160205260409020600981018054600890920154909181101561000257600091825260208083206040805193909101547f70a08231000000000000000000000000000000000000000000000000000000008452600160a060020a03338116600486015291519116936370a082319360248181019493929183900301908290876161da5a03f115610002575050604051519650505b600091505b60008881526001602052604090206009015460ff831610156116d65760406000908120908990526001602052600901805460ff84169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604080515160008b81526001602052919091206009018054919350915060ff84169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a031663721a37d233836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061175057610002565b60008881526001602052604090206003810154600890910154131561156c576127109450611598565b600088815260016020526040902060028101546003820154600890920154918190039103612710020594505b6000888152600160208190526040909120600901805461271088810361ffff16975087810396509286929181101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604080515160008d815260016020529182206009018054919094029389935091908110156100025790815260208120909054906101000a9004600160a060020a0316600160a060020a03166370a08231336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750505060405180519060200150020104955085506113ed565b6000888152600160209081526040808320600490810154825160e060020a63a9059cbb028152600160a060020a0333811693820193909352602481018c9052925191169363a9059cbb936044848101949193929183900301908290876161da5a03f115610002575050604051511515905061134357610002565b600191909101906113f2565b8495505b505050505098975050505050505050565b8d8d8d8d8d8d8d8d604051808960001916815260200188151560f860020a0281526001018781526020018681526020018560ff1660f860020a02815260010184600160a060020a03166c0100000000000000000000000002815260140183600160a060020a03166c010000000000000000000000000281526014018280519060200190602002808383829060006004602084601f0104600302600f01f1509050019850505050505050505060405180910390209450600060010260016000506000876000191681526020019081526020016000206000506000016000505460001916111561185e57611760565b87600160a060020a031663c91d7e9c886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600302600f01f150905001925050506040604051808303816000876161da5a03f1156100025750506040518051602091909101519095509350506000841180156119bd575082600160a060020a03166323b872dd3330876040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506020604051808303816000876161da5a03f11561000257505060405151159050806119bd575082600160a060020a031663095ea7b389866040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511590505b156119c757610002565b87600160a060020a031663c1b06513886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600302600f01f150905001925050506020604051808303816000876161da5a03f115610002575050604051519250506000821415611a5257610002565b60008e81526002602052604090208054600181018083558281838015829011611a9e57818360005260206000209182019101611a9e91905b80821115611c975760008155600101611a8a565b50505091909060005260206000209001600087909190915055508d60016000506000876000191681526020019081526020016000206000506000016000508190555087600160005060008760001916815260200190815260200160002060005060050160006101000a815481600160a060020a0302191690830217905550816001600050600087600019168152602001908152602001600020600050600601600050819055508c600160005060008760001916815260200190815260200160002060005060010160146101000a81548160ff021916908302179055508b6001600050600087600019168152602001908152602001600020600050600201600050819055508a60016000506000876000191681526020019081526020016000206000506003016000508190555088600160005060008760001916815260200190815260200160002060005060040160006101000a815481600160a060020a030219169083021790555033600160005060008760001916815260200190815260200160002060005060010160006101000a815481600160a060020a0302191690830217905550600090505b8960ff168160ff16101561175c57600085815260016020819052604090912060090180549182018082559091908281838015829011611c9b57600083815260209020611c9b918101908301611a8a565b5090565b5050509190906000526020600020900160006040516104368061236c833901809050604051809103906000f0825473ffffffffffffffffffffffffffffffffffffffff1916179091555050600101611c47565b83604051805910611cfc5750595b908082528060200260200182016040528015611d13575b506000945084935091505b8851831015611fa2576000600102600160005060008b868151811015610002576020908102909101810151825281019190915260400160002054118015611db7575087600160a060020a031660001480611db7575087600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060050154600160a060020a0316145b8015611e15575086600160a060020a031660001480611e15575086600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060040154600160a060020a0316145b8015611e73575085600160a060020a031660001480611e73575085600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060010154600160a060020a0316145b15611fe5578883815181101561000257906020019060200201516001900482858151811015610002576020908102909101015288516001906000908b908690811015610002576020908102909101810151825281019190915260400160002054825183906001870190811015610002576020908102909101015288516001906000908b9086908110156100025760209081029091018101518252810191909152604001600020600101548251600160a060020a03919091169083906002870190811015610002576020908102909101015288516001906000908b90869081101561000257602090810290910181015182528101919091526040016000206001015460a060020a900460ff1615611ff157600182856003018151811015610002576020908102909101015261200c565b50979650505050505050565b600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060090154909301600c01925b60019290920191611d1e565b60008285600301815181101561000257602090810290910101525b600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060020154825183906004870190811015610002576020908102909101015288516001906000908b908690811015610002576020908102909101810151825281019190915260400160002060030154825183906005870190811015610002576020908102909101015288516001906000908b9086908110156100025760209081029091018101518252810191909152604001600020600401548251600160a060020a03919091169083906006870190811015610002576020908102909101015288516001906000908b9086908110156100025760209081029091018101518252810191909152604001600020600501548251600160a060020a03919091169083906007870190811015610002576020908102909101015288516001906000908b908690811015610002576020908102909101810151825281019190915260400160002060060154825183906008870190811015610002576020908102909101015288516001906000908b90869081101561000257602090810290910181015182528101919091526040016000206007015460ff16156121ee576001828560090181518110156100025760209081029091010152612209565b60008285600901815181101561000257602090810290910101525b600160005060008a85815181101561000257602090810290910181015182528101919091526040016000206008015482518390600a870190811015610002576020908102909101015288516001906000908b90869081101561000257602090810290910181015182528101919091526040016000206009015482518390600b87019081101561000257602090810290910101525060005b600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060090154811015611fae57600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060090180548290811015610002576000918252602090912001548251600160a060020a0391909116908390868401600c019081101561000257602090810290910101526001016122a0565b620f424082101561236457506004819055600161023e565b50600061023e56606060405260008054600160a060020a03191633179055610412806100246000396000f36060604052361561008d5760e060020a600035046306fdde03811461008f578063095ea7b3146100a557806318160ddd1461012457806323b872dd1461012f578063313ce567146101dc578063475a9fa9146101f057806370a0823114610215578063721a37d21461024357806395d89b411461008f578063a9059cbb14610268578063dd62ed3e146102e7575b005b61031d6040805160208101909152600081525b90565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db63c6605267600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b6102316003546100a2565b61038b60043560243560443560008054604080517fa00bfa1100000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038781166024830152868116604483015260648201869052929092166084830152517319ee743d2e356d5f0e4d97cc09b96d06e933d0db9163a00bfa119160a482810192602092919082900301818660325a03f4156100025750506040515195945050505050565b604080516000815290519081900360200190f35b61038b6004356024356000805433600160a060020a0390811691161461039f57610002565b600160a060020a03600435166000908152600160205260409020545b60408051918252519081900360200190f35b61038b6004356024356000805433600160a060020a039081169116146103ce57610002565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db6388d5fecb600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b610231600435602435600160a060020a038281166000908152600260209081526040808320938516835292905220545b92915050565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561037d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b604080519115158252519081900360200190f35b50600160a060020a03821660009081526001602081905260409091208054830190556003805483019055610317565b600160a060020a038316600090815260016020526040902054821161040a57506040600020805482900390556003805482900390556001610317565b50600061031756",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a0600",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x00000000000000000000000000000000000000000000000000000000000007d0",
- "0x6b8ad191d0fa8204d4eafca22ce4ec42425fde2eecf25ce484ecc76765b9a937": "0x00000000000000000000000001e60b511fced1eb2b5b40991eb1dfd171a6df42",
- "0x6b8ad191d0fa8204d4eafca22ce4ec42425fde2eecf25ce484ecc76765b9a938": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e854": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d915",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e855": "0x00000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e856": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e857": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e858": "0x00000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e859": "0x000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e85a": "0x846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f1",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e85b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e85c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e85d": "0x0000000000000000000000000000000000000000000000000000000000000002"
- }
- },
- "0x61c808d82a3ac53231750dadc13c777b59310bd9": {
- "balance": "0x90a7af5d4755984561",
- "nonce": "197408"
- },
- "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5": {
- "balance": "0x0",
- "code": "0x606060405236156100a35760e060020a6000350463031d973e81146100a557806316181bb7146100da5780635aa97eeb146103b1578063674cc1f5146104f75780636da84ec0146105d7578063929e626e146105fe578063a0bde7e8146106ac578063bbd4f8541461078b578063c1fd43391461098e578063c3c95c7b14610a88578063db833e3a14610afe578063df6c13c314610cfe578063ebb7119414610d13575b005b610d4960043560008181526020819052604081206004015481908390600160a060020a039081163390911614610dcb57610002565b610d0160043560243560443560643560008481526020819052604080822054815160e160020a63460b97d1028152600481018290529151909183918291829182916000805160206123dd83398151915291638c172fa29160248181019261016092909190829003018187876161da5a03f1156100025750506040805160a081015160c08201517fc51cf179000000000000000000000000000000000000000000000000000000008352600483018d90529251909750919550600160a060020a038616926323b872dd92339230929163c51cf1799160248181019260209290919082900301818b876161da5a03f11561000257505060408051805160e060020a6323b872dd028252600160a060020a039586166004830152939094166024850152918d01604484015250516064828101926020929190829003018187876161da5a03f11561000257505060405151159050806102e8575082600160a060020a031663095ea7b36000805160206123dd8339815191526000805160206123dd833981519152600160a060020a031663c51cf1798c6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a63095ea7b30282526004820193909352918d0160248301525160448281019350602092829003018187876161da5a03f115610002575050604051511590505b806103a757506000805160206123dd833981519152600160a060020a03166307d5b826866000805160206123dd833981519152600160a060020a031663c51cf1798c6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e160020a6303eadc130282526004820194909452928d016024840152516044838101936020935082900301816000876161da5a03f115610002575050604051511590505b15610fcd57610002565b60408051600480358082013560208181028086018201909652818552610d5d9593946024949093850192918291908501908490808284375094965050933593505050506040805160208181018352600080835283519182019093528281529091908190815b86518310156112c757600060010260006000506000898681518110156100025760209081029091018101518252810191909152604001600020541180156104af575085600160a060020a0316600014806104af575085600160a060020a03166000600050600089868151811015610002576020908102909101810151825281019190915260400160002060040154600160a060020a0316145b156104eb576000600050600088858151811015610002576020908102909101810151825281019190915260400160002060070154909301600901925b60019290920191610416565b60408051600480358082013560208181028086018201909652818552610d5d959394602494909385019291829190850190849080828437509496505050505050506040805160208181018352600080835283519182019093528281529091908190815b8551831015611713576000600160005060008886815181101561000257602090810290910181015182528101919091526040016000205411156105cb576001600050600087858151811015610002576020908102909101810151825281019190915260400160002054909301600201925b6001929092019161055a565b610d016004356024355b60009182526020829052604090912060010154620f424091020490565b610da760043561200060405190810160405280610100905b6000815260200190600190039081610616575050604080516120008101909152610100815b600081526020019060019003908161063b5750600090505b60008481526020819052604090206007015460ff821610156118d8576040600020600701805460ff8316908110156100025760009182526020909120810154908390610100811015610002576020020152600101610653565b610d5d600435604080516020818101835260008083528351808301855281815285825291819052835193812060070154929391929091600191909101908059106106f35750595b90808252806020026020018201604052801561070a575b509150428260008151811015610002576020919091019190915290505b60008481526020819052604090206007015460ff821610156118d8576040600020600701805460ff83169081101561000257906000526020600020900160005054828260010160ff1681518110156100025760209081029091010152600101610727565b610d0160043560243560443560643560008481526020819052604080822054815160e160020a63460b97d102815260048101919091529051829182918291829182916000805160206123dd83398151915291638c172fa29160248181019261016092909190829003018187876161da5a03f1156100025750505060405180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200150505050509a50505050505050600060005060008b60001916815260200190815260200160002060005060050160009054906101000a9004600160a060020a0316600160a060020a0316630439978d8b600060005060008e60001916815260200190815260200160002060005060030160005054600060005060008f6000191681526020019081526020016000206000506007016000508d8d6040518660e060020a0281526004018086600019168152602001858152602001806020018460ff168152602001838152602001828103825285818154815260200191508054801561095657602002820191906000526020600020905b81600050548152602001906001019080831161093f575b505096505050505050506020604051808303816000876161da5a03f1156100025750506040515194505060008414156118e357610fc0565b610d01600435602435604435606435600060006000600060006000805160206123dd833981519152600160a060020a0316638c172fa28a6040518260e060020a0281526004018082600019168152602001915050610160604051808303816000876161da5a03f1156100025750506040805160a081015160c08201518d83526c01000000000000000000000000600160a060020a033381168202602086810191909152908d16909102603485015284516048948190039490940190932080875292869052928520600301549097509195509350821415905080610a7357506207a12088115b80610a7e5750836000145b15611cc857611cbc565b60048035600090815260208181526040918290206002810154815484516001840154600385015497850154600586015460069096015493835295820152808601929092526060820195909552600160a060020a039283166080820152911660a082015260c0810192909252519081900360e00190f35b610d0160043560243560443560643560008481526020819052604080822054815160e160020a63460b97d10281526004810191909152905182918291829182916000805160206123dd83398151915291638c172fa291602482810192610160929190829003018187876161da5a03f1156100025750505060405180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200150505050509950505050505050600060005060008a60001916815260200190815260200160002060005060050160009054906101000a9004600160a060020a0316600160a060020a031663f47cd6718a600060005060008d60001916815260200190815260200160002060005060030160005054600060005060008e6000191681526020019081526020016000206000506007016000508c8c6040518660e060020a0281526004018086600019168152602001858152602001806020018460ff1681526020018381526020018281038252858181548152602001915080548015610cc657602002820191906000526020600020905b816000505481526020019060010190808311610caf575b505096505050505050506020604051808303816000876161da5a03f11561000257505060405151935050600083141561201957611cbc565b60005b60408051918252519081900360200190f35b610d0160043560008181526020819052604081206004015481908190849033600160a060020a039081169116146122df57610002565b604080519115158252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600302600f01f1509050019250505060405180910390f35b6040518082612000808381846000600461030ff15090500191505060405180910390f35b600091505b60008481526020819052604090206007015460ff83161015610eed576040600081812086825260208281528351915460e260020a6307c30783028352600483015260ff8616602483015292516000805160206123dd83398151915293631f0c1e0c9360448481019492939283900301908290876161da5a03f115610002575050604080515160008781526020819052919091206007018054600160a060020a0392909216925063a9059cbb9133919060ff871690811015610002579060005260206000209001600050546040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750506040515115159050610f7357610002565b60406000908120602082815282825560018201839055600282018390556003820183905560048201805473ffffffffffffffffffffffffffffffffffffffff19908116909155600583018054909116905560068201839055600782018054848255908452908320919291610fa7918101905b80821115610fb45760008155600101610f5f565b6000848152602081905260408120600701805460ff8516908110156100025790825260208220015560019190910190610dd0565b5060019695505050505050565b5090565b818385010195505b5050505050949350505050565b6040805160e260020a6307c307830281526004810187905260ff8b16602482015290516000805160206123dd83398151915291631f0c1e0c91604482810192602092919082900301816000876161da5a03f11561000257505060408051805160e060020a63095ea7b302825230600160a060020a039081166004840152602483018d905292519216925063095ea7b391604482810192602092919082900301816000876161da5a03f115610002575050604051511515905061108e57610002565b604080517fdb833e3a000000000000000000000000000000000000000000000000000000008152600481018c905260ff8b166024820152604481018a905260648101899052905130600160a060020a03169163db833e3a91608482810192602092919082900301816000876161da5a03f11561000257505060405151925050600082141561111b57610002565b5060005b838160ff1610156111f75760ff808a169082161461125b576040805160e260020a6307c307830281526004810187905260ff8316602482015290516000805160206123dd83398151915291631f0c1e0c91604482810192602092919082900301816000876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600160a060020a033381166004840152602483018d905292519216925063a9059cbb91604482810192602092919082900301816000876161da5a03f115610002575050604051511515905061125b57610002565b82600160a060020a031663a9059cbb33846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061126357610002565b60010161111f565b816000805160206123dd833981519152600160a060020a031663c51cf1798a6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f115610002575050604051518a01919091039650610fc09050565b836040518059106112d55750595b9080825280602002602001820160405280156112ec575b506000945084935091505b86518310156116c65760006001026000600050600089868151811015610002576020908102909101810151825281019190915260400160002054118015611390575085600160a060020a031660001480611390575085600160a060020a03166000600050600089868151811015610002576020908102909101810151825281019190915260400160002060040154600160a060020a0316145b1561170757868381518110156100025790602001906020020151600190048285815181101561000257602090810290910101528651600090819089908690811015610002576020908102909101810151825281019190915260400160002054825183906001870190811015610002576020908102909101015286516000908190899086908110156100025760209081029091018101518252810191909152604001600020600101548251839060028701908110156100025760209081029091010152865160009081908990869081101561000257602090810290910181015182528101919091526040016000206002015482518390600387019081101561000257602090810290910101528651600090819089908690811015610002576020908102909101810151825281019190915260400160002060030154825183906004870190811015610002576020908102909101015286516000908190899086908110156100025760209081029091018101518252810191909152604001600020600401548251600160a060020a03919091169083906005870190811015610002576020908102909101015286516000908190899086908110156100025760209081029091018101518252810191909152604001600020600501548251600160a060020a03919091169083906006870190811015610002576020908102909101015286516000908190899086908110156100025760209081029091018101518252810191909152604001600020600601548251839060078701908110156100025760209081029091010152865160009081908990869081101561000257602090810290910181015182528101919091526040016000206007015482518390600887019081101561000257602090810290910101525060005b60006000506000888581518110156100025760209081029091018101518252810191909152604001600020600701548110156116d0576000600050600088858151811015610002576020908102909101810151825281019190915260400160002060070180548290811015610002579060005260206000209001600050548282866009010181518110156100025760209081029091010152600101611626565b5095945050505050565b6000600050600088858151811015610002576020908102909101810151825281019190915260400160002060070154909301600901925b600192909201916112f7565b836040518059106117215750595b908082528060200260200182016040528015611738575b506000945084935091505b8551831015611892576000600160005060008886815181101561000257602090810290910181015182528101919091526040016000205411156118cc578583815181101561000257906020019060200201516001900482858151811015610002576020908102909101015285516001906000908890869081101561000257602090810290910181015182528101919091526040016000205482518390600187019081101561000257602090810290910101525060005b600160005060008785815181101561000257602090810290910181015182528101919091526040016000205481101561189b57600160005060008785815181101561000257602090810290910181015182528101919091526040016000208054829081101561000257600091825260209091200154825183908684016002019081101561000257602090810290910101526001016117f9565b50949350505050565b6001600050600087858151811015610002575050602085810289018101518252919091526040902054909301600201925b60019290920191611743565b8192505b5050919050565b6118ed8a856105e1565b92506000805160206123dd833981519152600160a060020a031663c51cf179896040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f1156100025750506040515192505083830182018790111561195857610fc0565b84600160a060020a03166323b872dd333085878901016040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506020604051808303816000876161da5a03f1156100025750506040515115905080611a3557506040805160e060020a63095ea7b30281526000805160206123dd833981519152600482015285840160248201529051600160a060020a0387169163095ea7b391604482810192602092919082900301816000876161da5a03f115610002575050604051511590505b80611aa9575060008a81526020818152604080832054815160e160020a6303eadc130281526004810191909152878601602482015290516000805160206123dd833981519152936307d5b826936044848101949193929183900301908290876161da5a03f115610002575050604051511590505b15611ab357610002565b5060005b60008a81526020819052604090206007015460ff82161015611b06576040600020600701805485919060ff84169081101561000257600091825260209091200180549091019055600101611ab7565b604060009081208b8252602091909152600701805460ff8b169081101561000257600091825260209091200154881115611b3f57610002565b60008a815260208190526040902060028101805485019055600701805489919060ff8c1690811015610002579060005260206000209001600050805491909103905560008a81526020818152604080832054815160e260020a6307c30783028152600481019190915260ff8d16602482015290516000805160206123dd83398151915293631f0c1e0c936044848101949193929183900301908290876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600160a060020a033381166004840152602483018d905292519216925063a9059cbb91604482810192602092919082900301816000876161da5a03f1156100025750506040515115159050610fb857610002565b505050600092835250602080832090910184905583825281905260409020600181018990556003810188905589815560048101805473ffffffffffffffffffffffffffffffffffffffff199081163317909155600582018054909116881790554360069091015590935083905b50505050949350505050565b82600160a060020a03166323b872dd33306000805160206123dd833981519152600160a060020a031663c51cf1798c6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a6323b872dd028252600160a060020a039586166004830152939094166024850152918c0160448401525051606482810192602092919082900301816000876161da5a03f1156100025750506040515115905080611e45575082600160a060020a031663095ea7b36000805160206123dd8339815191526000805160206123dd833981519152600160a060020a031663c51cf1798b6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a63095ea7b30282526004820193909352918c016024830152516044828101935060209282900301816000876161da5a03f115610002575050604051511590505b80611f0457506000805160206123dd833981519152600160a060020a03166307d5b8268a6000805160206123dd833981519152600160a060020a031663c51cf1798b6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e160020a6303eadc130282526004820194909452928c016024840152516044838101936020935082900301816000876161da5a03f115610002575050604051511590505b15611f0e57610002565b83604051805910611f1c5750595b908082528060200260200182016040528015611f33575b506000838152602081815260408220600701805484518083558285529383902091949082019392018215611f86579160200282015b82811115611f86578251826000505591602001919060010190611f68565b50611f92929150610f5f565b5050600090505b838160ff161015611fda576000828152602081905260409020600701805488919060ff84169081101561000257600091825260209091200155600101611f99565b600089815260016020819052604090912080549182018082559091908281838015829011611c4f57600083815260209020611c4f918101908301610f5f565b61202389846105e1565b915085828403101561203457611cbc565b60008981526020818152604080832054815160e260020a6307c30783028152600481019190915260ff8c16602482015290516000805160206123dd83398151915293631f0c1e0c936044848101949193929183900301908290876161da5a03f11561000257505060408051805160e060020a6323b872dd028252600160a060020a0333811660048401523081166024840152604483018c90529251921692506323b872dd91606482810192602092919082900301816000876161da5a03f115610002575050604051511590508061218d57506000805160206123dd833981519152600160a060020a0316634025b293600060005060008c60001916815260200190815260200160002060005060000160005054856040518360e060020a0281526004018083600019168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511590505b1561219757610002565b6000898152602081905260409020600701805488919060ff8b16908110156100025760009182526020822001805490920190915590505b60008981526020819052604090206007015460ff82161015612254576040600020600701805484919060ff84169081101561000257600091825260209091200154106122d0576000898152602081905260409020600701805484919060ff84169081101561000257906000526020600020900160005080549190910390556001016121ce565b600089815260208181526040808320600201805486019055805160e060020a63a9059cbb028152600160a060020a033381166004830152868803602483015291519188169363a9059cbb93604483810194919391929183900301908290876161da5a03f11561000257505060405151151590506122d557610002565b610002565b8183039450611cbc565b60008581526020819052604080822054815160e160020a63460b97d1028152600481019190915290516000805160206123dd83398151915292638c172fa292602481810193610160939092839003909101908290876161da5a03f1156100025750506040805160c001516000888152602081905291822060020180549083905590955093508311905080156123ca575082600160a060020a031663a9059cbb33846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511590505b156123d457610002565b819350506118dc560000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "storage": {
- "0x50ff25f5e9a51687bca1c50f3544d5eef8202f228d3de791691a137aecb6b360": "0x00000000000000000000000000000000000000000000000026566ea1ec2f6a9b",
- "0x50ff25f5e9a51687bca1c50f3544d5eef8202f228d3de791691a137aecb6b361": "0x00000000000000000000000000000000000000000000000072aa5b7e04d56a9b",
- "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed86c": "0xd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac",
- "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed86d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed86e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed86f": "0x0000000000000000000000000000000000000000000000004563918244f40000",
- "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed871": "0x0000000000000000000000008695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed873": "0x0000000000000000000000000000000000000000000000000000000000000002"
- }
- },
- "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0": {
- "balance": "0x0",
- "code": "0x606060405260e060020a60003504630439978d811461003157806308f028d514610115578063f47cd6711461026e575b005b60408051604435600481810135602081810285810182019096528185526103509583359560248035966064959294910192829185019084908082843750949650509335935050608435915050600060006040604051908101604052806002905b60008152602001906001900390816100915790505060006000600061271073ef3487d24a0702703e04a26cef479e313c8fc7ae6324d4e90a604060020a8c51026040518260e060020a028152600401808281526020019150506020604051808303818660325a03f41561000257505060405151919091049550610398905089610157565b60408051600480358082013560208181028086018201909652818552610362959394602494909385019291829190850190849080828437509496505050505050505b6040604051908101604052806002905b6000815260200190600190039081610167575050604080518082019091526002815b600081526020019060019003908161018957905050600083600081518110156100025760209081029091010151825283518490600090811015610002576020908102909101810151908301525060005b83518160ff1610156104a7578351825190859060ff8416908110156100025790602001906020020151101561022357838160ff168151811015610002576020908102909101015182525b60208201518451859060ff8416908110156100025790602001906020020151111561026657838160ff168151811015610002576020908102909101810151908301525b6001016101d9565b60408051604435600481810135602081810285810182019096528185526103509583359560248035966064959294910192829185019084908082843750949650509335935050608435915050600060006040604051908101604052806002905b60008152602001906001900390816102ce579050506000600061271073ef3487d24a0702703e04a26cef479e313c8fc7ae6324d4e90a604060020a8b51026040518260e060020a028152600401808281526020019150506020604051808303818660325a03f415610002575050604051519190910494506104ae905088610157565b60408051918252519081900360200190f35b60408051908190839080838184600060046015f15090500191505060405180910390f35b8095505b505050505095945050505050565b935061044d85858b8d5b6000806127108304815b85518160ff16101561051d5773ef3487d24a0702703e04a26cef479e313c8fc7ae63872fb2b589848a6000909060200201518a8660ff1681518110156100025760209081029091010151038b600060200201518c600190906020020151030304026040518260e060020a028152600401808281526020019150506020604051808303818660325a03f4156100025750506040515190930192506001016103ac565b925086898960ff16815181101561000257602090810290910101805191909103905261047b85858b8d6103a2565b915050604060020a620186a0620186a28484036127108d0402020404868111156103865786955061038a565b5092915050565b6020810180518801905292506104c684848a8c6103a2565b915085888860ff16815181101561000257602090810290910101805190910190526104f384848a8c6103a2565b9050604060020a620186a06127108b04838503026201869e02040494505050505095945050505050565b87604060020a73ef3487d24a0702703e04a26cef479e313c8fc7ae6324d4e90a866040518260e060020a028152600401808281526020019150506020604051808303818660325a03f4156100025750506040515190910291909104999850505050505050505056"
- },
- "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2": {
- "balance": "0xa6e361612cc228000",
- "code": "0x6060604052361561008d5760e060020a600035046306fdde03811461008f578063095ea7b3146100ed57806318160ddd1461016257806323b872dd1461016b578063313ce567146102565780636c11bcd31461026257806370a08231146102d057806395d89b41146102f5578063a9059cbb14610353578063d0febe4c146103f8578063dd62ed3e14610439575b005b6040805160038054602060026001831615610100026000190190921691909104601f810182900482028401820190945283835261046d939083018282801561052e5780601f106105035761010080835404028352916020019161052e565b61042560043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b6104db60025481565b610425600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101be575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101ca5750600082115b1561053657600160a060020a0383811660008181526020818152604080832080548801905588851680845281842080548990039055600183528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a350600161053a565b6104ed60055460ff1681565b61042560043533600160a060020a0316600090815260208190526040812054821161054157604081208054839003905560028054839003905580821180156102c6575060405133600160a060020a0316908290849082818181858883f19350505050155b1561054957610002565b6104db600435600160a060020a0381166000908152602081905260409020545b919050565b61046d6004805460408051602060026000196101006001871615020190941693909304601f8101849004840282018401909252818152929183018282801561052e5780601f106105035761010080835404028352916020019161052e565b61042560043560243533600160a060020a03166000908152602081905260408120548290108015906103855750600082115b156105515733600160a060020a0390811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161015c565b33600160a060020a0316600090815260208190526040902080543490810190915560028054909101905560015b604080519115158252519081900360200190f35b6104db600435602435600160a060020a0382811660009081526001602090815260408083209385168352929052205461015c565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156104cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b81548152906001019060200180831161051157829003601f168201915b505050505081565b5060005b9392505050565b5060006102f0565b5060016102f0565b50600061015c56",
- "storage": {
- "0x3830062b39ca7888048a385f112e36aef7258a27d84eb6e31312c298e5954da3": "0x0000000000000000000000000000000000000000000000035fe3763f1973ab3b",
- "0x527b1dd758d53f706730e0fb37a8de5c38d8b4cd17fbe1cfa285480a00f55bf4": "0x000000000000000000000000000000000000000000000003ab97b2fc29ad66c6",
- "0x52cb6de4baff82acfb6977b64d52b9ac011f8af34631d933997b7649a84d716f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8f0cfa08792bcd3de052a3bb7bd54f8a62c44b02ba16ff336e9a881c348cca21": "0x000000000000000000000000000000000000000000046ba103abb9d1301f1b2e",
- "0xa29249eda6f9f8d0c67b7a4f954f6ba7a9f1bb3f216b2fedc6db8def03c47746": "0x00000000000000000000000000000000000000000000000007a93ebd870d6684",
- "0xbe1e23f4b08159a01ee61379749e9b484f5947aaeeb008ce7c97d1c56d3eeb8b": "0x0000000000000000000000000000000000000000000000000dfecc50c6f7d5cd"
- }
- },
- "0xef3487d24a0702703e04a26cef479e313c8fc7ae": {
- "balance": "0x0",
- "code": "0x6503060000000050606060405260e060020a600035046324d4e90a8114610031578063872fb2b514610078575b610007565b61013c6004356000680171547652b82fe177818080808061014e886000604060020a82048160bf605f5b6001830182146103c4578060020a8410156103ce579050806103d2565b61013c600435604060020a67b17217f7d1cf79ac81830281900482810460020a680100000016aee6e8ef67b172182739bc0e46858406908102869004673d7f78a624cfb9b582800288900490810288900491909101670e359bcfeb6e45319183028890049182028890040167027601df2fc048dc91830288900491820288900401665808a728816ee89183028890049182028890040166095dedef350bc991830288900491820297909704969096019190910182810295905b505050505050919050565b60408051918252519081900360200190f35b94508460020a88049350604060020a9250604060020a600a029150819050604060020a83680443b9c5adb08cc45f0204810390508050604060020a8484020492508250604060020a83680f0a52590f17c71a3f0204810190508050604060020a8484020492508250604060020a83682478f22e787502b0230204810390508050604060020a8484020492508250604060020a836848c6de1480526b8d4c0204810190508050604060020a8484020492508250604060020a836870c18cae824656408c0204810390508050604060020a8484020492508250604060020a8368883c81ec0ce7abebb20204810190508050604060020a8484020492508250604060020a836881814da94fe52ca9f50204810390508050604060020a8484020492508250604060020a8368616361924625d1acf50204810190508050604060020a8484020492508250604060020a836839f9a16fb9292a608d0204810390508050604060020a8484020492508250604060020a83681b3049a5740b21d65f0204810190508050604060020a8484020492508250604060020a836809ee1408bd5ad96f3e0204810390508050604060020a8484020492508250604060020a836802c465c91703b7a7f40204810190508050604060020a8484020492508250604060020a8367918d2d5f045a4d630204810390508050604060020a8484020492508250604060020a836714ca095145f44f780204810190508050604060020a8484020492508250604060020a836701d806fc412c1b990204810390508050604060020a8484020492508250604060020a836613950b4e1e89cc020481019050805085604060020a8383604060020a8902010302049650610131565b5090949350505050565b9150815b5060028282010461005b56"
- },
- "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28": {
- "balance": "0x0",
- "code": "0x6060604052361561008d5760e060020a600035046306fdde03811461008f578063095ea7b3146100a557806318160ddd1461012457806323b872dd1461012f578063313ce567146101dc578063475a9fa9146101f057806370a0823114610215578063721a37d21461024357806395d89b411461008f578063a9059cbb14610268578063dd62ed3e146102e7575b005b61031d6040805160208101909152600081525b90565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db63c6605267600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b6102316003546100a2565b61038b60043560243560443560008054604080517fa00bfa1100000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038781166024830152868116604483015260648201869052929092166084830152517319ee743d2e356d5f0e4d97cc09b96d06e933d0db9163a00bfa119160a482810192602092919082900301818660325a03f4156100025750506040515195945050505050565b604080516000815290519081900360200190f35b61038b6004356024356000805433600160a060020a0390811691161461039f57610002565b600160a060020a03600435166000908152600160205260409020545b60408051918252519081900360200190f35b61038b6004356024356000805433600160a060020a039081169116146103ce57610002565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db6388d5fecb600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b610231600435602435600160a060020a038281166000908152600260209081526040808320938516835292905220545b92915050565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561037d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b604080519115158252519081900360200190f35b50600160a060020a03821660009081526001602081905260409091208054830190556003805483019055610317565b600160a060020a038316600090815260016020526040902054821161040a57506040600020805482900390556003805482900390556001610317565b50600061031756",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000012098a4651fb262f7",
- "0xfae22198212900725daa5db635d1fda7b0fa195adaabdc806a7267959c3d8ae4": "0x000000000000000000000000000000000000000000000000731fb89f735062f7",
- "0xfd73dc2251dc113619c6fcc1c142e797f06e77a178cc37fe300a56823b741ef7": "0x0000000000000000000000000000000000000000000000008ac7230489e80000"
- }
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "2340153",
- "difficulty": "80383973372327",
- "timestamp": "1475034716",
- "gasLimit": "1500062",
- "miner": "0x61c808d82a3ac53231750dadc13c777b59310bd9"
- },
- "input": "0xf8ea508504a817c80083084398946ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba580b884bbd4f854e9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000080d29fa5cccfadac1ba0690ce7a4cf8590c636a1799ebf2cc52229714c47da72ee406fb9bd7d29e52440a017b6ce39e8876965afa2a1c579a592eb1af146506ccdbfc2c9ea422b13dca438",
- "tracerConfig": {
- "withLog": true
- },
- "result": {
- "from": "0x3de712784baf97260455ae25fb74f574ec9c1add",
- "gas": "0x84398",
- "gasUsed": "0x27ec3",
- "to": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "input": "0xbbd4f854e9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "output": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "calls": [
- {
- "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "gas": "0x77e82",
- "gasUsed": "0x54c",
- "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "input": "0x8c172fa2d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac",
- "output": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d91500000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "gas": "0x7737b",
- "gasUsed": "0x3fe1",
- "to": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "input": "0x0439978de9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000026566ea1ec2f6a9b00000000000000000000000000000000000000000000000072aa5b7e04d56a9b",
- "output": "0x0000000000000000000000000000000000000000000000008060b57e2e0c99aa",
- "calls": [
- {
- "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "gas": "0x770ef",
- "gasUsed": "0xc24",
- "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae",
- "input": "0x24d4e90a0000000000000000000000000000000000000000000000020000000000000000",
- "output": "0x000000000000000000000000000000000000000000000000b17217f7d1cf79ab",
- "type": "DELEGATECALL",
- "value": "0x0"
- },
- {
- "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "gas": "0x75eb2",
- "gasUsed": "0x265",
- "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae",
- "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8",
- "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878",
- "type": "DELEGATECALL",
- "value": "0x0"
- },
- {
- "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "gas": "0x75aad",
- "gasUsed": "0x25b",
- "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae",
- "input": "0x872fb2b50000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x00000000000000000000000000000000000000000000000100000016aee6e8ef",
- "type": "DELEGATECALL",
- "value": "0x0"
- },
- {
- "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "gas": "0x75737",
- "gasUsed": "0xc24",
- "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae",
- "input": "0x24d4e90a00000000000000000000000000000000000000000000000324bf7e0976f5f167",
- "output": "0x0000000000000000000000000000000000000000000000012535c5e5f87ee0d2",
- "type": "DELEGATECALL",
- "value": "0x0"
- },
- {
- "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "gas": "0x748c7",
- "gasUsed": "0x265",
- "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae",
- "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8",
- "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878",
- "type": "DELEGATECALL",
- "value": "0x0"
- },
- {
- "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "gas": "0x744c2",
- "gasUsed": "0x265",
- "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae",
- "input": "0x872fb2b500000000000000000000000000000000000000000000000237d37fe5d297a500",
- "output": "0x0000000000000000000000000000000000000000000000093088c407fcbbce38",
- "type": "DELEGATECALL",
- "value": "0x0"
- },
- {
- "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0",
- "gas": "0x74142",
- "gasUsed": "0xc99",
- "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae",
- "input": "0x24d4e90a00000000000000000000000000000000000000000000000b554841fac4cad6b0",
- "output": "0x0000000000000000000000000000000000000000000000026d7fc130d6a74cbe",
- "type": "DELEGATECALL",
- "value": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "gas": "0x731be",
- "gasUsed": "0x241",
- "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "input": "0xc51cf179000000000000000000000000000000000000000000000000de0b6b3a76400000",
- "output": "0x0000000000000000000000000000000000000000000000000071ea279ec31402",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "gas": "0x72df4",
- "gasUsed": "0x468b",
- "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "input": "0x23b872dd0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba500000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add",
- "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5"
- ],
- "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "gas": "0x6e627",
- "gasUsed": "0x56d6",
- "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "input": "0x095ea7b30000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "topics": [
- "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
- "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd"
- ],
- "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "gas": "0x68dae",
- "gasUsed": "0xd6f0",
- "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "input": "0x07d5b826d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac00000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "gas": "0x629ff",
- "gasUsed": "0x468b",
- "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "input": "0x23b872dd0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd"
- ],
- "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "gas": "0x5e0df",
- "gasUsed": "0x31af",
- "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "input": "0xa9059cbb000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a060000000000000000000000000000000000000000000000000041f50e27d56848",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "0x000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a06"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000041f50e27d56848",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "gas": "0x5ac6b",
- "gasUsed": "0x29ae",
- "to": "0x01e60b511fced1eb2b5b40991eb1dfd171a6df42",
- "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "gas": "0x57fed",
- "gasUsed": "0x29ae",
- "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28",
- "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "gas": "0x56030",
- "gasUsed": "0x265",
- "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd",
- "input": "0x1f0c1e0cd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac0000000000000000000000000000000000000000000000000000000000000001",
- "output": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "gas": "0x55cc3",
- "gasUsed": "0x339f",
- "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28",
- "input": "0xa9059cbb0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28",
- "gas": "0x55a8a",
- "gasUsed": "0x30f7",
- "to": "0x19ee743d2e356d5f0e4d97cc09b96d06e933d0db",
- "input": "0x88d5fecb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5",
- "0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add"
- ],
- "data": "0x000000000000000000000000000000000000000000000000de0b6b3a76400000",
- "position": "0x0"
- }
- ],
- "type": "DELEGATECALL",
- "value": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json
deleted file mode 100644
index 263e88d6e1..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json
+++ /dev/null
@@ -1,2327 +0,0 @@
-{
- "genesis": {
- "difficulty": "59917798787272",
- "extraData": "0xe4b883e5bda9e7a59ee4bb99e9b1bc",
- "gasLimit": "4712380",
- "hash": "0xae82afe3630b001a34ad4c51695dacb17872ebee4dadd2de88b1a16671871da4",
- "miner": "0x61c808d82a3ac53231750dadc13c777b59310bd9",
- "mixHash": "0x23c2289cdee8a397cf36db9ffa3419503bed54eb09e988b3c7a3587a090e6fc1",
- "nonce": "0x94dc83e0044f49c8",
- "number": "1881283",
- "stateRoot": "0x6e3832bc2e4e66170a1e716449083e08fbb70e7b2a9f1f34e0c57e66ce40c50f",
- "timestamp": "1468467284",
- "totalDifficulty": "37186898441932102239",
- "alloc": {
- "0x0000000000000000000000000000000000000004": {
- "balance": "0x0"
- },
- "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e": {
- "balance": "0x0",
- "code": "0x606060405236156100f05760e060020a600035046303afc23581146100f257806313af4035146101145780631838e26614610136578063186ef9621461014d57806327df8c501461016f578063295d5866146101915780634162169f146101b35780634dfc3db6146101c55780636637b882146101e8578063839d3f7f1461020a57806386c9b5361461021d5780638da5cb5b1461022f5780639093a5e714610241578063b199efb514610263578063b262b9ae14610275578063b9f34aa114610297578063be9a6555146102a9578063d1c3c84a146102c7578063e26fc92b146102d9578063e8d9f074146102eb575b005b6100f0600435600054600160a060020a03908116339091161461034057610002565b6100f0600435600054600160a060020a03908116339091161461035557610002565b6102fd60006000600060006000600061036a6101c9565b6100f0600435600054600160a060020a0390811633909116146108a157610002565b6100f0600435600054600160a060020a0390811633909116146108b657610002565b6100f0600435600054600160a060020a0390811633909116146108cb57610002565b61030f600154600160a060020a031681565b6102fd5b60008054600160a060020a0390811633909116146108e0575060015b90565b6100f0600435600054600160a060020a03908116339091161461098857610002565b61032c60075460a060020a900460ff1681565b61030f600454600160a060020a031681565b61030f600054600160a060020a031681565b6100f0600435600054600160a060020a03908116339091161461099d57610002565b61030f600254600160a060020a031681565b6100f0600435600054600160a060020a0390811633909116146109b257610002565b61030f600754600160a060020a031681565b6100f060005433600160a060020a03908116911614610a1a57610002565b61030f600354600160a060020a031681565b61030f600554600160a060020a031681565b61030f600654600160a060020a031681565b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60048054600160a060020a0319168217905550565b60008054600160a060020a0319168217905550565b945060008514610380578495505b505050505090565b6002546040805160015460e060020a634162169f0282529151600160a060020a039283169390921691634162169f9160048181019260209290919082900301816000876161da5a03f11561000257505060405151600160a060020a031690911490506103ef5760649550610378565b600260009054906101000a9004600160a060020a0316600160a060020a0316634dfc3db66040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519450506000841461045857836064019550610378565b6040805160015460035460e060020a634162169f0283529251600160a060020a039182169390911691634162169f91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a031690911490506104c65760c89550610378565b600360009054906101000a9004600160a060020a0316600160a060020a0316634dfc3db66040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519350506000831461052f578260c8019550610378565b604080516001546004805460e060020a634162169f0284529351600160a060020a039283169490921692634162169f928183019260209282900301816000876161da5a03f11561000257505060405151600160a060020a0316909114905061059b5761012c9550610378565b60408051600480547f4dfc3db60000000000000000000000000000000000000000000000000000000083529251600160a060020a039390931692634dfc3db692808301926020929182900301816000876161da5a03f1156100025750506040515192505060008214610613578161012c019550610378565b6040805160015460055460e060020a634162169f0283529251600160a060020a039182169390911691634162169f91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a03169091149050610682576101909550610378565b600560009054906101000a9004600160a060020a0316600160a060020a0316634dfc3db66040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151915050600081146106ec5780610190019550610378565b6040805160015460065460e060020a634162169f0283529251600160a060020a039182169390911691634162169f91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a0316909114905061075b576101f49550610378565b6040805160065460e060020a638da5cb5b028252915130600160a060020a03908116931691638da5cb5b91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a031690911490506107c6576101f59550610378565b6040805160075460015460e060020a634162169f0283529251600160a060020a03938416939190911691634162169f91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a03169091149050610836576102589550610378565b6040805160075460e060020a638da5cb5b028252915130600160a060020a03908116931691638da5cb5b91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a03169091149050610378576102599550610378565b60038054600160a060020a0319168217905550565b60058054600160a060020a0319168217905550565b60068054600160a060020a0319168217905550565b600154600160a060020a0316600014156108fc575060026101e5565b600654600160a060020a031660001415610918575060036101e5565b600754600160a060020a031660001415610934575060046101e5565b600254600160a060020a031660001415610950575060056101e5565b600354600160a060020a03166000141561096c575060066101e5565b600454600160a060020a0316600014156101e5575060076101e5565b60018054600160a060020a0319168217905550565b60078054600160a060020a0319168217905550565b60028054600160a060020a0319168217905550565b600260009054906101000a9004600160a060020a0316600160a060020a031663975057e76040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050505b565b610a8a600154604080517f4b6753bc0000000000000000000000000000000000000000000000000000000081529051600092600160a060020a031691634b6753bc916004828101926020929190829003018187876161da5a03f11561000257505060405151421191506101e59050565b1515610a9557610a18565b60075460a060020a900460ff1615610e93576111556040805160015460065460e060020a6370a08231028352600160a060020a039081166004840152925160009384939216916370a08231916024808301926020929190829003018187876161da5a03f1156100025750506040515191909111159050610c61576040805160065460025460015460e060020a6370a08231028452600160a060020a0392831660048501819052945163a9059cbb949284169391909116916370a0823191602482810192602092919082900301818a876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600482019490945260248101939093525160448084019360209350829003018187876161da5a03f1156100025750506040805160025460e060020a63a8618f71028252600160a060020a031660048201819052915191925063a8618f71916024828101926020929190829003018187876161da5a03f11561000257505060405151159050610c6157600260009054906101000a9004600160a060020a0316600160a060020a031663975057e76040518160e060020a0281526004018090506000604051808303816000876161da5a03f11561000257506001925050505b6001546007546040805160e060020a6370a08231028152600160a060020a0392831660048201529051600093909216916370a0823191602481810192602092909190829003018187876161da5a03f1156100025750506040515191909111159050610e1b576040805160075460025460015460e060020a6370a08231028452600160a060020a0392831660048501819052945163a9059cbb949284169391909116916370a0823191602482810192602092919082900301816000876161da5a03f11561000257505060408051805160e060020a63a9059cbb02825260048201949094526024810193909352516044838101936020935082900301816000876161da5a03f1156100025750506040805160025460e060020a63a8618f71028252600160a060020a031660048201819052915191925063a8618f7191602482810192602092919082900301816000876161da5a03f11561000257505060405151159050610e1b57600260009054906101000a9004600160a060020a0316600160a060020a031663975057e76040518160e060020a0281526004018090506000604051808303816000876161da5a03f11561000257506001925050505b8015610e7257600260009054906101000a9004600160a060020a0316600160a060020a0316632e64cec16040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050505b6007805474ff00000000000000000000000000000000000000001916905550565b600260009054906101000a9004600160a060020a0316600160a060020a0316632e64cec16040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050505b60048054604080517ffc3407160000000000000000000000000000000000000000000000000000000081529051600160a060020a03929092169263fc340716928282019260009290829003018183876161da5a03f115610002575050600354604080517fd95f98ce0000000000000000000000000000000000000000000000000000000081529051600160a060020a0392909216925063d95f98ce916004828101926000929190829003018183876161da5a03f11561000257505050620f42405a11156109c7576109c76001546005546040805160e060020a6370a08231028152600160a060020a039283166004820152905192909116916370a082319160248181019260209290919082900301816000876161da5a03f1156100025750506040515160001415905061108357604080516002546005547fd0679d34000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015260016024840152925192169163d0679d349160448181019260209290919082900301816000876161da5a03f115610002575050505b5b600554604080517f400e39490000000000000000000000000000000000000000000000000000000081529051600a92600160a060020a03169163400e394991600482810192602092919082900301816000876161da5a03f1156100025750506040515191909110905080156110fb5750620aae605a115b15610a1857600560009054906101000a9004600160a060020a0316600160a060020a031663ff2f4bd26040518160e060020a0281526004018090506000604051808303816000876161da5a03f11561000257505050611084565b610ee456",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89",
- "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000001f835a0247b0063c04ef22006ebe57c5f11977cc4"
- }
- },
- "0x304a554a310c7e546dfe434669c62820b7d83490": {
- "balance": "0x3034f5ca7d45e17df1d83",
- "nonce": "3",
- "code": "0x6060604052361561020e5760e060020a6000350463013cf08b8114610247578063095ea7b3146102d05780630c3b7b96146103455780630e7082031461034e578063149acf9a1461036057806318160ddd146103725780631f2dc5ef1461037b57806321b5b8dd1461039b578063237e9492146103ad57806323b872dd1461040e5780632632bf2014610441578063341458081461047257806339d1f9081461047b5780634b6753bc146104935780634df6d6cc1461049c5780634e10c3ee146104b7578063590e1ae3146104ca578063612e45a3146104db578063643f7cdd1461057a578063674ed066146105925780636837ff1e1461059b57806370a08231146105e5578063749f98891461060b57806378524b2e1461062457806381f03fcb1461067e57806382661dc41461069657806382bf6464146106b75780638b15a605146106c95780638d7af473146106d257806396d7f3f5146106e1578063a1da2fb9146106ea578063a3912ec814610704578063a9059cbb1461070f578063b7bc2c841461073f578063baac53001461074b578063be7c29c1146107b1578063c9d27afe14610817578063cc9ae3f61461082d578063cdef91d014610841578063dbde198814610859578063dd62ed3e1461087e578063e33734fd146108b2578063e5962195146108c6578063e66f53b7146108de578063eceb2945146108f0578063f8c80d261461094f575b610966600f546000906234bc000142108015610239575060125433600160a060020a03908116911614155b156109785761098033610752565b6109866004356000805482908110156100025750808052600e8202600080516020612a3683398151915201905060038101546004820154600683015460018401548454600786015460058701546009880154600a890154600d8a0154600160a060020a039586169b509599600201989760ff81811698610100909204811697949691951693168c565b61096660043560243533600160a060020a03908116600081815260156020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b61096660105481565b610a7d600754600160a060020a031681565b610a7d600e54600160a060020a031681565b61096660165481565b6109665b60004262127500600f60005054031115610de557506014610983565b610a7d601254600160a060020a031681565b60408051602060248035600481810135601f810185900485028601850190965285855261096695813595919460449492939092019181908401838280828437509496505050505050506000600060006000600060003411156116a857610002565b6109666004356024356044355b60115460009060ff1680156104315750600f5442115b80156124e957506124e78461044b565b6109666000610980335b600160a060020a0381166000908152600b602052604081205481908114156129cb57610b99565b61096660065481565b6109665b600d5430600160a060020a03163103610983565b610966600f5481565b61096660043560046020526000908152604090205460ff1681565b61096660043560243560006124cb610831565b610a9a6000341115610ba457610002565b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec565b61096660043560096020526000908152604090205481565b61096660015481565b610a9a60043530600160a060020a031633600160a060020a03161415806105db5750600160a060020a03811660009081526004602052604090205460ff16155b156121cb576121c8565b6109666004355b600160a060020a0381166000908152601460205260409020545b919050565b6109666004356024356000600034111561259957610002565b610966600062e6b680420360026000505410806106505750600354600160a060020a0390811633909116145b80156106645750600254621274ff19420190105b156126145750426002908155600180549091028155610983565b610966600435600a6020526000908152604090205481565b610966600435602435600060006000600060006000341115611ba157610002565b610a7d600854600160a060020a031681565b610966600c5481565b61096660005460001901610983565b61096660025481565b61096660043560006000600060003411156121fc57610002565b6109665b6001610983565b6109666004356024355b60115460009060ff16801561072f5750600f5442115b801561248757506124853361044b565b61096660115460ff1681565b6109666004355b60006000600f600050544210801561076a5750600034115b80156107a457506011546101009004600160a060020a0316600014806107a457506011546101009004600160a060020a0390811633909116145b15610b9f57610a9c61037f565b610a7d600435600060006000508281548110156100025750508080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56b600e83020180548290811015610002575081526020902060030154600160a060020a0316610606565b61096660043560243560006000610e1b336105ec565b6109665b6000600034111561247c57610002565b61096660043560056020526000908152604090205481565b610966600435602435604435600061252f845b6000600060003411156127ac57610002565b610966600435602435600160a060020a0382811660009081526015602090815260408083209385168352929052205461033f565b610a9a600435600034111561254557610002565b610966600435600b6020526000908152604090205481565b610a7d600354600160a060020a031681565b604080516020606435600481810135601f81018490048402850184019095528484526109669481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600034111561103257610002565b610a7d6011546101009004600160a060020a031681565b60408051918252519081900360200190f35b610980610708565b90505b90565b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b50509d505050505050505050505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b005b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f150505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c575060115460ff16155b15610b94576011805460ff1916600117905560165460408051918252517ff381a3e2428fdda36615919e8d9c35878d9eb0cf85ac6edf575088e80e4c147e9181900360200190a15b600191505b50919050565b610002565b600f5442118015610bb8575060115460ff16155b15610de357601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040516012549051600160a060020a039190911631109050610cc9576040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f19250505015610de35733600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a03168152602001908152602001600020600050819055505b565b4262054600600f60005054031115610e13576201518062127500600f60005054034203046014019050610983565b50601e610983565b60001415610e2857610002565b6000341115610e3657610002565b6000805485908110156100025750600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb05750600c810160205260406000205460ff165b80610ebf575060038101544210155b15610ec957610002565b8215610f0f5733600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b565b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff191660011790555b33600160a060020a03166000908152600b60205260408120541415610f77576040600020849055610feb565b33600160a060020a03166000908152600b60205260408120548154811015610002579080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb5733600160a060020a03166000908152600b602052604090208490555b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a35092915050565b6000805487908110156100025750808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816005016000505414915050949350505050565b600014156110ce57610002565b82801561111857508660001415806110e857508451600014155b806111005750600354600160a060020a038981169116145b8061110b5750600034115b80611118575062093a8084105b1561112257610002565b8215801561114257506111348861115c565b158061114257506212750084105b156111fe57610002565b83546118e590600160a060020a03165b600160a060020a03811660009081526004602052604081205460ff16806111f15750601254600160a060020a039081169083161480156111f15750601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051516006541190505b156129a157506001610606565b6249d40084111561120e57610002565b60115460ff1615806112215750600f5442105b806112365750600c5434108015611236575082155b1561124057610002565b42844201101561124f57610002565b30600160a060020a031633600160a060020a0316141561126e57610002565b60008054600181018083559091908280158290116112a557600e0281600e0283600052602060002091820191016112a5919061136a565b505060008054929450918491508110156100025750808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257805160ff19168380011785555b5061149292915061144a565b5050600060098201819055600a820155600d81018054600160a060020a03191690556001015b8082111561145e578054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057505b506000600383018190556004808401805461ffff19169055600584018290556006840182905560078401805460ff191690556008840180548382559083526020909220611344929091028101905b8082111561145e57600080825560018201818155600283019190915560039091018054600160a060020a03191690556113fc565b601f0160209004906000526020600020908101906113ae91905b8082111561145e576000815560010161144a565b5090565b82800160010185558215611338579182015b82811115611338578251826000505591602001919060010190611474565b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857600881018054600181018083559091908280158290116115735760040281600402836000526020600020918201910161157391906113fc565b505050505b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f150905090810190601f1680156116485780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2509695505050505050565b6040805186815260208101839052815189927fdfc78bdca8e3e0b18c16c5c99323c6cb9eb5e00afde190b4e7273f5158702b07928290030190a25b5050505092915050565b6000805488908110156100025750808052600e8802600080516020612a36833981519152019050600781015490945060ff166116e757620d2f006116ec565b622398805b600485015490935060ff16801561170857506003840154830142115b15611716576117b887611890565b600384015442108061172d5750600484015460ff16155b806117ae57508360000160009054906101000a9004600160a060020a03168460010160005054876040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020846005016000505414155b1561114c57610002565b61169e565b60048401805461ff001916610100179055835460019550600160a060020a03908116309091161480159061180157508354600754600160a060020a03908116911614155b801561181d57506008548454600160a060020a03908116911614155b801561183957508354601254600160a060020a03908116911614155b801561185557506003548454600160a060020a03908116911614155b1561188b5760018401805430600160a060020a031660009081526005602052604090208054919091019055546006805490910190555b611663875b6000600060005082815481101561000257908052600e02600080516020612a36833981519152018150600481015490915060ff16156118d757600d80546006830154900390555b600401805460ff1916905550565b15156118f45761190087611890565b6001915061193161047f565b604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050505061169e565b6001850154111561194157600091505b50600a8301546009840154865191019060049010801590611986575085600081518110156100025790602001015160f860020a900460f860020a02606860f860020a02145b80156119b6575085600181518110156100025790602001015160f860020a900460f860020a02603760f860020a02145b80156119e6575085600281518110156100025790602001015160f860020a900460f860020a0260ff60f860020a02145b8015611a16575085600381518110156100025790602001015160f860020a900460f860020a02601e60f860020a02145b8015611a45575030600160a060020a0316600090815260056020526040902054611a4290611a5d61047f565b81105b15611a4f57600091505b6001840154611a8090611a5f565b015b30600160a060020a03166000908152600560205260408120546129a961047f565b8110611ad457604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050501515611abc57610002565b4260025560165460059004811115611ad45760056001555b6001840154611ae290611a5f565b8110158015611af85750600a8401546009850154115b8015611b015750815b1561188b578360000160009054906101000a9004600160a060020a0316600160a060020a0316846001016000505487604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611b7d5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f19250505015156117bd57610002565b611baa336105ec565b60001415611bb757610002565b60008054889081101561000257508052600e87027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566810154600080516020612a36833981519152919091019450421080611c1957506003840154622398800142115b80611c3257508354600160a060020a0390811690871614155b80611c425750600784015460ff16155b80611c68575033600160a060020a03166000908152600b8501602052604090205460ff16155b80611c9c575033600160a060020a03166000908152600b60205260409020548714801590611c9c5750604060009081205414155b15611ca657610002565b600884018054600090811015610002579081526020812060030154600160a060020a03161415611e1257611efc86604051600090600160a060020a038316907f9046fefd66f538ab35263248a44217dcb70e2eb2cd136629e141b8b8f9f03b60908390a260408051600e547fe2faf044000000000000000000000000000000000000000000000000000000008252600160a060020a03858116600484015260248301859052604483018590526223988042016064840152925192169163e2faf04491608480820192602092909190829003018187876161da5a03f1156100025750506040515191506106069050565b6008850180546000908110156100025781815260208082209390935530600160a060020a031681526005909252604082205481549092908110156100025790815260208120905060020155601654600885018054600090811015610002579081526020812090506001015560048401805461ff0019166101001790555b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090505433600160a060020a031660009081526014602052604081205460088801805493909102939093049550908110156100025790815260208120905060030154604080517fbaac530000000000000000000000000000000000000000000000000000000000815233600160a060020a0390811660048301529151929091169163baac53009186916024808301926020929190829003018185886185025a03f11561000257505060405151600014159150611f78905057610002565b60088501805460009081101561000257818152602081206003018054600160a060020a03191690931790925580549091908110156100025790815260208120905060030154600160a060020a031660001415611f5757610002565b600d5430600160a060020a0316311015611f7057610002565b611d9561047f565b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090506002015433600160a060020a0390811660009081526014602090815260408083205430909416835260058083528184205460099093529083205460088b018054969095029690960497509487020494508593929091908290811015610002575260208120815060030154600160a060020a0390811682526020828101939093526040918201600090812080549095019094553016835260059091529020548290101561205357610002565b30600160a060020a031660009081526005602052604081208054849003905560088501805483926009929091829081101561000257508152602080822060030154600160a060020a039081168352929052604080822080549094019093553090911681522054819010156120c657610002565b30600160a060020a0390811660009081526009602090815260408083208054869003905533909316808352601482528383205484519081529351929390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36121383361086c565b5033600160a060020a03166000908152601460209081526040808320805460168054919091039055839055600a9091528120556001945061169e565b30600160a060020a0390811660008181526005602090815260408083208054958716808552828520805490970190965584845283905560099091528082208054948352908220805490940190935590815290555b50565b604051600160a060020a0382811691309091163190600081818185876185025a03f192505050151561217457610002565b33600160a060020a03818116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f028352935197995091969195929092169363d2cc718f936004848101949193929183900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a03168152602001908152602001600020600050540204101561229d57610002565b600160a060020a03338116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f02835293519296909593169363d2cc718f93600483810194929383900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a0316815260200190815260200160002060005054020403905083156123ec57600860009054906101000a9004600160a060020a0316600160a060020a0316630221038a83600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a031660048201526024810186905290516044808301935060209282900301816000876161da5a03f115610002575050604051511515905061245457610002565b6040805160085460e160020a63011081c5028252600160a060020a038581166004840152602483018590529251921691630221038a9160448082019260209290919082900301816000876161da5a03f115610002575050604051511515905061245457610002565b600160a060020a03331660009081526009602052604090208054909101905550600192915050565b6109803361086c565b155b80156124a257506124a23384845b6000600061293a856105ec565b80156124be57506124be83836000600034111561261c57610002565b15610b9f5750600161033f565b15156124d657610002565b6124e08383610719565b905061033f565b155b80156124fb57506124fb848484612495565b80156125185750612518848484600060003411156126c157610002565b15610b9f57506001612528565b90505b9392505050565b151561253a57610002565b61252584848461041b565b30600160a060020a031633600160a060020a031614158061258a575030600160a060020a031660009081526005602052604090205460649061258561047f565b010481115b1561259457610002565b600c55565b600354600160a060020a0390811633909116146125b557610002565b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f565b506000610983565b33600160a060020a03166000908152601460205260409020548290108015906126455750600082115b156126b957600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f565b50600061033f565b600160a060020a03841660009081526014602052604090205482901080159061270a5750601560209081526040600081812033600160a060020a03168252909252902054829010155b80156127165750600082115b156127a457600160a060020a03838116600081815260146020908152604080832080548801905588851680845281842080548990039055601583528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001612528565b506000612528565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f11561000257505060405151905061281a866105ec565b0204101561282757610002565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f115610002575050604051519050612895866105ec565b0204039050600760009054906101000a9004600160a060020a0316600160a060020a0316630221038a84836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061291357610002565b600160a060020a0383166000908152600a6020526040902080548201905560019150610b99565b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857610002565b600160a060020a038581166000908152600a60205260408082208054859003905591861681522080548201905560019150509392505050565b506000610606565b0160030260166000505483020460016000505460166000505404019050610606565b600160a060020a0383166000908152600b6020526040812054815481101561000257818052600e02600080516020612a368339815191520190506003810154909150421115610b9457600160a060020a0383166000908152600b602052604081208190559150610b9956290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000b656b2a9c3b2416437a811e07466ca712f5a5b5a",
- "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193",
- "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000057870858",
- "0x0000000000000000000000000000000000000000000000000000000000000011": "0x0000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c18941301",
- "0x0000000000000000000000000000000000000000000000000000000000000016": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b",
- "0x0421a2c4dbea98e8df669bb77238b62677daa210c5fbc46600627f90c03d0f08": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e571": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e572": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e573": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e574": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e575": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e576": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e577": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e578": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e579": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e57e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e57f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e580": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e581": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e582": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e583": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e584": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e585": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e586": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e587": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e58c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e58d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e58e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e58f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e590": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e591": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e592": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e593": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e594": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e595": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a1": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a2": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a3": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5aa": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ab": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ac": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ad": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ae": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5af": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b1": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b6": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ba": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5bb": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5bc": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5bd": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5be": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5bf": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c4": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c5": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c6": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ca": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5cb": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5cc": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5cd": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d2": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d3": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d4": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d5": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d6": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5da": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5db": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e1": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e2": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e3": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e4": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e5": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e6": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ee": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ef": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f1": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f2": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f3": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f4": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f5": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f6": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5fc": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x330b9432081afd3b64172d5df1f72ca72fc17e7e729ceb8b7529f91eee8b3f23": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x33f9bdb745e7edb1789dd1d68f40f693940aa8313b4f6bdc543be443dbc85e63": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x4830270ad35536baba417a92ea24656430586a37c90999b53c4d72ef1090cc9d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x4b16ba88f291613070529c10c8bdc41e973e2e2aa412ed92254cdca71ccfbc89": "0x00000000000000000000000000000000000000000001819451f999d617dafa76",
- "0x6546a4760869a51d07a75a31f00531836c32152c06dc88ac342da52fac5d939e": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492",
- "0x6796d25b854f17a11b940a9ff2822335f7d9bd1b85fbcd9d1f5cf742099d477a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x711886c99bc7a6e316551823dca012bd5b4381b57cec388f72c4b8105c1ed4ad": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x74024021ec74dc59b0fa1b66e9f430163a5e1128785ec9495f9686628ca7cc2b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x79a0e9ff42282e7cbcb539e164f024ab90021633de05f600fff6d16305888d26": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x81ffe0a69ee20c37e3f3ba834da8b20475846fcde1f4a39fdfc628a2560076aa": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8f85b96a91f601f62149f5dd6a35d6168f6de5bc047a18e3cf7b97a3843c6ffd": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x946f68a04a200ebe87f2f896f7f6c08f4e22813db910c8a6d6abf17611ce3ffb": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x9c1ad2f16775f94ffd360e8bc716f86016a3fcf90992b5b4f3312353efd1bd61": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xa66ae63934365a757bf33d70ca0a28352da4c2fe6cb147bf29d69fbea3a706e0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xa7653edcf1403f7ce2f75784d5f34ca5f57ff110bd0c3abbdcc5a84f101dc83a": "0x00000000000000000000000000000000000000000001819451f999d617dafa93",
- "0xa87317e3ffd5ed16f357bd31427bd97cbb35fc51ad1e00feec89bdfe82c5dba4": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xaa535eb427f7963e49601f9032ee6b62a9f72b6b3c610a5f11faf8dc68a97e2a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xaade287f2b81ac58dcc6ee0c381cde85b6aa7a9a769be73605f1af9453a340a0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xb56a086d82c3921c13c13d1d53f18bbbe36d9d1c4862be8339a5171feb94c164": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xb6ab9f1541f42dc4feba15ccd18bc3af7c8f99cafb184ab65539883a68c7a1a9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xbad9e5f7dc3001078ea6433993a2f145c2ef9af1c5137a35e9c173c208990249": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xc319152db8781ef1f12090aad94325d650e39c8a20285c7e02959817118f3f28": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xde65b6d76ea4a5547af9707e6e099bba6f16dbc7b5cf97fb8fedc82583b38de0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xdf71c8506c3cf85e2e677b60ec28fe60eb820775001bdce289e3253f304f22e8": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x4fd27b205895e698fa350f7ea57cec8a21927fcd": {
- "balance": "0x0",
- "nonce": "11",
- "code": "0x606060405236156100f05760e060020a600035046303afc23581146100f257806313af403514610114578063186ef962146101365780632e64cec11461015857806331962cdc146101d2578063365a86fc146101f45780634162169f146102065780634dfc3db61461021857806365f13792146102585780636637b88214610441578063715d832f146104625780637452c2e61461048457806386c9b536146105005780638da5cb5b14610512578063975057e714610524578063a8618f711461059f578063d0679d341461061b578063d1c3c84a14610698578063d9d35966146106aa578063f3273907146106c9575b005b6100f0600435600054600160a060020a03908116339091161461072e57610002565b6100f0600435600054600160a060020a03908116339091161461074457610002565b6100f0600435600054600160a060020a03908116339091161461075957610002565b6100f06000805481908190600160a060020a0390811633909116148015906101905750600154600160a060020a039081163390911614155b80156101ac5750600254600160a060020a039081163390911614155b80156101c85750600354600160a060020a039081163390911614155b1561076e57610002565b6100f0600435600054600160a060020a039081163390911614610a5d57610002565b6106eb600154600160a060020a031681565b6106eb600454600160a060020a031681565b61070860008054600160a060020a03908116339091161480159061024c5750600154600160a060020a039081163390911614155b15610a72575060015b90565b6107086004355b600060006000600060006000600460009054906101000a9004600160a060020a0316600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150945084600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604080518051600480547f81f03fcb000000000000000000000000000000000000000000000000000000008452600160a060020a038d81169285019290925293519198509290921692506381f03fcb916024828101926020929190829003018187876161da5a03f115610002575050604080518051600480547f18160ddd0000000000000000000000000000000000000000000000000000000084529351919750600160a060020a039390931693506318160ddd92828101926020929190829003018187876161da5a03f1156100025750506040805180516004805460e060020a6370a08231028452600160a060020a038d81169285019290925293519196509290921692506370a08231916024828101926020929190829003018187876161da5a03f11561000257505060405151909402919091049695505050505050565b6100f060043560005433600160a060020a03908116911614610ad957610002565b6100f06004356000805433600160a060020a03908116911614610aff57610002565b61071a600435600080548190819033600160a060020a039081169116148015906104be5750600154600160a060020a039081163390911614155b80156104da5750600254600160a060020a039081163390911614155b80156104f65750600354600160a060020a039081163390911614155b15610be657610002565b6106eb600354600160a060020a031681565b6106eb600054600160a060020a031681565b6100f06000805481908190819033600160a060020a0390811691161480159061055d5750600154600160a060020a039081163390911614155b80156105795750600254600160a060020a039081163390911614155b80156105955750600354600160a060020a039081163390911614155b15610c4457610002565b61071a6004355b60006000600460009054906101000a9004600160a060020a0316600160a060020a03166381f03fcb846040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519150610da490508361025f565b61071a60043560243560008054819033600160a060020a039081169116148015906106565750600154600160a060020a039081163390911614155b80156106725750600254600160a060020a039081163390911614155b801561068e5750600354600160a060020a039081163390911614155b15610dac57610002565b6106eb600254600160a060020a031681565b6100f06000805433600160a060020a03908116911614610ec457610002565b6106eb6004356000805433600160a060020a03908116911614610fd357610002565b60408051600160a060020a03929092168252519081900360200190f35b60408051918252519081900360200190f35b604080519115158252519081900360200190f35b60038054600160a060020a031916821790555b50565b60008054600160a060020a0319168217905550565b60028054600160a060020a0319168217905550565b30925061077a836105a6565b1561082557600480546006546040805160e060020a6370a08231028152600160a060020a038881169582019590955290519284169363a9059cbb9392169184916370a0823191602482810192602092919082900301816000876161da5a03f11561000257505060408051805160e060020a63a9059cbb02825260048201949094526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b600091505b6005548210156108f45760058054600454600160a060020a0316916370a0823191859081101561000257600091825260408051600080516020611089833981519152929092015460e060020a6370a08231028352600160a060020a0316600483015251602482810193602093839003909101908290876161da5a03f115610002575050604051519150506000811115610a51576108f96005600050838154811015610002576000919091526000805160206110898339815191520154600160a060020a03166105a6565b505050565b15156109c25760058054600454600160a060020a0316916323b872dd918590811015610002575060009081526040805160008051602061108983398151915287015460e060020a6323b872dd028252600160a060020a03908116600483015230166024820152604481018690529051606482810193602093839003909101908290876161da5a03f1156100025750506040805183815290517f92da44f6982cd1ca7a9c851f8c39b26c80c235d7bb9fd59bce334fa634a1728b92509081900360200190a1610a51565b60058054600454600160a060020a0316916323b872dd918590811015610002575060009081526006546040805160008051602061108983398151915288015460e060020a6323b872dd028252600160a060020a0390811660048301529290921660248301526044820186905251606482810193602093839003909101908290876161da5a03f115610002575050505b6001919091019061082a565b60018054600160a060020a0319168217905550565b600454600160a060020a031660001415610a8e57506002610255565b600354600160a060020a031660001415610aaa57506003610255565b600254600160a060020a031660001415610ac657506004610255565b6005546000141561025557506005610255565b6005546000901115610aea57610002565b60048054600160a060020a0319168217905550565b5060005b81811015610b5a57600580546001818101808455930192909190828015829011610b5e576000839052610b5e906000805160206110898339815191529081019083015b80821115610bd65760008155600101610b46565b5050565b5050604051600454600160a060020a0316925090506082806110078339018082600160a060020a03168152602001915050604051809103906000f06005805460001981019081101561000257600091909152600080516020611089833981519152018054600160a060020a0319169091179055610b03565b5090565b600092505b5050919050565b600091505b600554821015610bda57600580548390811015610002576000919091526000805160206110898339815191520154600160a060020a0390811691508416811415610c385760019250610bdf565b60019190910190610beb565b600460009054906101000a9004600160a060020a0316600160a060020a03166370a08231306040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519450506000841415610cbb575b50505050565b600554600093506004900460010191505b81831015610cb557506005805460045442850182900692600160a060020a03919091169163a9059cbb9190849081101561000257600091825260408051600080516020611089833981519152929092015460e060020a63a9059cbb028352600160a060020a03166004830152868904602483015251604482810193602093839003909101908290876161da5a03f11561000257505060408051848704815290517fc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b92509081900360200190a160019290920191610ccc565b901192915050565b600460009054906101000a9004600160a060020a0316600160a060020a03166370a08231306040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191505082811015610e5f57604080516020810185905281517f703690365b2d63b5b9ec4471a919cdd5924f745170399a5d24927fd07d81a04d929181900390910190a1600091505b5092915050565b604080516004805460e060020a63a9059cbb028352600160a060020a038881169284019290925260248301879052925192169163a9059cbb9160448082019260209290919082900301816000876161da5a03f115610002575060019350610e58915050565b600480546006546040805160e060020a6370a08231028152600160a060020a0392831694810194909452519116916370a0823191602482810192602092919082900301816000876161da5a03f11561000257505060405151915050600081111561074157604080516004805460065460e060020a6323b872dd028452600160a060020a039081169284019290925230821660248401526044830185905292519216916323b872dd9160648181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150507f32e95f921f72e9e736ccad1cc1c0ef6e3c3c08204eb74e9ee4ae8f98e195e3f0816040518082815260200191505060405180910390a150565b600580548390811015610002576000919091526000805160206110898339815191520154600160a060020a03169291505056006060604052604051602080608283396080604081905291517f095ea7b3000000000000000000000000000000000000000000000000000000008352600160a060020a0333811660845260001960a4819052919384939184169163095ea7b39160c491906044816000876161da5a03f115600257505033600160a060020a03169050ff036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000000000000000000000000000000000000000000000a",
- "0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db6": "0x0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf30",
- "0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db7": "0x0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a2",
- "0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db8": "0x000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b"
- }
- },
- "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f": {
- "balance": "0x0",
- "code": "0x606060405236156100da5760e060020a600035046303afc23581146100dc57806309f180f9146100fe5780630a39ce021461016c57806310aa1caa146101a057806313af40351461021e57806331962cdc14610240578063365a86fc146102625780634162169f146102745780634dfc3db6146102865780636637b882146102c65780636de45dee146102e85780638da5cb5b146103285780639137c1a71461033a578063b199efb51461035c578063b3a69f861461036e578063d5d7ff3c1461040b578063d95f98ce1461044b578063fe39084c146104b5575b005b6100da600435600054600160a060020a0390811633909116146104f657610002565b6104c76004355b6002546040805160e060020a6381f03fcb028152600160a060020a0384811660048301529151600093849384939116916381f03fcb91602481810192602092909190829003018187876161da5a03f1156100025750506040515192506105199050846101a7565b6104d960043560068054829081101561000257506000526000805160206110cf8339815191520154600160a060020a031681565b6104c76004355b604080516003547f65f13792000000000000000000000000000000000000000000000000000000008252600160a060020a038481166004840152925160009391909116916365f13792916024828101926020929190829003018187876161da5a03f115610002575050604051516001019392505050565b6100da600435600054600160a060020a03908116339091161461052c57610002565b6100da600435600054600160a060020a03908116339091161461054157610002565b6104d9600154600160a060020a031681565b6104d9600254600160a060020a031681565b6104c760008054600160a060020a0390811633909116148015906102ba5750600154600160a060020a039081163390911614155b15610556575060015b90565b6100da600435600054600160a060020a03908116339091161461063c57610002565b6100da600435600054600160a060020a03908116339091161480159061031e5750600154600160a060020a039081163390911614155b1561065157610002565b6104d9600054600160a060020a031681565b6100da600435600054600160a060020a03908116339091161461081b57610002565b6104d9600354600160a060020a031681565b6104c75b6000805b6006548110156108175760068054600254600160a060020a0316916370a08231918490811015610002576000918252604080516000805160206110cf833981519152929092015460e060020a6370a08231028352600160a060020a0316600483015251602482810193602093839003909101908290876161da5a03f11561000257505060405151929092019150600101610376565b6100da6004356000805433600160a060020a039081169116148015906104415750600154600160a060020a039081163390911614155b1561083057610002565b6100da60006000600060006000600060006000600060006000600060009054906101000a9004600160a060020a0316600160a060020a031633600160a060020a0316141580156104ab5750600154600160a060020a039081163390911614155b1561092d57610002565b6104d9600454600160a060020a031681565b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b60048054600160a060020a031916821790555b50565b81810392505b5050919050565b90508082111561050c5760009250610512565b60008054600160a060020a0319168217905550565b60018054600160a060020a0319168217905550565b600254600160a060020a031660001415610572575060026102c3565b600354600160a060020a03166000141561058e575060036102c3565b600354604080517fd1c3c84a000000000000000000000000000000000000000000000000000000008152905130600160a060020a0390811693169163d1c3c84a91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a0316909114905061060d575060046102c3565b60065460001415610620575060056102c3565b600454600160a060020a0316600014156102c3575060066102c3565b60028054600160a060020a0319168217905550565b6106ab816000805b6006548110156110bc5782600160a060020a03166006600050828154811015610002576000919091526000805160206110cf8339815191520154600160a060020a031614156110c757600191506110c1565b156106b557610509565b600354604080517f7452c2e6000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015291519290911691637452c2e69160248181019260209290919082900301816000876161da5a03f1156100025750506040515115905061072d57610509565b30600160a060020a031681600160a060020a0316148061075b5750600354600160a060020a03908116908216145b806107745750600154600160a060020a03908116908216145b1561077e57610509565b60068054600181018083559091908280158290116107bf578183600052602060002091820191016107bf91905b8082111561081757600081556001016107ab565b505060068054849350909150600019810190811015610002575080546000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3e018054600160a060020a031916909117905550565b5090565b60038054600160a060020a0319168217905550565b5060005b6006548110156109215781600160a060020a03166006600050828154811015610002576000919091526000805160206110cf8339815191520154600160a060020a0316141561092557600680546000198101908110156100025760009182526000805160206110cf83398151915201909054906101000a9004600160a060020a03166006600050828154811015610002576000805160206110cf833981519152018054600160a060020a0319169092179091558054600019810180835590919082801582901161091c5761091c906000805160206110cf8339815191529081019083016107ab565b505050505b5050565b600101610834565b6002546040805160e060020a6381f03fcb02815230600160a060020a0381811660048401529251909e5092909116916381f03fcb9160248181019260209290919082900301816000876161da5a03f115610002575050604051519a505060008a14156109c1576040517f044c61dab36644651a1f82d87d6494a3a6450a6edde20b9baf45e374fb2d0bb990600090a1610e04565b6109c9610372565b6040805160025460e060020a6370a08231028252600160a060020a038f811660048401529251939c50909116916370a082319160248181019260209290919082900301816000876161da5a03f115610002575050604051519850606497505086881015610ade57604080516003547fd0679d34000000000000000000000000000000000000000000000000000000008252600160a060020a038e811660048401528b8b036024840152925192169163d0679d349160448082019260209290919082900301816000876161da5a03f1156100025750506040515115159050610ad8576040517f044c61dab36644651a1f82d87d6494a3a6450a6edde20b9baf45e374fb2d0bb990600090a1610e04565b86975087505b600095505b600654861015610b2457610d8e6006600050878154811015610002576000919091526000805160206110cf8339815191520154600160a060020a0316610105565b6040805160025460e060020a6381f03fcb028252600160a060020a038e8116600484015292519216916381f03fcb9160248181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001509250600260009054906101000a9004600160a060020a0316600160a060020a03166370a082318c6040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f11561000257505060405151600097509250505b600654861015610e045760068054600254600160a060020a0316916370a082319189908110156100025760009182526000805160206110cf83398151915201546040805160e060020a6370a08231028152600160a060020a0392909216600483015251602482810193602093839003909101908290876161da5a03f115610002575050604051518084028b900495509150506000841115610d82577ff340c079d598119636d42046c6a2d2faf7a68c04aecee516f0e0b8a9e79b86666006600050878154811015610002576000919091526000805160206110cf833981519152015460408051600160a060020a03929092168252602082018790528386048c900482820152519081900360600190a160025460068054600160a060020a03929092169163a9059cbb919089908110156100025760009182526000805160206110cf83398151915201546040805160e060020a63a9059cbb028152600160a060020a039290921660048301526024820189905251604482810193602093839003909101908290876161da5a03f115610002575050505b60019590950194610bed565b9450898589020493508760001415610e11577fdb0f19c627ca59a2db73b1e1e8c4853f34a58afa92b29331e56c75144fa0c84c6006600050878154811015610002576000919091526000805160206110cf833981519152015460408051600160a060020a03929092168252519081900360200190a15b5050505050505050505050565b87841115610e84577f211d59fc569e166e12f7ca82135d85b1f178f636fefe40d168f0113cf07f818f6006600050878154811015610002576000919091526000805160206110cf833981519152015460408051600160a060020a03929092168252519081900360200190a1879350610ee8565b7f4b0bc4f25f8d0b92d2e12b686ba96cd75e4e69325e6cf7b1f3119d14eaf2cbdf6006600050878154811015610002576000919091526000805160206110cf833981519152015460408051600160a060020a03929092168252519081900360200190a15b60008411156110b05760068054998501997ff340c079d598119636d42046c6a2d2faf7a68c04aecee516f0e0b8a9e79b86669190889081101561000257600091909152604080516000805160206110cf8339815191529290920154600160a060020a0316825260208201879052818101889052519081900360600190a160025460068054600160a060020a03929092169163a9059cbb91908990811015610002576000918252604080516000805160206110cf833981519152929092015460e060020a63a9059cbb028352600160a060020a031660048301526024820189905251604482810193602093839003909101908290876161da5a03f1156100025750506040805160025460e060020a6370a08231028252600160a060020a038f811660048401529251921692506370a0823191602482810192602092919082900301816000876161da5a03f115610002575050506040518051906020015097508750600260009054906101000a9004600160a060020a0316600160a060020a03166381f03fcb8c6040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519a50505b60019590950194610ae3565b600091505b50919050565b60010161065956f652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526"
- }
- },
- "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc": {
- "balance": "0x4563918244f400000",
- "code": "0x606060405236156100da5760e060020a600035046313af40358114610145578063186ef9621461016757806331962cdc14610189578063365a86fc146101ab5780634162169f146101bd57806348c981e2146101cf5780634dfc3db61461020f57806361bc221a146102505780636637b882146102595780636c0e29601461027b5780638da5cb5b146104795780638f2b29a71461048b5780639137c1a714610602578063b199efb514610624578063b826c4fd14610636578063d1c3c84a1461063f578063d2f0ad9214610651578063fc340716146106bf575b6107236002546040805160e060020a630e7082030281529051600092600160a060020a031691630e708203916004828101926020929190829003018187876161da5a03f1156100025750506040515133600160a060020a039081169116149050610737575060015b90565b610861600435600054600160a060020a03908116339091161461089257610002565b610861600435600054600160a060020a0390811633909116146108a757610002565b610861600435600054600160a060020a0390811633909116146108bc57610002565b610863600154600160a060020a031681565b610863600254600160a060020a031681565b610861600435600054600160a060020a0390811633909116148015906102055750600154600160a060020a039081163390911614155b156108d157610002565b61088060008054600160a060020a0390811633909116148015906102435750600154600160a060020a039081163390911614155b156108fa57506001610142565b61088060055481565b610861600435600054600160a060020a0390811633909116146109e857610002565b6108805b6000600060006000600060006000600060006000600260009054906101000a9004600160a060020a0316600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150985088600160a060020a03163130600160a060020a03163101975088600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160025460035460e060020a6381f03fcb028452600160a060020a0390811660048501529351919b5090921692506381f03fcb916024828101926020929190829003018187876161da5a03f11561000257505060408051805160025460e060020a6318160ddd0283529251909950600160a060020a039290921692506318160ddd916004828101926020929190829003018187876161da5a03f11561000257505060408051805160025460035460e060020a6370a08231028452600160a060020a039081166004850152935191995090921692506370a08231916024828101926020929190829003018187876161da5a03f115610002575050506040518051906020015093508784860202925088600160a060020a03163188880103840291508585029050808210156109fd57610a05565b610863600054600160a060020a031681565b61088060043560006000600060006000600260009054906101000a9004600160a060020a0316600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150935083600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051600254815160035460e060020a6381f03fcb028452600160a060020a0390811660048501529351909750921692506381f03fcb916024808301926020929190829003018187876161da5a03f11561000257505060408051805160025460e060020a6318160ddd0283529251909550600160a060020a039290921692506318160ddd916004828101926020929190829003018187876161da5a03f115610002575050506040518051906020015090508581038183020486820387850204039450845084945050505050919050565b610861600435600054600160a060020a039081163390911614610a1157610002565b610863600354600160a060020a031681565b61088060065481565b610863600454600160a060020a031681565b6108806004355b6040805160025460035460e060020a6370a08231028352600160a060020a039081166004840152925160009384939216916370a08231916024828101926020929190829003018187876161da5a03f115610002575050604051519093046001019392505050565b61086160006000600060006000600060006000600060009054906101000a9004600160a060020a0316600160a060020a031633600160a060020a0316141580156107195750600154600160a060020a039081163390911614155b15610cbc57610002565b604080519115158252519081900360200190f35b600654600554600019909101901115610803576040805160025460035460e060020a6370a0823102835230600160a060020a03908116600485015293519184169363a9059cbb9391169160019185916370a082319160248082019260209290919082900301816000876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600482019590955260001994909401602485015251604480850194602094509192509082900301816000876161da5a03f115610002575060019250610142915050565b6005805460010190556040805160025460e160020a63664d71fb0282529151600160a060020a03929092169163cc9ae3f69160048181019260209290919082900301816000876161da5a03f115610002575060019250610142915050565b005b60408051600160a060020a03929092168252519081900360200190f35b60408051918252519081900360200190f35b60008054600160a060020a0319168217905550565b60048054600160a060020a0319168217905550565b60018054600160a060020a0319168217905550565b604051600160a060020a0382811691309091163190600081818185876185025a03f15050505050565b600254600160a060020a03166000141561091657506002610142565b600354600160a060020a03166000141561093257506003610142565b600454600160a060020a03166000141561094e57506004610142565b600354604080517f86c9b536000000000000000000000000000000000000000000000000000000008152905130600160a060020a039081169316916386c9b53691600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a031690911490506109cd57506005610142565b30600160a060020a0316316000141561014257506006610142565b60028054600160a060020a0319168217905550565b808203830499505b50505050505050505090565b60038054600160a060020a0319168217905550565b6006819055600354604080517fd0679d34000000000000000000000000000000000000000000000000000000008152600160a060020a038981166004830152938b04602482018190529151919750919092169163d0679d349160448181019260209290919082900301816000876161da5a03f11561000257505060408051600160055530600160a060020a031631815290517f7027eecbd2a688fc1fa281702b311ed7168571514adfd17014a55d828cb4338292509081900360200190a1604051600160a060020a0389811691309091163190600081818185876185025a03f15050604080517fd2cc718f000000000000000000000000000000000000000000000000000000008152905163d2cc718f9250600482810192602092919082900301816000876161da5a03f11561000257505060408051805160025460e060020a6370a08231028352600160a060020a038a81166004850152935191975090921692506370a0823191602482810192602092919082900301816000876161da5a03f11561000257505060408051805160025460e060020a6381f03fcb028352600160a060020a038a81166004850152935191965090921692506381f03fcb91602482810192602092919082900301816000876161da5a03f11561000257505060408051805160025460e160020a63664d71fb0283529251909450600160a060020a0392909216925063cc9ae3f691600482810192602092919082900301816000876161da5a03f115610002575050604080516002546004805460e060020a63a9059cbb028452600160a060020a03908116918401919091526001602484015292519216925063a9059cbb91604482810192602092919082900301816000876161da5a03f115610002575050505b5050505050505050565b6002546040805160e060020a630e7082030281529051600160a060020a0390921691630e7082039160048181019260209290919082900301816000876161da5a03f115610002575050604051519850610d15905061027f565b60408051600160a060020a038b1631815290519198507f07cf7e805770612a8b2ee8e0bcbba8aa908df5f85fbc4f9e2ef384cf75315038919081900360200190a187600160a060020a03163130600160a060020a0316310195508660001480610d7e5750856000145b15610db1576040517f30090d86c52e12fbc1213c1ecf7e193d6ce4a5c838c8c41d06c1a9daea8a2cec90600090a1610cb2565b309450610a268761065856",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b": {
- "balance": "0x0",
- "code": "0x606060405236156100985760e060020a6000350463013cf08b811461009a57806313af4035146100d757806331962cdc146100f9578063365a86fc1461011b578063400e39491461012d5780634162169f146101375780634dfc3db6146101495780636637b8821461018a5780638da5cb5b146101ac578063e66f53b7146101be578063e90956cf146101d0578063ff2f4bd2146101f2575b005b61024460043560048054829081101561000257506000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b015481565b610098600435600054600160a060020a03908116339091161461026157610002565b610098600435600054600160a060020a03908116339091161461027657610002565b61024e600154600160a060020a031681565b6102446004545b90565b61024e600254600160a060020a031681565b61024460008054600160a060020a03908116339091161480159061017d5750600154600160a060020a039081163390911614155b1561028b57506001610134565b610098600435600054600160a060020a0390811633909116146102c157610002565b61024e600054600160a060020a031681565b61024e600354600160a060020a031681565b610098600435600054600160a060020a0390811633909116146102d657610002565b6100986000606081815260a06040526080828152825491929091819033600160a060020a0390811691161480159061023a5750600154600160a060020a039081163390911614155b1561031857610002565b6060908152602090f35b600160a060020a03166060908152602090f35b60008054600160a060020a0319168217905550565b60018054600160a060020a0319168217905550565b600254600160a060020a03168114156102a657506002610134565b600354600160a060020a031681141561013457506003610134565b60028054600160a060020a0319168217905550565b60038054600160a060020a0319168217905550565b50508054839250600019810190811015610002579060005260206000209001600050819055505b50505050565b6002547f70a082310000000000000000000000000000000000000000000000000000000060a090815230600160a060020a0390811660a45291909116906370a082319060c49060209060248187876161da5a03f11561000257505060405151821415905061038557610312565b60006040518059106103945750595b9080825280602002602001820160405250935062093a809150600260009054906101000a9004600160a060020a0316600160a060020a031663612e45a3600360009054906101000a9004600160a060020a0316600086888760016040518760e060020a0281526004018087600160a060020a03168152602001868152602001806020018060200185815260200184151581526020018381038352878181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156104815780820380516001836020036101000a031916815260200191505b508381038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156104da5780820380516001836020036101000a031916815260200191505b50985050505050505050506020604051808303816000876161da5a03f1156100025750506040515160048054600181018083559294509250908280158290116102eb578183600052602060002091820191016102eb91905b808211156105465760008155600101610532565b509056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a1": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a2": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a3": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a4": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0xad3ecf23c0c8983b07163708be6d763b5f056193": {
- "balance": "0x0",
- "code": "0x606060405236156100405760e060020a60003504630221038a811461004d57806318bdc79a146100aa5780638da5cb5b146100be578063d2cc718f146100d0575b6100d96001805434019055565b6100db6004356024356000805433600160a060020a0390811691161415806100755750600034115b806100a05750805460a060020a900460ff1680156100a057508054600160a060020a03848116911614155b156100f757610002565b6100db60005460ff60a060020a9091041681565b6100ed600054600160a060020a031681565b6100db60015481565b005b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a0383168260608381818185876185025a03f1925050501561015c57604080518381529051600160a060020a038516917f9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc919081900360200190a25060015b9291505056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b": {
- "balance": "0x167d285b38143c04f",
- "nonce": "68"
- },
- "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89": {
- "balance": "0x9651c71936",
- "code": "0x606060405236156100b95760e060020a600035046313af4035811461019e57806326f5a8c9146101c1578063371fa854146101ca5780634162169f146101d35780634c8fe526146101e55780635970c915146101f757806361bc221a14610209578063625e847d146102125780636637b882146102325780637f9f519f146102555780638da5cb5b14610278578063a9059cbb1461028a578063c4463c80146102b0578063c9d27afe146102df578063e66f53b714610305575b6103176002547f0e708203000000000000000000000000000000000000000000000000000000006060908152600091600160a060020a031690630e7082039060649060209060048187876161da5a03f1156100025750506040515133600160a060020a039081169116149050610329576040805133600160a060020a03166020820152818152600f818301527f636f6e73747563746f72206661696c0000000000000000000000000000000000606082015290517fa6af7265d7ede5fbf0ee375956b52b362800d4f92e268809bef5fdf2a57924b89181900360800190a15060015b90565b61031760043560008054600160a060020a03908116339091161461049257610002565b61047560055481565b61047560045481565b61047f600254600160a060020a031681565b61047f600654600160a060020a031681565b61047f600754600160a060020a031681565b61047560035481565b61031760008054600160a060020a0390811633909116146104ef57610002565b61031760043560008054600160a060020a03908116339091161461057a57610002565b61031760043560008054600160a060020a0390811633909116146105d757610002565b61047f600054600160a060020a031681565b61031760043560243560008054600160a060020a03908116339091161461060f57610002565b61031760043560243560443560643560843560008054600160a060020a0390811633909116146106a657610002565b61031760043560243560008054600160a060020a0390811633909116146107bb57610002565b61047f600154600160a060020a031681565b60408051918252519081900360200190f35b60055460035460001990910190111561040257604080516002546006547f70a0823100000000000000000000000000000000000000000000000000000000835230600160a060020a03908116600485015293519184169363a9059cbb9391169184916370a0823191602480830192602092919082900301818a876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600482019490945260248101939093525160448084019360209350829003018187876161da5a03f11561000257505060016003819055915061019b9050565b6040805160038054600190810190915560025460048054925460e260020a632099877102855290840192909252600160a060020a03918216602484015292519216916382661dc491604480820192602092909190829003018187876161da5a03f11561000257506001925061019b915050565b6060908152602090f35b600160a060020a03166060908152602090f35b600160a060020a03821660609081527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc90602090a181600060006101000a815481600160a060020a0302191690830217905550600190505b919050565b6001600355600754600160a060020a03908116908290301631606082818181858883f15050604080516002546001546004805460e260020a632099877102855290840152600160a060020a0390811660248401529251921694506382661dc493506044808201935060209291829003018187876161da5a03f11561000257506001925061019b915050565b6002805473ffffffffffffffffffffffffffffffffffffffff1916831790819055600160a060020a031660609081527fce6a5015a40a2ec38ce912a63bca374d85386207c6927d284292449f1431082290602090a15060016104ea565b600582905560608281527fbab6859bc098da798dbdc4860f0fee7467d703dadd975799e8c258b46a37d3de90602090a15060016104ea565b60025460e060020a63a9059cbb026060908152600160a060020a0385811660645260848590529091169063a9059cbb9060a49060209060448187876161da5a03f11561000257505060408051600160a060020a03861681526020810185905281517f69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de293509081900390910190a15060015b92915050565b6006805473ffffffffffffffffffffffffffffffffffffffff1990811686179091556001600381905580548216871790556004879055600584905560078054909116831790819055600160a060020a03908116908290301631606082818181858883f15050604080516002546004805460015460e260020a632099877102855291840152600160a060020a0390811660248401529251921694506382661dc493506044808201935060209291829003018187876161da5a03f11561000257505060408051600454600654908252600160a060020a0316602082015281517fa1ab731770d71027cd294cc0af5c8f5ec3c2ff5dbe6b75d68963d17192f8377b93509081900390910190a150600195945050505050565b6002547fc9d27afe0000000000000000000000000000000000000000000000000000000060609081526064859052831515608452600160a060020a039091169063c9d27afe9060a49060209060448187876161da5a03f11561000257505060408051858152841515602082015281517f8bfa1f40665434b48e7becc865cc0586ce3d6d2388521c05d4db87536ac8279993509081900390910190a15060016106a056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490"
- }
- },
- "0xea674fdde714fd979de3edf0f56aa9716b898ec8": {
- "balance": "0x4ab3566739e7b24371",
- "nonce": "286339"
- },
- "0xf835a0247b0063c04ef22006ebe57c5f11977cc4": {
- "balance": "0x9645db5736",
- "code": "0x606060405236156100b95760e060020a600035046313af4035811461019e57806326f5a8c9146101c1578063371fa854146101ca5780634162169f146101d35780634c8fe526146101e55780635970c915146101f757806361bc221a14610209578063625e847d146102125780636637b882146102325780637f9f519f146102555780638da5cb5b14610278578063a9059cbb1461028a578063c4463c80146102b0578063c9d27afe146102df578063e66f53b714610305575b6103176002547f0e708203000000000000000000000000000000000000000000000000000000006060908152600091600160a060020a031690630e7082039060649060209060048187876161da5a03f1156100025750506040515133600160a060020a039081169116149050610329576040805133600160a060020a03166020820152818152600f818301527f636f6e73747563746f72206661696c0000000000000000000000000000000000606082015290517fa6af7265d7ede5fbf0ee375956b52b362800d4f92e268809bef5fdf2a57924b89181900360800190a15060015b90565b61031760043560008054600160a060020a03908116339091161461049257610002565b61047560055481565b61047560045481565b61047f600254600160a060020a031681565b61047f600654600160a060020a031681565b61047f600754600160a060020a031681565b61047560035481565b61031760008054600160a060020a0390811633909116146104ef57610002565b61031760043560008054600160a060020a03908116339091161461057a57610002565b61031760043560008054600160a060020a0390811633909116146105d757610002565b61047f600054600160a060020a031681565b61031760043560243560008054600160a060020a03908116339091161461060f57610002565b61031760043560243560443560643560843560008054600160a060020a0390811633909116146106a657610002565b61031760043560243560008054600160a060020a0390811633909116146107bb57610002565b61047f600154600160a060020a031681565b60408051918252519081900360200190f35b60055460035460001990910190111561040257604080516002546006547f70a0823100000000000000000000000000000000000000000000000000000000835230600160a060020a03908116600485015293519184169363a9059cbb9391169184916370a0823191602480830192602092919082900301818a876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600482019490945260248101939093525160448084019360209350829003018187876161da5a03f11561000257505060016003819055915061019b9050565b6040805160038054600190810190915560025460048054925460e260020a632099877102855290840192909252600160a060020a03918216602484015292519216916382661dc491604480820192602092909190829003018187876161da5a03f11561000257506001925061019b915050565b6060908152602090f35b600160a060020a03166060908152602090f35b600160a060020a03821660609081527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc90602090a181600060006101000a815481600160a060020a0302191690830217905550600190505b919050565b6001600355600754600160a060020a03908116908290301631606082818181858883f15050604080516002546001546004805460e260020a632099877102855290840152600160a060020a0390811660248401529251921694506382661dc493506044808201935060209291829003018187876161da5a03f11561000257506001925061019b915050565b6002805473ffffffffffffffffffffffffffffffffffffffff1916831790819055600160a060020a031660609081527fce6a5015a40a2ec38ce912a63bca374d85386207c6927d284292449f1431082290602090a15060016104ea565b600582905560608281527fbab6859bc098da798dbdc4860f0fee7467d703dadd975799e8c258b46a37d3de90602090a15060016104ea565b60025460e060020a63a9059cbb026060908152600160a060020a0385811660645260848590529091169063a9059cbb9060a49060209060448187876161da5a03f11561000257505060408051600160a060020a03861681526020810185905281517f69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de293509081900390910190a15060015b92915050565b6006805473ffffffffffffffffffffffffffffffffffffffff1990811686179091556001600381905580548216871790556004879055600584905560078054909116831790819055600160a060020a03908116908290301631606082818181858883f15050604080516002546004805460015460e260020a632099877102855291840152600160a060020a0390811660248401529251921694506382661dc493506044808201935060209291829003018187876161da5a03f11561000257505060408051600454600654908252600160a060020a0316602082015281517fa1ab731770d71027cd294cc0af5c8f5ec3c2ff5dbe6b75d68963d17192f8377b93509081900390910190a150600195945050505050565b6002547fc9d27afe0000000000000000000000000000000000000000000000000000000060609081526064859052831515608452600160a060020a039091169063c9d27afe9060a49060209060448187876161da5a03f11561000257505060408051858152841515602082015281517f8bfa1f40665434b48e7becc865cc0586ce3d6d2388521c05d4db87536ac8279993509081900390910190a15060016106a056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490"
- }
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "1881284",
- "difficulty": "59917798852808",
- "timestamp": "1468467296",
- "gasLimit": "4712388",
- "miner": "0xea674fdde714fd979de3edf0f56aa9716b898ec8"
- },
- "input": "0xf869448505d21dba00833567e09403e3d4561a8f8e975fdcd798d32857a20cf25e7e8084be9a65551ba0d4dd5fff30e83fbe630bb0fd67eeefe9e3aad0c3ee870a2b6e80fc40191bc7d4a074f93b546bfad60f3cae8e4aafef835237095d6618334154a24df4b4d49d9359",
- "tracerConfig": {
- "withLog": true
- },
- "result": {
- "from": "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b",
- "gas": "0x3567e0",
- "gasUsed": "0x26e1ef",
- "to": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "input": "0xbe9a6555",
- "calls": [
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x34affa",
- "gasUsed": "0x1ef",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x4b6753bc",
- "output": "0x0000000000000000000000000000000000000000000000000000000057870858",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x34abef",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a08231000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89",
- "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x34a705",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a08231000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89",
- "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x34a31a",
- "gasUsed": "0xa2f3",
- "to": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89",
- "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89",
- "gas": "0x343e8c",
- "gasUsed": "0x9a62",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd"
- ],
- "data": "0x00000000000000000000000000000000000000000001819451f999d617dafa93",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89",
- "topics": [
- "0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2"
- ],
- "data": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93",
- "position": "0x1"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x33ff04",
- "gasUsed": "0x168e",
- "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "input": "0xa8618f710000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "calls": [
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x339a3b",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x3395a4",
- "gasUsed": "0x15f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x0e708203",
- "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x339363",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x339129",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x338cfa",
- "gasUsed": "0x13f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x18160ddd",
- "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x338a75",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x33e6f2",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a08231000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4",
- "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x33e208",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a08231000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4",
- "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x33de20",
- "gasUsed": "0x685b",
- "to": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4",
- "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4",
- "gas": "0x337992",
- "gasUsed": "0x5fca",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd"
- ],
- "data": "0x00000000000000000000000000000000000000000001819451f999d617dafa76",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4",
- "topics": [
- "0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2"
- ],
- "data": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76",
- "position": "0x1"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x3374a2",
- "gasUsed": "0x168e",
- "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "input": "0xa8618f710000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "calls": [
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x330fd9",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x330b42",
- "gasUsed": "0x15f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x0e708203",
- "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x330901",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x3306c7",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x330298",
- "gasUsed": "0x13f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x18160ddd",
- "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x330013",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x33490b",
- "gasUsed": "0x3f781",
- "to": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "input": "0xfc340716",
- "calls": [
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x32e30d",
- "gasUsed": "0x15f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x0e708203",
- "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x32e037",
- "gasUsed": "0x15f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x0e708203",
- "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x32dd7b",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x32daf9",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x32d6ab",
- "gasUsed": "0x13f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x18160ddd",
- "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x32d400",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x32c975",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x3276d3",
- "gasUsed": "0xa49d",
- "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "input": "0xd0679d340000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x320fe1",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x320b5b",
- "gasUsed": "0x9a62",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc"
- ],
- "data": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x3164e1",
- "gasUsed": "0x4e91",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0x",
- "value": "0x4563918244f400000",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x3115cc",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x000000000000000000000000000000000000000000000004563918244f400000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x311382",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x310f37",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x310ae9",
- "gasUsed": "0x1446e",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xcc9ae3f6",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x30a397",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x000000000000000000000000000000000000000000000004563918244f400000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x309fc1",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x000000000000000000000000000000000000000000000004563918244f400000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x309c45",
- "gasUsed": "0x122af",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0x0221038a0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000000022b1c8c12279fffff",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "gas": "0x301e6f",
- "gasUsed": "0x10068",
- "to": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "input": "0x",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x2fbb97",
- "gasUsed": "0x15f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x0e708203",
- "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x2fa477",
- "gasUsed": "0xe7b6",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xcc9ae3f6",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x2f3d25",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x000000000000000000000000000000000000000000000004563918244f400000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x2f394f",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x000000000000000000000000000000000000000000000004563918244f400000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x2f35d3",
- "gasUsed": "0x8b5f",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0x0221038a0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000000022b1c8c12279fffff",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "gas": "0x2eb7fd",
- "gasUsed": "0x6918",
- "to": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "input": "0x",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x2e5525",
- "gasUsed": "0x15f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x0e708203",
- "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x2e5168",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x2e4d69",
- "gasUsed": "0x5fca",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccc",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd"
- ],
- "data": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccc",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x22b1c8c12279fffff",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "topics": [
- "0x9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc",
- "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc"
- ],
- "data": "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff",
- "position": "0x1"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x22b1c8c12279fffff",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "topics": [
- "0x9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc",
- "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc"
- ],
- "data": "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff",
- "position": "0x1"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "gas": "0x2fc505",
- "gasUsed": "0xd4fa",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000001",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "topics": [
- "0x07cf7e805770612a8b2ee8e0bcbba8aa908df5f85fbc4f9e2ef384cf75315038"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x6"
- },
- {
- "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc",
- "topics": [
- "0x7027eecbd2a688fc1fa281702b311ed7168571514adfd17014a55d828cb43382"
- ],
- "data": "0x000000000000000000000000000000000000000000000004563918244f400000",
- "position": "0x8"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x2f5092",
- "gasUsed": "0x14e37",
- "to": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "input": "0xd95f98ce",
- "calls": [
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2eea7c",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2ee4cb",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526",
- "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2edfff",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2edb9a",
- "gasUsed": "0x6994",
- "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "input": "0xd0679d340000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000063",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2e7519",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f508",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2e7093",
- "gasUsed": "0x5fca",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000063",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000063",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2e6f59",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2e6afa",
- "gasUsed": "0x1113",
- "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "input": "0x65f13792000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526",
- "output": "0x0000000000000000000000000000000000000000000000000037bc5737aa7ba8",
- "calls": [
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2e06f9",
- "gasUsed": "0x15f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x0e708203",
- "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2e04b8",
- "gasUsed": "0x113",
- "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193",
- "input": "0xd2cc718f",
- "output": "0x000000000000000000000000000000000000000000000004563918244f400000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2e027b",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2dfe4c",
- "gasUsed": "0x13f",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x18160ddd",
- "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2dfbc7",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526",
- "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2e5281",
- "gasUsed": "0x329",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x81f03fcb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2e4dcc",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000064",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2e4857",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526",
- "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "gas": "0x2e3bae",
- "gasUsed": "0x9a62",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e965260000000000000000000000000000000000000000000000000000000000000064",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000064",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "topics": [
- "0x4b0bc4f25f8d0b92d2e12b686ba96cd75e4e69325e6cf7b1f3119d14eaf2cbdf"
- ],
- "data": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526",
- "position": "0x6"
- },
- {
- "address": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f",
- "topics": [
- "0xf340c079d598119636d42046c6a2d2faf7a68c04aecee516f0e0b8a9e79b8666"
- ],
- "data": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e9652600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x9"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x2e00dc",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x2dfc58",
- "gasUsed": "0xa3bb",
- "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "input": "0xd0679d340000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b0000000000000000000000000000000000000000000000000000000000000001",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2d9648",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a5",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0x2d91c2",
- "gasUsed": "0x9a62",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b0000000000000000000000000000000000000000000000000000000000000001",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x2d57a6",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x2d5515",
- "gasUsed": "0x3478d",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x2ceffb",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x2ce86e",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000001"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x2a0c87",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x2a09f6",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x29a4dc",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x299d4f",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000002"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x26fc00",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x26f96f",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x269455",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x268cc8",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000003",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000003"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x23eb79",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000003",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x23e8e8",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x2383ce",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x237c41",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000004",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000004"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x20daf2",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000004",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x20d861",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x207347",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x206bba",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000005",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000005"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x1dca6b",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000005",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x1dc7da",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x1d62c0",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x1d5b33",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000006",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000006"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x1ab9e4",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000006",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x1ab753",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x1a5239",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x1a4aac",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000007",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000007"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x17a95d",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000007",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x17a6cc",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x1741b2",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x173a25",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000008",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000008"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x1498d6",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000008",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x149645",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x14312b",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x14299e",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000009",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x0000000000000000000000000000000000000000000000000000000000000009"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x11884f",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000009",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0x1185be",
- "gasUsed": "0x30cf5",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0xff2f4bd2",
- "calls": [
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x1120a4",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "gas": "0x111917",
- "gasUsed": "0x29e8d",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
- "output": "0x000000000000000000000000000000000000000000000000000000000000000a",
- "calls": [
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "gas": "0x3",
- "gasUsed": "0x3",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x",
- "error": "out of gas",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f",
- "0x000000000000000000000000000000000000000000000000000000000000000a"
- ],
- "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000",
- "position": "0x2"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0xe77c8",
- "gasUsed": "0x112",
- "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b",
- "input": "0x400e3949",
- "output": "0x000000000000000000000000000000000000000000000000000000000000000a",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e",
- "gas": "0xe7537",
- "gasUsed": "0x1eafd",
- "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "input": "0x975057e7",
- "calls": [
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0xe0f53",
- "gasUsed": "0x314",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a4",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0xe096d",
- "gasUsed": "0x9a62",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf3000000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf30"
- ],
- "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0xd6871",
- "gasUsed": "0x9a62",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a200000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a2"
- ],
- "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "gas": "0xcc775",
- "gasUsed": "0x9a62",
- "to": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "input": "0xa9059cbb000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x304a554a310c7e546dfe434669c62820b7d83490",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd",
- "0x000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b"
- ],
- "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "topics": [
- "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b"
- ],
- "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "position": "0x2"
- },
- {
- "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "topics": [
- "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b"
- ],
- "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "position": "0x3"
- },
- {
- "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd",
- "topics": [
- "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b"
- ],
- "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c",
- "position": "0x4"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json
deleted file mode 100644
index 66d4582008..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json
+++ /dev/null
@@ -1,580 +0,0 @@
-{
- "genesis": {
- "difficulty": "7507253814130",
- "extraData": "0xd783010400844765746887676f312e352e31856c696e7578",
- "gasLimit": "3141592",
- "hash": "0x3d9d19618f67bbb7708403fe9bda131fbade0449d2ac12bf3b140b4269112826",
- "miner": "0x63a9975ba31b0b9626b34300f7f627147df1f526",
- "mixHash": "0x50aaa8973eadd4bbfc7f5b59d5be52f6a1be2d38f40b5a0786a24b90257520da",
- "nonce": "0x3547956c62c256b9",
- "number": "595531",
- "stateRoot": "0x79d00dd270bffc48d89fa55842f63f840981121378da8c6de4d479535f25ed6a",
- "timestamp": "1448471472",
- "totalDifficulty": "3448100174991667199",
- "alloc": {
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x44dc051cccdfd2e132",
- "nonce": "39602"
- },
- "0x350e0ffc780a6a75b44cc52e1ff9092870668945": {
- "balance": "0xe37111b7c79406c0",
- "code": "0x606060405236156100f05760e060020a60003504631ff6c70581146100f257806347980c0d146100fd57806353ba9c2f146101085780635ea8cd12146101c957806369d640fd146101f05780637ce3489b146102405780637d1bb97a1461026b5780637fd6f15c146103e55780638bf50628146103f057806390a248f814610411578063a8f37bb214610438578063b019e0171461046a578063b4c70cea1461059b578063cf955f34146106a1578063d229b54b146106bd578063d54b4a04146106e4578063e021fadb146106f1578063e45be8eb14610858578063eddfa7c814610863578063f2a75fe41461095d575b005b6109a5621e84845481565b6109a5621e84865481565b6109b76004356024356000808080806003876103e881101561000257506107d0880201866103e8811015610002579090600202016000505461ffff168152602081019190915260400160002054600160a060020a031692506003856103e881101561000257506107d0860201846103e88110156100025790906002020160005054620100009004600390810b9250856103e881101561000257506107d0860201846103e8811015610002579090600202016000506001015490509250925092565b6100f0600435621e848354600160a060020a0390811633909116141561026857621e848755565b6109e36004356024356003826103e881101561000257506107d0830201816103e88110156100025790906002020160005080546001919091015461ffff821693506201000090910460030b915083565b6100f0600435621e848354600160a060020a0390811633909116141561026857621e84858190555b50565b610a0a600435617d00604051908101604052806103e8905b600081526020019060019003908161028357505060408051617d0081019091526103e8815b60008152602001906001900390816102a857505060408051617d0081019091526103e8815b60008152602001906001900390816102cd5750600090505b6103e861ffff82161015610d09576000806003836103e8811015610002576107d002018150876103e881101561000257600202016000505461ffff168152602081019190915260400160002054600160a060020a031684826103e8811015610002575050602082028501526003816103e8811015610002576107d00201600050856103e8811015610002579090600202016000505462010000900460030b83826103e8811015610002575050600390810b60208302850152816103e8811015610002576107d00201600050856103e8811015610002579090600202016000506001015482826103e8811015610002575050602082028301526001016102e5565b6109a5621e84855481565b610a59600435600060208190529081526040902054600160a060020a031681565b6100f0600435621e848354600160a060020a0390811633909116141561026857621e848655565b6100f060043560243560443560643560843560a435610a8e868684866101000288620100000286607f02010101610870565b604080516004803580820135602081810280860182019096528185526100f09593946024949093850192918291908501908490808284375050604080518735808a013560208181028085018201909552818452989a996044999398509190910195509350839250850190849080828437505060408051606435808a013560208181028085018201909552818452989a9935999860849850929650602491909101945092508291908501908490808284375050604080519635808901356020818102808b018201909452818a5297999860a4989097506024929092019550935083925085019084908082843750949650505050505050621e848354600090600160a060020a03908116339091161415610a8e575b8551811015610a8e57606060405190810160405280610d1186610ebc565b60408051602060248035600481810135601f81018590048502860185019096528585526109a5958135959194604494929390920191819084018382808284375094965050933593505050505b6000831515610699577ffd33e90d0eac940755277aa91045b95664988beeeafc4ed7d1281a6d83afbc003384846040518084600160a060020a03168152602001806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156106895780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a15b509192915050565b610a7660043560016020526000908152604090205461ffff1681565b6100f0600435621e848354600160a060020a0390811633909116141561026857621e848455565b610a7660025461ffff1681565b604080516004803580820135602081810280860182019096528185526109a59593946024949093850192918291908501908490808284375050604080518735808a013560208181028085018201909552818452989a9960449993985091909101955093508392508501908490808284375050604080519635808901356020818102808b018201909452818a529799986064989097506024929092019550935083925085019084908082843750506040805196358089013560208181028a81018201909452818a5297999860849890975060249290920195509350839250850190849080828437509496505050505050506000600060006000610ad68751895114606060405190810160405280602381526020017f446966666572656e74206e756d626572206f66207856616c732061732079566181526020017f6c732e00000000000000000000000000000000000000000000000000000000008152602001508a516105e7565b6109a5621e84875481565b6100f06004356024356044355b6000610a96848484345b6000808080808060038a6103e8811015610002576107d00201896103e88110156100025760020201805461ffff16825260208290526040822054621e8484546001830154621e848654939850600160a060020a03928316975060649181028290049650929092029190910492503316841415610f4d57610fbc82341015606060405190810160405280602e81526020017f4368616e67696e6720796f7572206f776e20706978656c20636f73747320313081526020017f25206f66206974732076616c7565000000000000000000000000000000000000815260200150846105e7565b6100f0621e848354600160a060020a039081163390911614156109a357604051621e848354600160a060020a03908116916000913016319082818181858883f150505050505b565b60408051918252519081900360200190f35b60408051600160a060020a0394909416845260039290920b602084015282820152519081900360600190f35b6040805161ffff94909416845260039290920b602084015282820152519081900360600190f35b6040518084617d008083818460006004610bc7f150918201918591508083818460006004610bc7f15061fa00840192508491508083818460006004610bc7f15062017700965092945050505050f35b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b505050505050565b90506000811115610ac25760405133600160a060020a031690600090839082818181858883f150505050505b50505050565b93505b505050949350505050565b1580610b4e5750610b4c8651895114606060405190810160405280602481526020017f446966666572656e74206e756d626572206f66207856616c7320617320636f6c81526020017f6f72732e000000000000000000000000000000000000000000000000000000008152602001508a516105e7565b155b80610bc55750610bc38551895114606060405190810160405280602481526020017f446966666572656e74206e756d626572206f66207856616c732061732070726981526020017f6365732e000000000000000000000000000000000000000000000000000000008152602001508a516105e7565b155b15610bd35760009350610acb565b5034915060009050805b8751811015610c63578481815181101561000257602090810290910101519092039160008310610d0157610cfb88828151811015610002579060200190602002015188838151811015610002579060200190602002015188848151811015610002579060200190602002015188858151811015610002579060200190602002015161087a565b6000821115610c8d5760405133600160a060020a031690600090849082818181858883f150505050505b610ac86000841015606060405190810160405280602181526020017f56616c756520776173206c657373207468616e2073756d206f6620707269636581526020017f7300000000000000000000000000000000000000000000000000000000000000815260200150856105e7565b91909101905b600101610bdd565b509193909250565b8152602001848381518110156100025790602001906020020151815260200183838151811015610002579060200190602002015181526020015060036000508783815181101561000257906020019060200201516103e8811015610002576107d002016000508683815181101561000257906020019060200201516103e8811015610002576002020160005081518154602084015160e060020a90810204620100000261ffff199190911690911765ffffffff00001916178155604091909101516001919091015560010161057d565b8454600061ffff919091161115610e225750604051621e84855460649088020490600160a060020a03851690600090838a039082818181858883f150505050505b845460018601546040805161ffff8e811682528d166020820152600160a060020a038881168284015262010000909404600390810b810b606083015260808201939093523390931660a0840152908a900b60c083015260e08201899052517fcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42918190036101000190a1606060405190810160405280611143335b600160a060020a03811660009081526001602052604081205461ffff1690811415610f485750604060008181206002805461ffff1981811661ffff928316600190810191821790945591821685526020858152958520805473ffffffffffffffffffffffffffffffffffffffff191688179055600160a060020a03871690945293528054909116821790555b919050565b60408051621e848754606082018352602182527f4d696e696d756d20706978656c2070726963652069732035302066696e6e657960208301527f2e00000000000000000000000000000000000000000000000000000000000000928201929092526110c29134101590896105e7565b1515610fca578695506110b5565b33600160a060020a031684600160a060020a03161415610de157604080518654600188015461ffff8e811684528d166020840152600160a060020a03881683850181905262010000909204600390810b810b60608501526080840182905260a0840192909252908b900b60c083015260e082015290517fcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42918190036101000190a18760038b6103e8811015610002576107d002018a6103e88110156100025760020201805465ffffffff0000191660e060020a92830292909204620100000291909117905581870395505b5050505050949350505050565b15806111365750610fbc83341015606060405190810160405280603281526020017f56616c7565206d7573742062652031302520686967686572207468616e20637581526020017f7272656e7420706978656c2070726963652e0000000000000000000000000000815260200150856105e7565b15610fca578695506110b5565b8152602081018a905260400188905260038b6103e8811015610002576107d002018a6103e8811015610002576002020160005081518154602084015160e060020a90810204620100000261ffff199190911690911765ffffffff000019161781556040919091015160019190910155600095506110b556",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000175901": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000175902": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000175903": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000175904": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760c7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760c8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760c9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760ca": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760cb": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760cc": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760cd": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760ce": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760cf": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d1": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d2": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d3": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d4": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d5": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d6": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760d9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760da": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760db": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760dc": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760dd": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760de": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760df": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001760e0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000176897": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000176898": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000176899": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000017689a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000017689b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000017689c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000017689d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000017689e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000017689f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768a0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768a7": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768a8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768a9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768aa": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768ab": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768ac": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768ad": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768ae": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768af": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001768b0": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c37": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c38": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c39": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c3a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c3b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c3c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c3d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c3e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c3f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c40": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c45": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c46": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c47": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c48": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c49": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c4a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c4b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c4c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c4d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c4e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c4f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000196c50": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197407": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197408": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197409": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019740a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019740b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019740c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019740d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019740e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019740f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197410": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197411": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197412": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197413": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197414": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197415": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197416": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197417": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197418": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197419": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019741a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019741b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019741c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019741d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019741e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000019741f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197420": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197be3": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000197be4": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x00000000000000000000000000000000000000000000000000000000001e8484": "0x000000000000000000000000000000000000000000000000000000000000006e",
- "0x00000000000000000000000000000000000000000000000000000000001e8486": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0x00000000000000000000000000000000000000000000000000000000001e8487": "0x0000000000000000000000000000000000000000000000000011c37937e08000",
- "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xe1723559c995b1804c0512df6fe6d061eeb47aff37a3ced3b93f0c1bef247540": "0x0000000000000000000000000000000000000000000000000000000000000007"
- }
- },
- "0x3fcb0342353c541e210013aaddc2e740b9a33d08": {
- "balance": "0x6a0e4be198f18400",
- "nonce": "17"
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "595532",
- "difficulty": "7503588162862",
- "timestamp": "1448471495",
- "gasLimit": "3141592",
- "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
- },
- "input": "0xf91a7311850ba43b7400832dc6c094350e0ffc780a6a75b44cc52e1ff90928706689458803782dace9d90000b91a04e021fadb000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000013a00000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fd000000000000000000000000000000000000000000000000000000000000034300000000000000000000000000000000000000000000000000000000000002fd0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000032fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebebebffffffffffffffffffffffffffffffffffffffffffffffffffffffffff888888ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3b3b3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3e3e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e3e3effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbdbdbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0b0b0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0a0a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5b5bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9a9a9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9b9b9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff636363fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c9c9cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d4e53ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f494b00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080001ca0e8a879dd98a39d735b866ff64d84e9c144a17bcab106cf2f1327b1272db06aaca02ab279a2459b5e30dfea0bc8a888c7d2a190740090352b4a7aded30c45490af9",
- "tracerConfig": {
- "withLog": true
- },
- "result": {
- "from": "0x3fcb0342353c541e210013aaddc2e740b9a33d08",
- "gas": "0x2dc6c0",
- "gasUsed": "0x2570bf",
- "to": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "input": "0xe021fadb000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000013a00000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fd000000000000000000000000000000000000000000000000000000000000034300000000000000000000000000000000000000000000000000000000000002fd0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000032fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebebebffffffffffffffffffffffffffffffffffffffffffffffffffffffffff888888ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3b3b3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3e3e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e3e3effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbdbdbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0b0b0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0a0a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5b5bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9a9a9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9b9b9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff636363fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c9c9cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d4e53ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f494b00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e08000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "logs": [
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebebeb0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8888880000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3b3b30000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfc0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3e3e30000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e3e3e0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbdbdb0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f40000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfb0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0b0b00000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0a0a00000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5b5b0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababa0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaea0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9a9a90000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9b9b90000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfb0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababa0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6363630000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f9f90000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaea0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c9c9c0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f80000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfc0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d4e530000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x000000000000000000000000000000000000000000000000000000000000034300000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- },
- {
- "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945",
- "topics": [
- "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42"
- ],
- "data": "0x00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f494b0000000000000000000000000000000000000000000000000011c37937e08000",
- "position": "0x0"
- }
- ],
- "value": "0x3782dace9d90000",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json
deleted file mode 100644
index 762ccbe58f..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json
+++ /dev/null
@@ -1,288 +0,0 @@
-{
- "genesis": {
- "difficulty": "45944156141275",
- "extraData": "0xd783010406844765746887676f312e342e32856c696e7578",
- "gasLimit": "4714680",
- "hash": "0x3c41811ab60f232565db6cfafb939d96255b9f678a203181c6f537d6c22d7e6f",
- "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5",
- "mixHash": "0x8b736c63e05d381ae593d584b63fef5c31b04a3cea72bd5a3c92f95f4f7040e8",
- "nonce": "0xce8ffb5c1ad942ec",
- "number": "1725115",
- "stateRoot": "0xca08a341c1f95fcba0821c4a27662ef162d39e1f9f5722717531f510d54112b0",
- "timestamp": "1466232982",
- "totalDifficulty": "28554024908214037524",
- "alloc": {
- "0x0000000000000000000000000000000000000004": {
- "balance": "0x0"
- },
- "0x1d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed": {
- "balance": "0x0",
- "code": "0x606060405260e060020a600035046338cc483181146038578063767800de14604f578063a6f9dae1146060578063d1d80fdf14607e575b005b600054600160a060020a03165b6060908152602090f35b6045600054600160a060020a031681565b603660043560015433600160a060020a03908116911614609c576002565b603660043560015433600160a060020a0390811691161460be576002565b6001805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6000805473ffffffffffffffffffffffffffffffffffffffff1916821790555056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000088e1315687aec48a72786c6b3b3f075208b62713"
- }
- },
- "0x50739060a2c32dc076e507ae1a893aab28ecfe68": {
- "balance": "0x6a8ecefb09f7c4141",
- "code": "0x606060405236156101745760e060020a6000350463058aace1811461017f578063061e494f146101905780630d1fce421461021e57806311610c251461029157806312253a6c146102b5578063132ae5e9146102d357806316d190e3146102dc57806329e206bd146102e5578063337b68ba1461030a57806338bbfa50146103135780633f683b6a146104115780634dc6b523146104245780634e69d5601461042d57806366d16cc31461044a578063724ae9d014610453578063758971e81461046f5780637cf0ffcb146104965780638ca17995146104a35780639619367d146104b7578063a96a5a5b146104c0578063adc2c98a146104c9578063b70d0b3b146104d2578063bc99cc37146104db578063c4bc5da5146104e4578063cafb220214610502578063d28442ef1461050b578063d4c80edf14610514578063df06f9061461051d578063e8b5e51f14610527578063f738e5ca14610546578063f8b2cb4f14610553578063fa968eea14610594575b610661610663610295565b6106616000341115610eab57610002565b61066560043560006000600060006000600f6000508054905086101561021657600f8054879081101561000257505050507f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80284015490819052600e602052604090912080546001820154600283015460039390930154600160a060020a03929092169450925b509193509193565b6106965b601254601354601154600c5460009391019091010330600160a060020a0316318190101561028957604080517f62616e6b726f6c6c5f6d69736d61746368000000000000000000000000000000815290519081900360110190a05030600160a060020a0316315b8091505b5090565b6106615b600060006000600d60149054906101000a900460ff16156106ef57610002565b610661600d5433600160a060020a03908116911614610fd657610002565b610696600a5481565b61069660045481565b6106616004355b600d5460009033600160a060020a0390811691161461101c57610002565b61069660125481565b60408051602060248035600481810135601f81018590048502860185019096528585526106619581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760649791965060249190910194509092508291508401838280828437509496505050505050506000600060006000610a18600080546040805160e060020a6338cc483102815290518392600160a060020a0316916338cc4831916004828101926020929190829003018187876161da5a03f11561000257505060405151915050600160a060020a0381168214156114635761140b6000610939565b610696600d5460a060020a900460ff1681565b61069660085481565b6106a8600060006000600060006000600060006000610f8d610222565b61069660115481565b6106965b600a54600654600091829182911015610ef857610f33565b6106616004355b600d54600090819033600160a060020a0390811691161461108657610002565b61066161066360006102ec565b6106616004356000341115610e7957610002565b61069660055481565b61069660025481565b61069660035481565b61069660075481565b61069660065481565b610661600d5433600160a060020a03908116911614610ffc57610002565b610696600c5481565b61069660135481565b61069660105481565b610696600f545b90565b610661600d54600090819060a060020a900460ff1615610c8057610002565b6106616106636000610476565b6106966004355b600160a060020a0381166000908152600b602052604081205481901180156105845750600c548190115b15610ebd57600c54610ec6610222565b610696600080546040805160e060020a6338cc483102815290518392600160a060020a0316916338cc4831916004828101926020929190829003018187876161da5a03f11561000257505060408051805160e260020a630bbceb33028252620249f06024830152600482018390526003604483015260ea60020a621554930260648301529151600160a060020a03929092169250632ef3accc916084828101926020929190829003018187876161da5a03f1156100025750506040515160055481019350915061028d9050565b005b565b60408051600160a060020a039590951685526020850193909352838301919091526060830152519081900360800190f35b60408051918252519081900360200190f35b60408051998a5260208a0198909852888801969096526060880194909452608087019290925260a086015260c085015260e084015261010083015251908190036101200190f35b600060009054906101000a9004600160a060020a0316600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a630bbceb33028252620249f06024830152600482018390526003604483015260ea60020a621554930260648301529151600160a060020a03929092169250632ef3accc91608480830192602092919082900301816000876161da5a03f1156100025750506040515193505034839010156107c257610002565b82340391506127106107d2610222565b600460005054020460026000505460026000505460036000505461271003038402041115801561080457506005548210155b1561095a576040805180820182526003815260ea60020a62155493026020828101919091528251608081018452604381527f6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e818301527f2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174818501527f612e30000000000000000000000000000000000000000000000000000000000060608201528351610160810190945261012c80855261095f94919261175690830139620249f0600060006000600060009054906101000a9004600160a060020a0316600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151915050600160a060020a03811682141561118c5761113460005b600060006115ef731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed5b3b90565b610002565b6040805160808101825233815260208181018681526000838501818152606085018a8152878352600e90945293519490208054600160a060020a031916909417845551600184810191909155915160028401555160039290920191909155600f8054918201808255929350918281838015829011610a0057818360005260206000209182019101610a0091905b8082111561028d57600081556001016109ec565b5050506000928352506020909120018190555b505050565b600160a060020a031633600160a060020a0316141515610a3757610002565b6000878152600e6020526040812060018101549095501115610c5257600d5460a060020a900460ff166000148015610aa15750612710610a75610222565b600460005054020460026000505460026000505460036000505461271003038660010160005054020411155b15610b4957610b968660006114e28260006040805160208101909152600090819052828180805b8351811015610b3e57603060f860020a02848281518110156100025790602001015160f860020a900460f860020a0210158015610b295750603960f860020a02848281518110156100025790602001015160f860020a900460f860020a0211155b156116cb578115611722578560001415611719575b509095945050505050565b60018401548454610c5291600160a060020a0391909116905b604051600160a060020a038316906161a89083906000818181858888f193505050501515610d005760138054820190555050565b92506001831080610ba8575061271083115b15610bc75783546001850154610c5291600160a060020a031690610b62565b6000878152600e6020526040902060029081018490555460001984011015610c5b57506002546003546001850154855461271092909203029190910490610c7190600160a060020a031682610b62565b60018401546000190191505b601380546007546127109085020590810190915560118054918403909101905560018401546010805490910190555b50505050505050565b8354610c1790600160a060020a03166001610b62565b60018401548190039150610c23565b33600160a060020a03166000908152600b60205260408120541115610ca757610cc5610cab565b610d045b6011546012546000918291829114610a13576114e9610222565b33600160a060020a03166000908152600b6020908152604080832054835260099091529020600101805434908101909155600c805490910190555b5050565b600a5460065460009350901015610d6557600a80546001019081905591505b600082111561095a576000828152600960205260408120600101541115610deb576040600020805460019190910154610dc591600160a060020a031690610e7f565b5060015b600a548111610d23576000818152600960205260409020600101543490108015610db457508160001480610db457506040600081812060019081015485835292822001549083905290105b15610dbd579050805b600101610d69565b600082815260096020908152604080832054600160a060020a03168352600b9091528120555b600082815260096020526040812060010154148015610e2357506040600081812054600160a060020a03168152600b60205290812054145b1561095a5760008281526009602090815260408083208054600160a060020a03191633908117825534600192909201829055600c8054909201909155600160a060020a03168352600b9091529020829055610d00565b610ea833825b600160a060020a0382166000908152600b602052604081205481901115610a1357611578610cab565b50565b61066333610eb83361055a565b610e7f565b5060005b919050565b600160a060020a0384166000908152600b60209081526040808320548352600990915290206001015402049050610ec1565b5060015b600a548111610f38578160001480610f5b5750600082815260096020526040902054610f6c90600160a060020a031661055a565b92505b505090565b600082815260096020526040902054610f3090600160a060020a031661055a565b105b15610f64579050805b600101610efc565b600082815260096020526040902054610f5990600160a060020a031661055a565b601154600254600354600454600554601054939492939192909190610fb0610457565b600f60005080549050985098509850985098509850985098509850909192939495969798565b600d805474ff0000000000000000000000000000000000000000191660a060020a179055565b600d805474ff000000000000000000000000000000000000000019169055565b5060015b600a54811161104e5760008181526009602052604090205461107e90600160a060020a0316610eb88161055a565b8115610d0057604051600d54600160a060020a03908116916000913016319082818181858883f150505050505050565b600101611020565b82156110bb57506000905060015b600a5481116110e55760008181526009602052604090206001015490910190600101611094565b601354604051600d54600160a060020a03169160009182818181858883f150505060135550505050565b816000148015611101575060135430600160a060020a03163114155b1561112f57604051600d54600160a060020a03908116916000913016319082818181858883f1505050601355505b610a13565b50600060009054906101000a9004600160a060020a0316600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519150505b60018054600160a060020a0319168217908190556040805160e260020a630bbceb330281526024810187905260048181019283528a5160448301528a51600160a060020a039490941693632ef3accc938c938a939192839260649290920191602087810192918291859183918691600091601f850104600f02600301f150905090810190601f1680156112335780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f115610002575050604051519250503a8402670de0b6b3a76400000182111561127c5750600091505b50949350505050565b600160009054906101000a9004600160a060020a0316600160a060020a03166385dee34c8360008a8a8a8a6040518760e060020a028152600401808681526020018060200180602001806020018581526020018481038452888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156113275780820380516001836020036101000a031916815260200191505b508481038352878181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156113805780820380516001836020036101000a031916815260200191505b508481038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156113d95780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038185886185025a03f11561000257505060405151945061127392505050565b50600060009054906101000a9004600160a060020a0316600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519150505b60018054600160a060020a031916821790819055604080517fc281d19e0000000000000000000000000000000000000000000000000000000081529051600160a060020a03929092169163c281d19e9160048181019260209290919082900301816000876161da5a03f115610002575050604051519250610524915050565b9050610ec1565b9150600190505b600a54811161151a5760008181526009602052604090205461155990600160a060020a031661055a565b600c8390558282148015906115325750600a54600090115b1561154e5760138054848403908101909155600c805490910190555b601154601255505050565b60008281526009602052604090206001908101829055930192016114f0565b6115818361055a565b821115611594576115918361055a565b91505b50600160a060020a0382166000908152600b602090815260408083205483526009909152902060010180548290039055600c8054829003905560085460138054612710928402929092049182019055610a1383828403610b62565b1115611623575060008054600160a060020a031916731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed1790556001610ec1565b6000611642739efbea6358bed926b293d2ce63a730d6d98d43dd610956565b1115611678575060008054739efbea6358bed926b293d2ce63a730d6d98d43dd600160a060020a03199091161790556001610ec1565b60006116977320e12a1f859b3feae5fb2a0a32c18f5a65555bbf610956565b1115610ebd575060008054600160a060020a0319167320e12a1f859b3feae5fb2a0a32c18f5a65555bbf1790556001610ec1565b8381815181101561000257016020015160f860020a90819004027f2e00000000000000000000000000000000000000000000000000000000000000141561171157600191505b600101610ac8565b60001995909501945b600a83029250825060308482815181101561000257016020015160f860020a90819004810204909301602f19019250611711564244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000001d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000088e1315687aec48a72786c6b3b3f075208b62713",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000009c4",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000000000000000000000000000000000000000000000000000be",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000064",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000000000000000000000000000002c68af0bb140000",
- "0x000000000000000000000000000000000000000000000000000000000000000c": "0x000000000000000000000000000000000000000000000006ad2ff8ba84afdcdc",
- "0x000000000000000000000000000000000000000000000000000000000000000d": "0x000000000000000000000000a1b5f95be71ffa2f86adefcaa0028c46fe825161",
- "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000000000022",
- "0x0000000000000000000000000000000000000000000000000000000000000011": "0xffffffffffffffffffffffffffffffffffffffffffffffffd14ae0a37b4cc1d4",
- "0x0000000000000000000000000000000000000000000000000000000000000012": "0xffffffffffffffffffffffffffffffffffffffffffffffffd5ab72be30cb5f50",
- "0x0000000000000000000000000000000000000000000000000000000000000013": "0xffffffffffffffffd5bbd8ce9d1eb44232ca20eb5b4319ac5e1982d2c94bc3cb",
- "0x8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac824": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xe950f1be9a49788ef79ea4e854ed56155a7f60661724f41e3af5f799203a1eb9": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xe950f1be9a49788ef79ea4e854ed56155a7f60661724f41e3af5f799203a1eba": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xe950f1be9a49788ef79ea4e854ed56155a7f60661724f41e3af5f799203a1ebb": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xe950f1be9a49788ef79ea4e854ed56155a7f60661724f41e3af5f799203a1ebc": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x61c808d82a3ac53231750dadc13c777b59310bd9": {
- "balance": "0x12f621ea72fef44f848",
- "nonce": "51830"
- },
- "0x6412becf35cc7e2a9e7e47966e443f295e1e4f4a": {
- "balance": "0xfb5dbfc0d448e70",
- "nonce": "6"
- },
- "0x88e1315687aec48a72786c6b3b3f075208b62713": {
- "balance": "0x24b9f2c5dc266dc6",
- "code": "0x606060405236156101535760e060020a60003504630f825673811461018f57806323dc42e7146102135780632ef3accc146102ad578063453629781461033b578063480a434d146103d5578063524f3889146103de5780635c242c591461043f57806360f66701146104de57806362b3b8331461056757806368742da6146105eb578063688dcfd71461062b578063757004371461065857806377228659146106f25780637d242ae5146107cd5780637e1c42051461085357806381ade3071461033b57806385dee34c14610932578063a2ec191a14610a0c578063adf59f9914610213578063ae81584314610658578063b5bfdd7314610a64578063bf1fe42014610af2578063c281d19e14610b32578063c51be90f14610b44578063ca6ad1e414610bdd578063d959701614610bff578063db37e42f14610cb6578063de4b326214610d6d578063e839e65e14610daf575b61065660025433600160a060020a039081169116148015906101855750600154600160a060020a039081163390911614155b15610e8a57610002565b6106566004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650505050505050600254600160a060020a0390811633909116148015906102095750600154600160a060020a039081163390911614155b15610ebb57610002565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760649791965060249190910194509092508291508401838280828437509496505050505050506000610f2084848462030d406104cb565b610e8c6004808035906020019082018035906020019191908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965050933593505050506000610f288383335b6000600062030d40841115801561032d5750600160a060020a03831681526020819052604081205481145b1561184e5760009150611846565b610e8c6004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750506040805160208835808b0135601f81018390048302840183019094528383529799986044989297509190910194509092508291508401838280828437509496505050505050506000610f286000848462030d406104cb565b610e8c60085481565b610e8c6004808035906020019082018035906020019191908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496505050505050506000610f2f82336000610f288362030d4084610302565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050505b600083826000600061113d848433610302565b6106566004808035906020019082018035906020019191908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965050505050505080604051808280519060200190808383829060006004602084601f0104600f02600301f150905001915050604051809103902060046000508190555050565b6106566004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650505050505050600254600160a060020a0390811633909116148015906105e15750600154600160a060020a039081163390911614155b1561119757610002565b610656600435600254600160a060020a0390811633909116148015906106215750600154600160a060020a039081163390911614155b156111f957610002565b600160a060020a0333166000908152600660205260409020805460ff191660f860020a600435041790555b005b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050505b6000610f1d858585856104cb565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760849791965060249190910194509092508291508401838280828437509496505050505050506000610f1d8585858562030d4061091f565b60408051602060248035600481810135601f81018590048502860185019096528585526106569581359591946044949293909201918190840183828082843750949650505050505050600254600090600160a060020a0390811633909116148015906108495750600154600160a060020a039081163390911614155b1561121f57610002565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505050505b6000848260006000611516848433610302565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760849791965060249190910194509092508291508401838280828437509496505093359350505050600061156b868686868661091f565b6106566004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650509335935050505061157282600083610ab5565b6106566004808035906020019082018035906020019191908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496505093359350506044359150505b600254600090600160a060020a039081163390911614801590610ae85750600154600160a060020a039081163390911614155b1561157657610002565b610656600435600254600160a060020a039081163390911614801590610b285750600154600160a060020a039081163390911614155b1561162f57610002565b610e9e600154600160a060020a031681565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050506000610f1d858585856106e4565b600160a060020a03331660009081526007602052604090206004359055610656565b604080516004803580820135602081810285810182019096528185526106569593946024949093850192918291908501908490808284375050604080518735808a013560208181028085018201909552818452989a99604499939850919091019550935083925085019084908082843750949650505050505050600254600090600160a060020a039081163390911614801590610cac5750600154600160a060020a039081163390911614155b1561163457610002565b604080516004803580820135602081810285810182019096528185526106569593946024949093850192918291908501908490808284375050604080518735808a013560208181028085018201909552818452989a99604499939850919091019550935083925085019084908082843750949650505050505050600254600090600160a060020a039081163390911614801590610d635750600154600160a060020a039081163390911614155b1561168f57610002565b61065660043560025460009033600160a060020a03908116911614801590610da55750600154600160a060020a039081163390911614155b1561170557610002565b610e8c6004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750506040805160208835808b0135601f8101839004830284018301909452838352979998604498929750919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760649791965060249190910194509092508291508401838280828437509496505050505050506000610f20600085858562030d4061091f565b565b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b60006003600050600083604051808280519060200190808383829060006004602084601f0104600f02600301f1509050019150506040518091039020815260200190815260200160002060006101000a81548160ff0219169083021790555050565b90505b949350505050565b9392505050565b92915050565b6000600050600033600160a060020a031681526020019081526020016000206000505433600160a060020a031630600160a060020a03160101604051808281526020019150506040518091039020945084506000600050600033600160a060020a031681526020019081526020016000206000818150548092919060010191905055507fb76d0edd90c6a07aa3ff7a222d7f5933e29c6acc660c059c97837f05c4ca1a8433868b8b8b8b6006600050600033600160a060020a0316815260200190815260200160002060009054906101000a900460f860020a026007600050600033600160a060020a03168152602001908152602001600020600050546040518089600160a060020a0316815260200188815260200187815260200180602001806020018681526020018581526020018481526020018381038352888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156110c35780820380516001836020036101000a031916815260200191505b508381038252878181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561111c5780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390a150505050949350505050565b91503482901061119257813403905060008111156111765760405133600160a060020a031690600090839082818181858883f150505050505b42624f1a000189118061118857504586115b15610f3557610002565b610002565b60016003600050600083604051808280519060200190808383829060006004602084601f0104600f02600301f1509050019150506040518091039020815260200190815260200160002060006101000a81548160ff0219169083021790555050565b604051600160a060020a03828116916000913016319082818181858883f1505050505050565b50600882905560005b600b548110156112a757600b8054600a91600091849081101561000257508054600080516020611883833981519152850154835260209390935260408220548602926009929190859081101561000257908252600080516020611883833981519152018150548152602081019190915260400160002055600101611228565b505050565b6000600050600033600160a060020a031681526020019081526020016000206000505433600160a060020a031630600160a060020a03160101604051808281526020019150506040518091039020945084506000600050600033600160a060020a031681526020019081526020016000206000818150548092919060010191905055507faf30e4d66b2f1f23e63ef4591058a897f67e6867233e33ca3508b982dcc4129b33868c8c8c8c8c6006600050600033600160a060020a0316815260200190815260200160002060009054906101000a900460f860020a026007600050600033600160a060020a0316815260200190815260200160002060005054604051808a600160a060020a0316815260200189815260200188815260200180602001806020018060200187815260200186815260200185815260200184810384528a8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561143f5780820380516001836020036101000a031916815260200191505b508481038352898181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156114985780820380516001836020036101000a031916815260200191505b508481038252888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156114f15780820380516001836020036101000a031916815260200191505b509c5050505050505050505050505060405180910390a1505050505b95945050505050565b915034829010611192578134039050600081111561154f5760405133600160a060020a031690600090839082818181858883f150505050505b42624f1a00018a118061156157504586115b156112ac57610002565b905061150d565b5050565b8383604051808380519060200190808383829060006004602084601f0104600f02600301f150905001828152600101925050506040518091039020905080600b600050600b600050805480919060010190908154818355818115116115fe578183600052602060002091820191016115fe91905b8082111561162b57600081556001016115ea565b5050508154811015610002576000918252602080832090910192909255918252600a905260409020555050565b5090565b600555565b5060005b81518110156112a7578281815181101561000257906020019060200201516007600050600084848151811015610002576020908102909101810151600160a060020a03168252919091526040902055600101611638565b5060005b81518110156112a75782818151811015610002579060200190602002015160f860020a026006600050600084848151811015610002576020908102909101810151600160a060020a031682529190915260409020805460f860020a90920460ff19909216919091179055600101611693565b50600881905560005b600b5481101561157257600b8054600a91600091849081101561000257600080516020611883833981519152015482526020929092526040812054825490850292600992918590811015610002576000805160206118838339815191520154825250602091909152604090205560010161170e565b60096000506000866006600050600087600160a060020a0316815260200190815260200160002060009054906101000a900460f860020a02604051808380519060200190808383829060006004602084601f0104600f02600301f150905001828152600101925050506040518091039020815260200190815260200160002060005054915081506007600050600084600160a060020a03168152602001908152602001600020600050549050806000141561183d57506005545b83810291909101905b509392505050565b600454600014801590611875575060045460009081526003602052604090205460ff166001145b156117835760009150611846560175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0xbb130806898f085471286ecb4f3966fcbe090ba29e4f9d194ee9e9062f6b61ae",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000000000000000000000000000000000004a817c800",
- "0x797fdd0f6c82412493cfa2aacdc9999c10e5d0c9aa3f05a8a289b1b3918c6db8": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8d90a37db271d62339ebfe84641d1ebdaf56fd5d50861d795eacb410dbb57630": "0x000000000000000000000000000000000000000000000000000cf4e712e8d654",
- "0x9864048b6d6c99ecd7fcaecf663fbe1036a6e1fc00cec0a3eb25684dd08184c2": "0x0000000000000000000000000000000000000000000000000000000000000011",
- "0xca9ea8077ddc97a21c029df4b19819e51903e11d4bfc7564a622a192cefd6356": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xf34e44a0672ef76b852374cc47d9772eb4e5e41fa79fba61dcfc9cf7d50418d5": "0x0000000000000000000000000000000000000000000000000000000000000022"
- }
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "1725116",
- "difficulty": "45966589844033",
- "timestamp": "1466232988",
- "gasLimit": "4716972",
- "miner": "0x61c808d82a3ac53231750dadc13c777b59310bd9"
- },
- "input": "0xf86d068504e3b2920083030d409450739060a2c32dc076e507ae1a893aab28ecfe68880429d069189e0000801ca04e403b46022c2098e41d3a0e561881ac368cd330637239da85759c1b4f44ab24a072a88235d98959283c00af411bd663b0da8703e05a94d3673aca37d0a39b7e07",
- "tracerConfig": {
- "withLog": true
- },
- "result": {
- "from": "0x6412becf35cc7e2a9e7e47966e443f295e1e4f4a",
- "gas": "0x30d40",
- "gasUsed": "0x249eb",
- "to": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "input": "0x",
- "calls": [
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x257af",
- "gasUsed": "0xbc",
- "to": "0x1d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed",
- "input": "0x38cc4831",
- "output": "0x00000000000000000000000088e1315687aec48a72786c6b3b3f075208b62713",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x255a1",
- "gasUsed": "0x73a",
- "to": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "input": "0x2ef3accc000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000355524c0000000000000000000000000000000000000000000000000000000000",
- "output": "0x00000000000000000000000000000000000000000000000000179d63013c5654",
- "calls": [
- {
- "from": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "gas": "0x12",
- "gasUsed": "0x12",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x55524c",
- "output": "0x55524c",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x24680",
- "gasUsed": "0xbc",
- "to": "0x1d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed",
- "input": "0x38cc4831",
- "output": "0x00000000000000000000000088e1315687aec48a72786c6b3b3f075208b62713",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x12",
- "gasUsed": "0x12",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x55524c",
- "output": "0x55524c",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x22f3b",
- "gasUsed": "0x73a",
- "to": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "input": "0x2ef3accc000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000355524c0000000000000000000000000000000000000000000000000000000000",
- "output": "0x00000000000000000000000000000000000000000000000000179d63013c5654",
- "calls": [
- {
- "from": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "gas": "0x12",
- "gasUsed": "0x12",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x55524c",
- "output": "0x55524c",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x12",
- "gasUsed": "0x12",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x55524c",
- "output": "0x55524c",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x30",
- "gasUsed": "0x18",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e30",
- "output": "0x6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e30",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x99",
- "gasUsed": "0x2d",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d",
- "output": "0x4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "gas": "0x2083e",
- "gasUsed": "0x4417",
- "to": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "input": "0x85dee34c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000355524c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000436a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d0000000000000000000000000000000000000000",
- "output": "0xd1b13c1538a940417bf0e73b2498634436753c854c7fb971224d971bd2ae3e88",
- "calls": [
- {
- "from": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "gas": "0x12",
- "gasUsed": "0x12",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x55524c",
- "output": "0x55524c",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "gas": "0x12",
- "gasUsed": "0x12",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x55524c",
- "output": "0x55524c",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "gas": "0x30",
- "gasUsed": "0x18",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e30",
- "output": "0x6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e30",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "gas": "0x99",
- "gasUsed": "0x2d",
- "to": "0x0000000000000000000000000000000000000004",
- "input": "0x4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d",
- "output": "0x4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x88e1315687aec48a72786c6b3b3f075208b62713",
- "topics": [
- "0xaf30e4d66b2f1f23e63ef4591058a897f67e6867233e33ca3508b982dcc4129b"
- ],
- "data": "0x00000000000000000000000050739060a2c32dc076e507ae1a893aab28ecfe68d1b13c1538a940417bf0e73b2498634436753c854c7fb971224d971bd2ae3e8800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000249f011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000355524c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000436a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d0000000000000000000000000000000000000000",
- "position": "0x4"
- }
- ],
- "value": "0x179d63013c5654",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0x50739060a2c32dc076e507ae1a893aab28ecfe68",
- "topics": [],
- "data": "0x62616e6b726f6c6c5f6d69736d61746368",
- "position": "0x2"
- }
- ],
- "value": "0x429d069189e0000",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json
deleted file mode 100644
index 64941dd4db..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "genesis": {
- "difficulty": "8430028481555",
- "extraData": "0xd783010302844765746887676f312e352e31856c696e7578",
- "gasLimit": "3141592",
- "hash": "0xde66937783697293f2e529d2034887c531535d78afa8c9051511ae12ba48fbea",
- "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226",
- "mixHash": "0xba28a43bfbca4a2effbb76bb70d03482a8a0c92e2883ff36cbac3d7c6dbb7df5",
- "nonce": "0xa3827ec0a82fe823",
- "number": "765824",
- "stateRoot": "0x8d96cb027a29f8ca0ccd6d31f9ea0656136ec8030ecda70bb9231849ed6f41a2",
- "timestamp": "1451389443",
- "totalDifficulty": "4838314986494741271",
- "alloc": {
- "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb": {
- "balance": "0x14203bee2ea6fbe8c",
- "nonce": "34"
- },
- "0xe2fe6b13287f28e193333fdfe7fedf2f6df6124a": {
- "balance": "0x2717a9c870a286f4350"
- },
- "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd": {
- "balance": "0x0",
- "code": "0x606060405260e060020a600035046306fdde038114610047578063313ce567146100a457806370a08231146100b057806395d89b41146100c8578063a9059cbb14610123575b005b61015260008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156101f55780601f106101ca576101008083540402835291602001916101f5565b6101c060025460ff1681565b6101c060043560036020526000908152604090205481565b610152600180546020601f6002600019610100858716150201909316929092049182018190040260809081016040526060828152929190828280156101f55780601f106101ca576101008083540402835291602001916101f5565b610045600435602435600160a060020a033316600090815260036020526040902054819010156101fd57610002565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156101b25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116101d857829003601f168201915b505050505081565b600160a060020a03821660009081526040902054808201101561021f57610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505056",
- "storage": {
- "0x1dae8253445d3a5edbe8200da9fc39bc4f11db9362181dc1b640d08c3c2fb4d6": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8ba52aac7f255d80a49abcf003d6af4752aba5a9531cae94fde7ac8d72191d67": "0x000000000000000000000000000000000000000000000000000000000178e460"
- }
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "765825",
- "difficulty": "8425912256743",
- "timestamp": "1451389488",
- "gasLimit": "3141592",
- "miner": "0xe2fe6b13287f28e193333fdfe7fedf2f6df6124a"
- },
- "input": "0xf8aa22850ba43b740083024d4594f4eced2f682ce333f96f2d8966c613ded8fc95dd80b844a9059cbb000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb00000000000000000000000000000000000000000000000000000000009896801ca067da548a2e0f381a957b9b51f086073375d6bfc7312cbc9540b3647ccab7db11a042c6e5b34bc7ba821e9c25b166fa13d82ad4b0d044d16174d5587d4f04ecfcd1",
- "tracerConfig": {
- "withLog": true
- },
- "result": {
- "from": "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
- "gas": "0x24d45",
- "gasUsed": "0xc6a5",
- "to": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd",
- "input": "0xa9059cbb000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb0000000000000000000000000000000000000000000000000000000000989680",
- "logs": [
- {
- "address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd",
- "topics": [
- "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
- "0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb",
- "0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb"
- ],
- "data": "0x0000000000000000000000000000000000000000000000000000000000989680",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json
deleted file mode 100644
index 30346d07f1..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json
+++ /dev/null
@@ -1,244 +0,0 @@
-{
- "genesis": {
- "difficulty": "56311715121637",
- "extraData": "0x7777772e62772e636f6d",
- "gasLimit": "4712388",
- "hash": "0x20d3b8daa046f2f10564d84ccbe6d0a8842d8d52bc6d623e23c38050a8f73776",
- "miner": "0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1",
- "mixHash": "0x75029f90d7de3f9e3d5eac4a25019f9ac5d0041641d1ef17e7759e45699d4224",
- "nonce": "0x54ff3b34fa1d9c97",
- "number": "1968179",
- "stateRoot": "0x6420003b1779cca3bcdab698c239bbc63623c0a7e4deeedbdb8190b9e7fd7520",
- "timestamp": "1469713675",
- "totalDifficulty": "42284028928878034360",
- "alloc": {
- "0x10abb5efecdc09581f8b7cb95791fe2936790b4e": {
- "balance": "0x81f158e2814b4ab624c",
- "code": "0x6060604052361561020e5760e060020a6000350463013cf08b8114610247578063095ea7b3146102d05780630c3b7b96146103455780630e7082031461034e578063149acf9a1461036057806318160ddd146103725780631f2dc5ef1461037b57806321b5b8dd1461039b578063237e9492146103ad57806323b872dd1461040e5780632632bf2014610441578063341458081461047257806339d1f9081461047b5780634b6753bc146104935780634df6d6cc1461049c5780634e10c3ee146104b7578063590e1ae3146104ca578063612e45a3146104db578063643f7cdd1461057a578063674ed066146105925780636837ff1e1461059b57806370a08231146105e5578063749f98891461060b57806378524b2e1461062457806381f03fcb1461067e57806382661dc41461069657806382bf6464146106b75780638b15a605146106c95780638d7af473146106d257806396d7f3f5146106e1578063a1da2fb9146106ea578063a3912ec814610704578063a9059cbb1461070f578063b7bc2c841461073f578063baac53001461074b578063be7c29c1146107b1578063c9d27afe14610817578063cc9ae3f61461082d578063cdef91d014610841578063dbde198814610859578063dd62ed3e1461087e578063e33734fd146108b2578063e5962195146108c6578063e66f53b7146108de578063eceb2945146108f0578063f8c80d261461094f575b610966600f546000906234bc000142108015610239575060125433600160a060020a03908116911614155b156109785761098033610752565b6109866004356000805482908110156100025750808052600e8202600080516020612a3683398151915201905060038101546004820154600683015460018401548454600786015460058701546009880154600a890154600d8a0154600160a060020a039586169b509599600201989760ff81811698610100909204811697949691951693168c565b61096660043560243533600160a060020a03908116600081815260156020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b61096660105481565b610a7d600754600160a060020a031681565b610a7d600e54600160a060020a031681565b61096660165481565b6109665b60004262127500600f60005054031115610de557506014610983565b610a7d601254600160a060020a031681565b60408051602060248035600481810135601f810185900485028601850190965285855261096695813595919460449492939092019181908401838280828437509496505050505050506000600060006000600060003411156116a857610002565b6109666004356024356044355b60115460009060ff1680156104315750600f5442115b80156124e957506124e78461044b565b6109666000610980335b600160a060020a0381166000908152600b602052604081205481908114156129cb57610b99565b61096660065481565b6109665b600d5430600160a060020a03163103610983565b610966600f5481565b61096660043560046020526000908152604090205460ff1681565b61096660043560243560006124cb610831565b610a9a6000341115610ba457610002565b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec565b61096660043560096020526000908152604090205481565b61096660015481565b610a9a60043530600160a060020a031633600160a060020a03161415806105db5750600160a060020a03811660009081526004602052604090205460ff16155b156121cb576121c8565b6109666004355b600160a060020a0381166000908152601460205260409020545b919050565b6109666004356024356000600034111561259957610002565b610966600062e6b680420360026000505410806106505750600354600160a060020a0390811633909116145b80156106645750600254621274ff19420190105b156126145750426002908155600180549091028155610983565b610966600435600a6020526000908152604090205481565b610966600435602435600060006000600060006000341115611ba157610002565b610a7d600854600160a060020a031681565b610966600c5481565b61096660005460001901610983565b61096660025481565b61096660043560006000600060003411156121fc57610002565b6109665b6001610983565b6109666004356024355b60115460009060ff16801561072f5750600f5442115b801561248757506124853361044b565b61096660115460ff1681565b6109666004355b60006000600f600050544210801561076a5750600034115b80156107a457506011546101009004600160a060020a0316600014806107a457506011546101009004600160a060020a0390811633909116145b15610b9f57610a9c61037f565b610a7d600435600060006000508281548110156100025750508080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56b600e83020180548290811015610002575081526020902060030154600160a060020a0316610606565b61096660043560243560006000610e1b336105ec565b6109665b6000600034111561247c57610002565b61096660043560056020526000908152604090205481565b610966600435602435604435600061252f845b6000600060003411156127ac57610002565b610966600435602435600160a060020a0382811660009081526015602090815260408083209385168352929052205461033f565b610a9a600435600034111561254557610002565b610966600435600b6020526000908152604090205481565b610a7d600354600160a060020a031681565b604080516020606435600481810135601f81018490048402850184019095528484526109669481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600034111561103257610002565b610a7d6011546101009004600160a060020a031681565b60408051918252519081900360200190f35b610980610708565b90505b90565b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b50509d505050505050505050505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b005b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f150505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c575060115460ff16155b15610b94576011805460ff1916600117905560165460408051918252517ff381a3e2428fdda36615919e8d9c35878d9eb0cf85ac6edf575088e80e4c147e9181900360200190a15b600191505b50919050565b610002565b600f5442118015610bb8575060115460ff16155b15610de357601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040516012549051600160a060020a039190911631109050610cc9576040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f19250505015610de35733600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a03168152602001908152602001600020600050819055505b565b4262054600600f60005054031115610e13576201518062127500600f60005054034203046014019050610983565b50601e610983565b60001415610e2857610002565b6000341115610e3657610002565b6000805485908110156100025750600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb05750600c810160205260406000205460ff165b80610ebf575060038101544210155b15610ec957610002565b8215610f0f5733600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b565b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff191660011790555b33600160a060020a03166000908152600b60205260408120541415610f77576040600020849055610feb565b33600160a060020a03166000908152600b60205260408120548154811015610002579080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb5733600160a060020a03166000908152600b602052604090208490555b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a35092915050565b6000805487908110156100025750808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816005016000505414915050949350505050565b600014156110ce57610002565b82801561111857508660001415806110e857508451600014155b806111005750600354600160a060020a038981169116145b8061110b5750600034115b80611118575062093a8084105b1561112257610002565b8215801561114257506111348861115c565b158061114257506212750084105b156111fe57610002565b83546118e590600160a060020a03165b600160a060020a03811660009081526004602052604081205460ff16806111f15750601254600160a060020a039081169083161480156111f15750601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051516006541190505b156129a157506001610606565b6249d40084111561120e57610002565b60115460ff1615806112215750600f5442105b806112365750600c5434108015611236575082155b1561124057610002565b42844201101561124f57610002565b30600160a060020a031633600160a060020a0316141561126e57610002565b60008054600181018083559091908280158290116112a557600e0281600e0283600052602060002091820191016112a5919061136a565b505060008054929450918491508110156100025750808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257805160ff19168380011785555b5061149292915061144a565b5050600060098201819055600a820155600d81018054600160a060020a03191690556001015b8082111561145e578054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057505b506000600383018190556004808401805461ffff19169055600584018290556006840182905560078401805460ff191690556008840180548382559083526020909220611344929091028101905b8082111561145e57600080825560018201818155600283019190915560039091018054600160a060020a03191690556113fc565b601f0160209004906000526020600020908101906113ae91905b8082111561145e576000815560010161144a565b5090565b82800160010185558215611338579182015b82811115611338578251826000505591602001919060010190611474565b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857600881018054600181018083559091908280158290116115735760040281600402836000526020600020918201910161157391906113fc565b505050505b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f150905090810190601f1680156116485780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2509695505050505050565b6040805186815260208101839052815189927fdfc78bdca8e3e0b18c16c5c99323c6cb9eb5e00afde190b4e7273f5158702b07928290030190a25b5050505092915050565b6000805488908110156100025750808052600e8802600080516020612a36833981519152019050600781015490945060ff166116e757620d2f006116ec565b622398805b600485015490935060ff16801561170857506003840154830142115b15611716576117b887611890565b600384015442108061172d5750600484015460ff16155b806117ae57508360000160009054906101000a9004600160a060020a03168460010160005054876040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020846005016000505414155b1561114c57610002565b61169e565b60048401805461ff001916610100179055835460019550600160a060020a03908116309091161480159061180157508354600754600160a060020a03908116911614155b801561181d57506008548454600160a060020a03908116911614155b801561183957508354601254600160a060020a03908116911614155b801561185557506003548454600160a060020a03908116911614155b1561188b5760018401805430600160a060020a031660009081526005602052604090208054919091019055546006805490910190555b611663875b6000600060005082815481101561000257908052600e02600080516020612a36833981519152018150600481015490915060ff16156118d757600d80546006830154900390555b600401805460ff1916905550565b15156118f45761190087611890565b6001915061193161047f565b604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050505061169e565b6001850154111561194157600091505b50600a8301546009840154865191019060049010801590611986575085600081518110156100025790602001015160f860020a900460f860020a02606860f860020a02145b80156119b6575085600181518110156100025790602001015160f860020a900460f860020a02603760f860020a02145b80156119e6575085600281518110156100025790602001015160f860020a900460f860020a0260ff60f860020a02145b8015611a16575085600381518110156100025790602001015160f860020a900460f860020a02601e60f860020a02145b8015611a45575030600160a060020a0316600090815260056020526040902054611a4290611a5d61047f565b81105b15611a4f57600091505b6001840154611a8090611a5f565b015b30600160a060020a03166000908152600560205260408120546129a961047f565b8110611ad457604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050501515611abc57610002565b4260025560165460059004811115611ad45760056001555b6001840154611ae290611a5f565b8110158015611af85750600a8401546009850154115b8015611b015750815b1561188b578360000160009054906101000a9004600160a060020a0316600160a060020a0316846001016000505487604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611b7d5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f19250505015156117bd57610002565b611baa336105ec565b60001415611bb757610002565b60008054889081101561000257508052600e87027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566810154600080516020612a36833981519152919091019450421080611c1957506003840154622398800142115b80611c3257508354600160a060020a0390811690871614155b80611c425750600784015460ff16155b80611c68575033600160a060020a03166000908152600b8501602052604090205460ff16155b80611c9c575033600160a060020a03166000908152600b60205260409020548714801590611c9c5750604060009081205414155b15611ca657610002565b600884018054600090811015610002579081526020812060030154600160a060020a03161415611e1257611efc86604051600090600160a060020a038316907f9046fefd66f538ab35263248a44217dcb70e2eb2cd136629e141b8b8f9f03b60908390a260408051600e547fe2faf044000000000000000000000000000000000000000000000000000000008252600160a060020a03858116600484015260248301859052604483018590526223988042016064840152925192169163e2faf04491608480820192602092909190829003018187876161da5a03f1156100025750506040515191506106069050565b6008850180546000908110156100025781815260208082209390935530600160a060020a031681526005909252604082205481549092908110156100025790815260208120905060020155601654600885018054600090811015610002579081526020812090506001015560048401805461ff0019166101001790555b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090505433600160a060020a031660009081526014602052604081205460088801805493909102939093049550908110156100025790815260208120905060030154604080517fbaac530000000000000000000000000000000000000000000000000000000000815233600160a060020a0390811660048301529151929091169163baac53009186916024808301926020929190829003018185886185025a03f11561000257505060405151600014159150611f78905057610002565b60088501805460009081101561000257818152602081206003018054600160a060020a03191690931790925580549091908110156100025790815260208120905060030154600160a060020a031660001415611f5757610002565b600d5430600160a060020a0316311015611f7057610002565b611d9561047f565b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090506002015433600160a060020a0390811660009081526014602090815260408083205430909416835260058083528184205460099093529083205460088b018054969095029690960497509487020494508593929091908290811015610002575260208120815060030154600160a060020a0390811682526020828101939093526040918201600090812080549095019094553016835260059091529020548290101561205357610002565b30600160a060020a031660009081526005602052604081208054849003905560088501805483926009929091829081101561000257508152602080822060030154600160a060020a039081168352929052604080822080549094019093553090911681522054819010156120c657610002565b30600160a060020a0390811660009081526009602090815260408083208054869003905533909316808352601482528383205484519081529351929390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36121383361086c565b5033600160a060020a03166000908152601460209081526040808320805460168054919091039055839055600a9091528120556001945061169e565b30600160a060020a0390811660008181526005602090815260408083208054958716808552828520805490970190965584845283905560099091528082208054948352908220805490940190935590815290555b50565b604051600160a060020a0382811691309091163190600081818185876185025a03f192505050151561217457610002565b33600160a060020a03818116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f028352935197995091969195929092169363d2cc718f936004848101949193929183900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a03168152602001908152602001600020600050540204101561229d57610002565b600160a060020a03338116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f02835293519296909593169363d2cc718f93600483810194929383900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a0316815260200190815260200160002060005054020403905083156123ec57600860009054906101000a9004600160a060020a0316600160a060020a0316630221038a83600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a031660048201526024810186905290516044808301935060209282900301816000876161da5a03f115610002575050604051511515905061245457610002565b6040805160085460e160020a63011081c5028252600160a060020a038581166004840152602483018590529251921691630221038a9160448082019260209290919082900301816000876161da5a03f115610002575050604051511515905061245457610002565b600160a060020a03331660009081526009602052604090208054909101905550600192915050565b6109803361086c565b155b80156124a257506124a23384845b6000600061293a856105ec565b80156124be57506124be83836000600034111561261c57610002565b15610b9f5750600161033f565b15156124d657610002565b6124e08383610719565b905061033f565b155b80156124fb57506124fb848484612495565b80156125185750612518848484600060003411156126c157610002565b15610b9f57506001612528565b90505b9392505050565b151561253a57610002565b61252584848461041b565b30600160a060020a031633600160a060020a031614158061258a575030600160a060020a031660009081526005602052604090205460649061258561047f565b010481115b1561259457610002565b600c55565b600354600160a060020a0390811633909116146125b557610002565b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f565b506000610983565b33600160a060020a03166000908152601460205260409020548290108015906126455750600082115b156126b957600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f565b50600061033f565b600160a060020a03841660009081526014602052604090205482901080159061270a5750601560209081526040600081812033600160a060020a03168252909252902054829010155b80156127165750600082115b156127a457600160a060020a03838116600081815260146020908152604080832080548801905588851680845281842080548990039055601583528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001612528565b506000612528565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f11561000257505060405151905061281a866105ec565b0204101561282757610002565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f115610002575050604051519050612895866105ec565b0204039050600760009054906101000a9004600160a060020a0316600160a060020a0316630221038a84836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061291357610002565b600160a060020a0383166000908152600a6020526040902080548201905560019150610b99565b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857610002565b600160a060020a038581166000908152600a60205260408082208054859003905591861681522080548201905560019150509392505050565b506000610606565b0160030260166000505483020460016000505460166000505404019050610606565b600160a060020a0383166000908152600b6020526040812054815481101561000257818052600e02600080516020612a368339815191520190506003810154909150421115610b9457600160a060020a0383166000908152600b602052604081208190559150610b9956290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563",
- "nonce": "3",
- "storage": {
- "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000057bda071",
- "0x0000000000000000000000000000000000000000000000000000000000000010": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000011": "0x0000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c18941301",
- "0x0000000000000000000000000000000000000000000000000000000000000012": "0x000000000000000000000000fde8d5f77ef48bb7bf5766c7404691b9ee1dfca7",
- "0x0000000000000000000000000000000000000000000000000000000000000016": "0x00000000000000000000000000000000000000000000081f158e2814b4ab624c",
- "0x7ffc832d0c7f56b16d03bf3ff14bc4dd6a6cb1ec75841f7397362f4a9be4d392": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xaccfa2662c944e8eae80b7720d9d232eb6809c18f6c8da65189acbb38069d869": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x630a0cd35d5bd57e61410fda76fea850225cda18": {
- "balance": "0x0",
- "code": "0x6060604052361561006c5760e060020a60003504630121b93f81146100e15780636637b882146101615780636dbf2fa0146101935780638da5cb5b1461026a578063a6f9dae11461027c578063beabacc8146102ae578063d979f5aa14610322578063e1fa763814610354575b61050b600060006000600460005054111561051d576004805460001901905560015460035460055460e260020a6320998771026060908152606492909252600160a060020a03908116608452909116906382661dc49060a49060209060448187876161da5a03f11561000257506105c3915050565b6105cb60043560005433600160a060020a039081169116141561015e57600180547fc9d27afe0000000000000000000000000000000000000000000000000000000060609081526064849052608492909252600160a060020a03169063c9d27afe9060a4906020906044816000876161da5a03f115610002575050505b50565b6105cb60043560005433600160a060020a039081169116141561015e5760018054600160a060020a0319168217905550565b60806020604435600481810135601f8101849004909302840160405260608381526105cb9482359460248035956064949391019190819083828082843750949650505050505050600054600160a060020a039081163390911614156102655782600160a060020a03168282604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561024b5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f1505050505b505050565b6105cd600054600160a060020a031681565b6105cb60043560005433600160a060020a039081169116141561015e5760008054600160a060020a0319168217905550565b6105cb6004356024356044356000805433600160a060020a039081169116141561031c5760e060020a63a9059cbb026060908152600160a060020a03848116606452608484905285929083169163a9059cbb9160a4916020916044908290876161da5a03f115610002575050505b50505050565b6105cb60043560005433600160a060020a039081169116141561015e5760028054600160a060020a0319168217905550565b6105cb60043560243560005433600160a060020a03908116911614156105075760015460e060020a6370a0823102606090815230600160a060020a0390811660645291909116906370a08231906084906020906024816000876161da5a03f1156100025750506040805180516006556002546001547f1a695230000000000000000000000000000000000000000000000000000000008352600160a060020a039081166004840152925192169250631a695230916024828101926000929190829003018183876161da5a03f1156100025750505060048181556003839055600154604080517f013cf08b00000000000000000000000000000000000000000000000000000000815292830185905251600160a060020a03919091169163013cf08b91602482810192602092919082900301816000876161da5a03f11561000257505060408051805160058054600160a060020a0319169091179081905560015460035460e260020a63209987710284526004840152600160a060020a0391821660248401529251921692506382661dc491604482810192602092919082900301816000876161da5a03f115610002575050505b5050565b60408051918252519081900360200190f35b60015460e060020a6370a0823102606090815230600160a060020a0390811660645291909116906370a082319060849060209060248187876161da5a03f11561000257505060408051805160015460025460e060020a63a9059cbb028452600160a060020a039081166004850152602484018390529351919550909216925063a9059cbb916044828101926020929190829003018188876161da5a03f115610002575050505b600191505090565b005b6060908152602090f3",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000e6002189a74b43e6868b20c1311bc108e38aac57",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c189413",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000006e073c0e1bd5af550239025dffcfb37175acedd3",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x6e073c0e1bd5af550239025dffcfb37175acedd3": {
- "balance": "0x0",
- "code": "0x606060405260e060020a60003504631a69523081146100475780636dbf2fa01461006d5780638da5cb5b14610144578063a6f9dae114610156578063beabacc814610196575b005b610045600435600080548190819032600160a060020a0390811691161461022957610002565b60806020604435600481810135601f8101849004909302840160405260608381526100459482359460248035956064949391019190819083828082843750949650505050505050600054600160a060020a0390811633909116141561013f5782600160a060020a03168282604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101255780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f1505050505b505050565b61021f600054600160a060020a031681565b61004560043560005433600160a060020a0390811691161415610193576000805473ffffffffffffffffffffffffffffffffffffffff1916821790555b50565b6100456004356024356044356000805433600160a060020a0390811691161415610343577fa9059cbb000000000000000000000000000000000000000000000000000000006060908152600160a060020a03808516606452608484905285929083169163a9059cbb9160a4916020916044908290876161da5a03f1156100025750505050505050565b6060908152602090f35b7f70a0823100000000000000000000000000000000000000000000000000000000606090815230600160a060020a039081166064528594508416906370a082319060849060209060248187876161da5a03f1156100025750506040805180517f18160ddd00000000000000000000000000000000000000000000000000000000825291519194506318160ddd916004828101926020929190829003018187876161da5a03f11561000257505050604051805190602001509050808211156102ee579050805b82600160a060020a031663a9059cbb33846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050505b5050505056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000e6002189a74b43e6868b20c1311bc108e38aac57"
- }
- },
- "0xbb9bc244d798123fde783fcc1c72d3bb8c189413": {
- "balance": "0x53d2c8df046dd3db5",
- "code": "0x6060604052361561020e5760e060020a6000350463013cf08b8114610247578063095ea7b3146102d05780630c3b7b96146103455780630e7082031461034e578063149acf9a1461036057806318160ddd146103725780631f2dc5ef1461037b57806321b5b8dd1461039b578063237e9492146103ad57806323b872dd1461040e5780632632bf2014610441578063341458081461047257806339d1f9081461047b5780634b6753bc146104935780634df6d6cc1461049c5780634e10c3ee146104b7578063590e1ae3146104ca578063612e45a3146104db578063643f7cdd1461057a578063674ed066146105925780636837ff1e1461059b57806370a08231146105e5578063749f98891461060b57806378524b2e1461062457806381f03fcb1461067e57806382661dc41461069657806382bf6464146106b75780638b15a605146106c95780638d7af473146106d257806396d7f3f5146106e1578063a1da2fb9146106ea578063a3912ec814610704578063a9059cbb1461070f578063b7bc2c841461073f578063baac53001461074b578063be7c29c1146107b1578063c9d27afe14610817578063cc9ae3f61461082d578063cdef91d014610841578063dbde198814610859578063dd62ed3e1461087e578063e33734fd146108b2578063e5962195146108c6578063e66f53b7146108de578063eceb2945146108f0578063f8c80d261461094f575b610966600f546000906234bc000142108015610239575060125433600160a060020a03908116911614155b156109785761098033610752565b6109866004356000805482908110156100025750808052600e8202600080516020612a3683398151915201905060038101546004820154600683015460018401548454600786015460058701546009880154600a890154600d8a0154600160a060020a039586169b509599600201989760ff81811698610100909204811697949691951693168c565b61096660043560243533600160a060020a03908116600081815260156020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b61096660105481565b610a7d600754600160a060020a031681565b610a7d600e54600160a060020a031681565b61096660165481565b6109665b60004262127500600f60005054031115610de557506014610983565b610a7d601254600160a060020a031681565b60408051602060248035600481810135601f810185900485028601850190965285855261096695813595919460449492939092019181908401838280828437509496505050505050506000600060006000600060003411156116a857610002565b6109666004356024356044355b60115460009060ff1680156104315750600f5442115b80156124e957506124e78461044b565b6109666000610980335b600160a060020a0381166000908152600b602052604081205481908114156129cb57610b99565b61096660065481565b6109665b600d5430600160a060020a03163103610983565b610966600f5481565b61096660043560046020526000908152604090205460ff1681565b61096660043560243560006124cb610831565b610a9a6000341115610ba457610002565b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec565b61096660043560096020526000908152604090205481565b61096660015481565b610a9a60043530600160a060020a031633600160a060020a03161415806105db5750600160a060020a03811660009081526004602052604090205460ff16155b156121cb576121c8565b6109666004355b600160a060020a0381166000908152601460205260409020545b919050565b6109666004356024356000600034111561259957610002565b610966600062e6b680420360026000505410806106505750600354600160a060020a0390811633909116145b80156106645750600254621274ff19420190105b156126145750426002908155600180549091028155610983565b610966600435600a6020526000908152604090205481565b610966600435602435600060006000600060006000341115611ba157610002565b610a7d600854600160a060020a031681565b610966600c5481565b61096660005460001901610983565b61096660025481565b61096660043560006000600060003411156121fc57610002565b6109665b6001610983565b6109666004356024355b60115460009060ff16801561072f5750600f5442115b801561248757506124853361044b565b61096660115460ff1681565b6109666004355b60006000600f600050544210801561076a5750600034115b80156107a457506011546101009004600160a060020a0316600014806107a457506011546101009004600160a060020a0390811633909116145b15610b9f57610a9c61037f565b610a7d600435600060006000508281548110156100025750508080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56b600e83020180548290811015610002575081526020902060030154600160a060020a0316610606565b61096660043560243560006000610e1b336105ec565b6109665b6000600034111561247c57610002565b61096660043560056020526000908152604090205481565b610966600435602435604435600061252f845b6000600060003411156127ac57610002565b610966600435602435600160a060020a0382811660009081526015602090815260408083209385168352929052205461033f565b610a9a600435600034111561254557610002565b610966600435600b6020526000908152604090205481565b610a7d600354600160a060020a031681565b604080516020606435600481810135601f81018490048402850184019095528484526109669481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600034111561103257610002565b610a7d6011546101009004600160a060020a031681565b60408051918252519081900360200190f35b610980610708565b90505b90565b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b50509d505050505050505050505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b005b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f150505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c575060115460ff16155b15610b94576011805460ff1916600117905560165460408051918252517ff381a3e2428fdda36615919e8d9c35878d9eb0cf85ac6edf575088e80e4c147e9181900360200190a15b600191505b50919050565b610002565b600f5442118015610bb8575060115460ff16155b15610de357601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040516012549051600160a060020a039190911631109050610cc9576040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f19250505015610de35733600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a03168152602001908152602001600020600050819055505b565b4262054600600f60005054031115610e13576201518062127500600f60005054034203046014019050610983565b50601e610983565b60001415610e2857610002565b6000341115610e3657610002565b6000805485908110156100025750600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb05750600c810160205260406000205460ff165b80610ebf575060038101544210155b15610ec957610002565b8215610f0f5733600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b565b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff191660011790555b33600160a060020a03166000908152600b60205260408120541415610f77576040600020849055610feb565b33600160a060020a03166000908152600b60205260408120548154811015610002579080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb5733600160a060020a03166000908152600b602052604090208490555b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a35092915050565b6000805487908110156100025750808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816005016000505414915050949350505050565b600014156110ce57610002565b82801561111857508660001415806110e857508451600014155b806111005750600354600160a060020a038981169116145b8061110b5750600034115b80611118575062093a8084105b1561112257610002565b8215801561114257506111348861115c565b158061114257506212750084105b156111fe57610002565b83546118e590600160a060020a03165b600160a060020a03811660009081526004602052604081205460ff16806111f15750601254600160a060020a039081169083161480156111f15750601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051516006541190505b156129a157506001610606565b6249d40084111561120e57610002565b60115460ff1615806112215750600f5442105b806112365750600c5434108015611236575082155b1561124057610002565b42844201101561124f57610002565b30600160a060020a031633600160a060020a0316141561126e57610002565b60008054600181018083559091908280158290116112a557600e0281600e0283600052602060002091820191016112a5919061136a565b505060008054929450918491508110156100025750808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257805160ff19168380011785555b5061149292915061144a565b5050600060098201819055600a820155600d81018054600160a060020a03191690556001015b8082111561145e578054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057505b506000600383018190556004808401805461ffff19169055600584018290556006840182905560078401805460ff191690556008840180548382559083526020909220611344929091028101905b8082111561145e57600080825560018201818155600283019190915560039091018054600160a060020a03191690556113fc565b601f0160209004906000526020600020908101906113ae91905b8082111561145e576000815560010161144a565b5090565b82800160010185558215611338579182015b82811115611338578251826000505591602001919060010190611474565b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857600881018054600181018083559091908280158290116115735760040281600402836000526020600020918201910161157391906113fc565b505050505b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f150905090810190601f1680156116485780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2509695505050505050565b6040805186815260208101839052815189927fdfc78bdca8e3e0b18c16c5c99323c6cb9eb5e00afde190b4e7273f5158702b07928290030190a25b5050505092915050565b6000805488908110156100025750808052600e8802600080516020612a36833981519152019050600781015490945060ff166116e757620d2f006116ec565b622398805b600485015490935060ff16801561170857506003840154830142115b15611716576117b887611890565b600384015442108061172d5750600484015460ff16155b806117ae57508360000160009054906101000a9004600160a060020a03168460010160005054876040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020846005016000505414155b1561114c57610002565b61169e565b60048401805461ff001916610100179055835460019550600160a060020a03908116309091161480159061180157508354600754600160a060020a03908116911614155b801561181d57506008548454600160a060020a03908116911614155b801561183957508354601254600160a060020a03908116911614155b801561185557506003548454600160a060020a03908116911614155b1561188b5760018401805430600160a060020a031660009081526005602052604090208054919091019055546006805490910190555b611663875b6000600060005082815481101561000257908052600e02600080516020612a36833981519152018150600481015490915060ff16156118d757600d80546006830154900390555b600401805460ff1916905550565b15156118f45761190087611890565b6001915061193161047f565b604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050505061169e565b6001850154111561194157600091505b50600a8301546009840154865191019060049010801590611986575085600081518110156100025790602001015160f860020a900460f860020a02606860f860020a02145b80156119b6575085600181518110156100025790602001015160f860020a900460f860020a02603760f860020a02145b80156119e6575085600281518110156100025790602001015160f860020a900460f860020a0260ff60f860020a02145b8015611a16575085600381518110156100025790602001015160f860020a900460f860020a02601e60f860020a02145b8015611a45575030600160a060020a0316600090815260056020526040902054611a4290611a5d61047f565b81105b15611a4f57600091505b6001840154611a8090611a5f565b015b30600160a060020a03166000908152600560205260408120546129a961047f565b8110611ad457604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050501515611abc57610002565b4260025560165460059004811115611ad45760056001555b6001840154611ae290611a5f565b8110158015611af85750600a8401546009850154115b8015611b015750815b1561188b578360000160009054906101000a9004600160a060020a0316600160a060020a0316846001016000505487604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611b7d5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f19250505015156117bd57610002565b611baa336105ec565b60001415611bb757610002565b60008054889081101561000257508052600e87027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566810154600080516020612a36833981519152919091019450421080611c1957506003840154622398800142115b80611c3257508354600160a060020a0390811690871614155b80611c425750600784015460ff16155b80611c68575033600160a060020a03166000908152600b8501602052604090205460ff16155b80611c9c575033600160a060020a03166000908152600b60205260409020548714801590611c9c5750604060009081205414155b15611ca657610002565b600884018054600090811015610002579081526020812060030154600160a060020a03161415611e1257611efc86604051600090600160a060020a038316907f9046fefd66f538ab35263248a44217dcb70e2eb2cd136629e141b8b8f9f03b60908390a260408051600e547fe2faf044000000000000000000000000000000000000000000000000000000008252600160a060020a03858116600484015260248301859052604483018590526223988042016064840152925192169163e2faf04491608480820192602092909190829003018187876161da5a03f1156100025750506040515191506106069050565b6008850180546000908110156100025781815260208082209390935530600160a060020a031681526005909252604082205481549092908110156100025790815260208120905060020155601654600885018054600090811015610002579081526020812090506001015560048401805461ff0019166101001790555b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090505433600160a060020a031660009081526014602052604081205460088801805493909102939093049550908110156100025790815260208120905060030154604080517fbaac530000000000000000000000000000000000000000000000000000000000815233600160a060020a0390811660048301529151929091169163baac53009186916024808301926020929190829003018185886185025a03f11561000257505060405151600014159150611f78905057610002565b60088501805460009081101561000257818152602081206003018054600160a060020a03191690931790925580549091908110156100025790815260208120905060030154600160a060020a031660001415611f5757610002565b600d5430600160a060020a0316311015611f7057610002565b611d9561047f565b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090506002015433600160a060020a0390811660009081526014602090815260408083205430909416835260058083528184205460099093529083205460088b018054969095029690960497509487020494508593929091908290811015610002575260208120815060030154600160a060020a0390811682526020828101939093526040918201600090812080549095019094553016835260059091529020548290101561205357610002565b30600160a060020a031660009081526005602052604081208054849003905560088501805483926009929091829081101561000257508152602080822060030154600160a060020a039081168352929052604080822080549094019093553090911681522054819010156120c657610002565b30600160a060020a0390811660009081526009602090815260408083208054869003905533909316808352601482528383205484519081529351929390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36121383361086c565b5033600160a060020a03166000908152601460209081526040808320805460168054919091039055839055600a9091528120556001945061169e565b30600160a060020a0390811660008181526005602090815260408083208054958716808552828520805490970190965584845283905560099091528082208054948352908220805490940190935590815290555b50565b604051600160a060020a0382811691309091163190600081818185876185025a03f192505050151561217457610002565b33600160a060020a03818116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f028352935197995091969195929092169363d2cc718f936004848101949193929183900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a03168152602001908152602001600020600050540204101561229d57610002565b600160a060020a03338116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f02835293519296909593169363d2cc718f93600483810194929383900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a0316815260200190815260200160002060005054020403905083156123ec57600860009054906101000a9004600160a060020a0316600160a060020a0316630221038a83600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a031660048201526024810186905290516044808301935060209282900301816000876161da5a03f115610002575050604051511515905061245457610002565b6040805160085460e160020a63011081c5028252600160a060020a038581166004840152602483018590529251921691630221038a9160448082019260209290919082900301816000876161da5a03f115610002575050604051511515905061245457610002565b600160a060020a03331660009081526009602052604090208054909101905550600192915050565b6109803361086c565b155b80156124a257506124a23384845b6000600061293a856105ec565b80156124be57506124be83836000600034111561261c57610002565b15610b9f5750600161033f565b15156124d657610002565b6124e08383610719565b905061033f565b155b80156124fb57506124fb848484612495565b80156125185750612518848484600060003411156126c157610002565b15610b9f57506001612528565b90505b9392505050565b151561253a57610002565b61252584848461041b565b30600160a060020a031633600160a060020a031614158061258a575030600160a060020a031660009081526005602052604090205460649061258561047f565b010481115b1561259457610002565b600c55565b600354600160a060020a0390811633909116146125b557610002565b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f565b506000610983565b33600160a060020a03166000908152601460205260409020548290108015906126455750600082115b156126b957600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f565b50600061033f565b600160a060020a03841660009081526014602052604090205482901080159061270a5750601560209081526040600081812033600160a060020a03168252909252902054829010155b80156127165750600082115b156127a457600160a060020a03838116600081815260146020908152604080832080548801905588851680845281842080548990039055601583528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001612528565b506000612528565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f11561000257505060405151905061281a866105ec565b0204101561282757610002565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f115610002575050604051519050612895866105ec565b0204039050600760009054906101000a9004600160a060020a0316600160a060020a0316630221038a84836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061291357610002565b600160a060020a0383166000908152600a6020526040902080548201905560019150610b99565b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857610002565b600160a060020a038581166000908152600a60205260408082208054859003905591861681522080548201905560019150509392505050565b506000610606565b0160030260166000505483020460016000505460166000505404019050610606565b600160a060020a0383166000908152600b6020526040812054815481101561000257818052600e02600080516020612a368339815191520190506003810154909150421115610b9457600160a060020a0383166000908152600b602052604081208190559150610b9956290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563",
- "nonce": "3",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000120",
- "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000057495e10",
- "0x0000000000000000000000000000000000000000000000000000000000000011": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0x0000000000000000000000000000000000000000000000000000000000000016": "0x000000000000000000000000000000000000000000098b4d3b425f8c368391b2",
- "0x29066f14bd0b438bb3db8771a65febf0be7574be7528f87e7ae11aafc2b2c3ac": "0x000000000000000000000000000000000000000000000025d57ab057892050fc",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f443": "0x000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e650",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f444": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f445": "0x0000000000000000000000000000000000000000000000000000000000000093",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f446": "0x00000000000000000000000000000000000000000000000000000000579a07ea",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f447": "0x0000000000000000000000000000000000000000000000000000000000000101",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f448": "0x63c103e1feea47a9bf6c0dce1349da1a95b96532661d43063ab8e52b3e2a844b",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f449": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f44a": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f44b": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f44c": "0x00000000000000000000000000000000000000000000000001620725a3de2009",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f44d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f450": "0x000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e650",
- "0x3987ba2457a57cc6778cce06d8c58970029977d834f0de345c7a495612cbb060": "0x00000000000000000000000000000000000000000000081f2acc2a62590de041",
- "0x3987ba2457a57cc6778cce06d8c58970029977d834f0de345c7a495612cbb061": "0x000000000000000000000000000000000000000000098b4d3b425f8c368391b2",
- "0x3987ba2457a57cc6778cce06d8c58970029977d834f0de345c7a495612cbb062": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000",
- "0x3987ba2457a57cc6778cce06d8c58970029977d834f0de345c7a495612cbb063": "0x00000000000000000000000010abb5efecdc09581f8b7cb95791fe2936790b4e",
- "0x6f125332c6f598e8798f0c277f4b1052ac80cd02ff2eebe0c7f362d63b6959ef": "0x000000000000000000000000000000000000000000000000008dc9007b27b5a9",
- "0x793bebaf0ea12c858c08547e9aa88b849bba94bb6933c7bdb0fecbb707ecf5c7": "0x00000000000000000000000000000000000000000000076d52eebfbfbfc172e5",
- "0xaccfa2662c944e8eae80b7720d9d232eb6809c18f6c8da65189acbb38069d869": "0x000000000000000000000000000000000000000000000000000289739e60e3e2",
- "0xb6e4d5c52e0c64fb49c5a97cacdbcf8bd94b5bd4d490590326a19d27eaf543ae": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xbe273e24e8bd646e29d1fb5a924a12a8585095b9f45a317fc708165a127fdd70": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xc34fc4bc1a730d3f836c9ac5124865056e88f3776b63662e34976bdb47549077": "0x000000000000000000000000000000000000000000000036353be4c563784a57",
- "0xe2112d92b8a1d00a569b85fbe7a384a5c9f74f5ff8478647397cb58dde254ffa": "0x53706c697420666f722070656f706c652077686f2073656e74206d6f6e657920",
- "0xe2112d92b8a1d00a569b85fbe7a384a5c9f74f5ff8478647397cb58dde254ffb": "0x746f207468652044414f20616674657220746865204861726420466f726b2062",
- "0xe2112d92b8a1d00a569b85fbe7a384a5c9f74f5ff8478647397cb58dde254ffc": "0x79206d697374616b650000000000000000000000000000000000000000000000",
- "0xf60322aa1a2e769d412b36e4a9def4300f7540bf1bc9e0f4691786a9100145fa": "0x0000000000000000000000000000000000000000000000000000000062188dd2",
- "0xf735edeea40e4ec771f49da7f7b854b398a1ad43f8a9617d43e53d3093e9fdc0": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xf7905fa5d54027d5d59f4678dda481331babad2d3d0fdefd552afbce2e74c07e": "0x0000000000000000000000000000000000000000000000000000000000000110"
- }
- },
- "0xe6002189a74b43e6868b20c1311bc108e38aac57": {
- "balance": "0x29129264d1ae4848b",
- "nonce": "45"
- },
- "0xea674fdde714fd979de3edf0f56aa9716b898ec8": {
- "balance": "0x1601bbe4c58ec73210",
- "nonce": "337736"
- },
- "0xfde8d5f77ef48bb7bf5766c7404691b9ee1dfca7": {
- "balance": "0x0",
- "code": "0x606060405236156100405760e060020a60003504630221038a811461004d57806318bdc79a146100aa5780638da5cb5b146100be578063d2cc718f146100d0575b6100d96001805434019055565b6100db6004356024356000805433600160a060020a0390811691161415806100755750600034115b806100a05750805460a060020a900460ff1680156100a057508054600160a060020a03848116911614155b156100f757610002565b6100db60005460ff60a060020a9091041681565b6100ed600054600160a060020a031681565b6100db60015481565b005b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a0383168260608381818185876185025a03f1925050501561015c57604080518381529051600160a060020a038516917f9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc919081900360200190a25060015b9291505056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "1968180",
- "difficulty": "56311715252709",
- "timestamp": "1469713694",
- "gasLimit": "4712388",
- "miner": "0xea674fdde714fd979de3edf0f56aa9716b898ec8"
- },
- "input": "0xf8aa2d850c2b6f9f7e830aae6094630a0cd35d5bd57e61410fda76fea850225cda1880b844e1fa7638000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000001ba0563f81ca66b2c618bf4be9470fab88fff1b44eb5c33a9c73a68e8b26fbaa7c8da041464789c49fee77d2e053ff0705bc845fe2a78a35e478132371f294bb594021",
- "tracerConfig": {
- "withLog": true
- },
- "result": {
- "from": "0xe6002189a74b43e6868b20c1311bc108e38aac57",
- "gas": "0xaae60",
- "gasUsed": "0xaae60",
- "to": "0x630a0cd35d5bd57e61410fda76fea850225cda18",
- "input": "0xe1fa763800000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000000",
- "error": "invalid jump destination",
- "calls": [
- {
- "from": "0x630a0cd35d5bd57e61410fda76fea850225cda18",
- "gas": "0x9f5a0",
- "gasUsed": "0x314",
- "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
- "input": "0x70a08231000000000000000000000000630a0cd35d5bd57e61410fda76fea850225cda18",
- "output": "0x000000000000000000000000000000000000000000000000000289739e60e3e2",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x630a0cd35d5bd57e61410fda76fea850225cda18",
- "gas": "0x9a327",
- "gasUsed": "0x67b0",
- "to": "0x6e073c0e1bd5af550239025dffcfb37175acedd3",
- "input": "0x1a695230000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c189413",
- "calls": [
- {
- "from": "0x6e073c0e1bd5af550239025dffcfb37175acedd3",
- "gas": "0x93ff6",
- "gasUsed": "0x314",
- "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
- "input": "0x70a082310000000000000000000000006e073c0e1bd5af550239025dffcfb37175acedd3",
- "output": "0x000000000000000000000000000000000000000000000025d57ab057892050fc",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e073c0e1bd5af550239025dffcfb37175acedd3",
- "gas": "0x93c42",
- "gasUsed": "0x13f",
- "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
- "input": "0x18160ddd",
- "output": "0x000000000000000000000000000000000000000000098b4d3b425f8c368391b2",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x6e073c0e1bd5af550239025dffcfb37175acedd3",
- "gas": "0x939ba",
- "gasUsed": "0x5fca",
- "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
- "input": "0xa9059cbb000000000000000000000000630a0cd35d5bd57e61410fda76fea850225cda18000000000000000000000000000000000000000000000025d57ab057892050fc",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x630a0cd35d5bd57e61410fda76fea850225cda18",
- "gas": "0x8d8b6",
- "gasUsed": "0x7be",
- "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
- "input": "0x013cf08b0000000000000000000000000000000000000000000000000000000000000110",
- "output": "0x000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000579a07ea0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000163c103e1feea47a9bf6c0dce1349da1a95b96532661d43063ab8e52b3e2a844b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000001620725a3de20090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e650000000000000000000000000000000000000000000000000000000000000004953706c697420666f722070656f706c652077686f2073656e74206d6f6e657920746f207468652044414f20616674657220746865204861726420466f726b206279206d697374616b650000000000000000000000000000000000000000000000",
- "value": "0x0",
- "type": "CALL"
- },
- {
- "from": "0x630a0cd35d5bd57e61410fda76fea850225cda18",
- "gas": "0x880f8",
- "gasUsed": "0x880f8",
- "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
- "input": "0x82661dc40000000000000000000000000000000000000000000000000000000000000110000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e650",
- "error": "invalid jump destination",
- "calls": [
- {
- "from": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
- "gas": "0x7f910",
- "gasUsed": "0xd20f",
- "to": "0x10abb5efecdc09581f8b7cb95791fe2936790b4e",
- "input": "0xbaac5300000000000000000000000000630a0cd35d5bd57e61410fda76fea850225cda18",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "calls": [
- {
- "from": "0x10abb5efecdc09581f8b7cb95791fe2936790b4e",
- "gas": "0x76e12",
- "gasUsed": "0x13f9",
- "to": "0xfde8d5f77ef48bb7bf5766c7404691b9ee1dfca7",
- "input": "0x",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x20320625e3126cb0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json
deleted file mode 100644
index 6faf898a0f..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json
+++ /dev/null
@@ -1,108 +0,0 @@
-{
- "genesis": {
- "difficulty": "45372803248884",
- "extraData": "0x65746865726d696e652e6f7267202855533129",
- "gasLimit": "4712388",
- "hash": "0xa2b18cc64ec062676680f2bb2d880205dcd372f4396722f2294d3fceece96193",
- "miner": "0xea674fdde714fd979de3edf0f56aa9716b898ec8",
- "mixHash": "0xce7c26a9238b249edcdcd51f0ea1ad0e632e872daf9a09f039d918bcaeb7194f",
- "nonce": "0x849d49e634e93bb5",
- "number": "1646451",
- "stateRoot": "0x2bd193b9911caf43204960cc7661ce864bf0bac7f9b60191aa02bbff24f061fb",
- "timestamp": "1465103859",
- "totalDifficulty": "24813742796574158431",
- "alloc": {
- "0x01115b41bd2731353dd3e6abf44818fdc035aaf1": {
- "balance": "0x16d99e16e809000",
- "nonce": "23"
- },
- "0x61c808d82a3ac53231750dadc13c777b59310bd9": {
- "balance": "0x6a636960e34bd696f4",
- "nonce": "36888"
- },
- "0xbb9bc244d798123fde783fcc1c72d3bb8c189413": {
- "balance": "0x9b37460cdbcba74181f81",
- "code": "0x6060604052361561020e5760e060020a6000350463013cf08b8114610247578063095ea7b3146102d05780630c3b7b96146103455780630e7082031461034e578063149acf9a1461036057806318160ddd146103725780631f2dc5ef1461037b57806321b5b8dd1461039b578063237e9492146103ad57806323b872dd1461040e5780632632bf2014610441578063341458081461047257806339d1f9081461047b5780634b6753bc146104935780634df6d6cc1461049c5780634e10c3ee146104b7578063590e1ae3146104ca578063612e45a3146104db578063643f7cdd1461057a578063674ed066146105925780636837ff1e1461059b57806370a08231146105e5578063749f98891461060b57806378524b2e1461062457806381f03fcb1461067e57806382661dc41461069657806382bf6464146106b75780638b15a605146106c95780638d7af473146106d257806396d7f3f5146106e1578063a1da2fb9146106ea578063a3912ec814610704578063a9059cbb1461070f578063b7bc2c841461073f578063baac53001461074b578063be7c29c1146107b1578063c9d27afe14610817578063cc9ae3f61461082d578063cdef91d014610841578063dbde198814610859578063dd62ed3e1461087e578063e33734fd146108b2578063e5962195146108c6578063e66f53b7146108de578063eceb2945146108f0578063f8c80d261461094f575b610966600f546000906234bc000142108015610239575060125433600160a060020a03908116911614155b156109785761098033610752565b6109866004356000805482908110156100025750808052600e8202600080516020612a3683398151915201905060038101546004820154600683015460018401548454600786015460058701546009880154600a890154600d8a0154600160a060020a039586169b509599600201989760ff81811698610100909204811697949691951693168c565b61096660043560243533600160a060020a03908116600081815260156020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b61096660105481565b610a7d600754600160a060020a031681565b610a7d600e54600160a060020a031681565b61096660165481565b6109665b60004262127500600f60005054031115610de557506014610983565b610a7d601254600160a060020a031681565b60408051602060248035600481810135601f810185900485028601850190965285855261096695813595919460449492939092019181908401838280828437509496505050505050506000600060006000600060003411156116a857610002565b6109666004356024356044355b60115460009060ff1680156104315750600f5442115b80156124e957506124e78461044b565b6109666000610980335b600160a060020a0381166000908152600b602052604081205481908114156129cb57610b99565b61096660065481565b6109665b600d5430600160a060020a03163103610983565b610966600f5481565b61096660043560046020526000908152604090205460ff1681565b61096660043560243560006124cb610831565b610a9a6000341115610ba457610002565b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec565b61096660043560096020526000908152604090205481565b61096660015481565b610a9a60043530600160a060020a031633600160a060020a03161415806105db5750600160a060020a03811660009081526004602052604090205460ff16155b156121cb576121c8565b6109666004355b600160a060020a0381166000908152601460205260409020545b919050565b6109666004356024356000600034111561259957610002565b610966600062e6b680420360026000505410806106505750600354600160a060020a0390811633909116145b80156106645750600254621274ff19420190105b156126145750426002908155600180549091028155610983565b610966600435600a6020526000908152604090205481565b610966600435602435600060006000600060006000341115611ba157610002565b610a7d600854600160a060020a031681565b610966600c5481565b61096660005460001901610983565b61096660025481565b61096660043560006000600060003411156121fc57610002565b6109665b6001610983565b6109666004356024355b60115460009060ff16801561072f5750600f5442115b801561248757506124853361044b565b61096660115460ff1681565b6109666004355b60006000600f600050544210801561076a5750600034115b80156107a457506011546101009004600160a060020a0316600014806107a457506011546101009004600160a060020a0390811633909116145b15610b9f57610a9c61037f565b610a7d600435600060006000508281548110156100025750508080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56b600e83020180548290811015610002575081526020902060030154600160a060020a0316610606565b61096660043560243560006000610e1b336105ec565b6109665b6000600034111561247c57610002565b61096660043560056020526000908152604090205481565b610966600435602435604435600061252f845b6000600060003411156127ac57610002565b610966600435602435600160a060020a0382811660009081526015602090815260408083209385168352929052205461033f565b610a9a600435600034111561254557610002565b610966600435600b6020526000908152604090205481565b610a7d600354600160a060020a031681565b604080516020606435600481810135601f81018490048402850184019095528484526109669481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600034111561103257610002565b610a7d6011546101009004600160a060020a031681565b60408051918252519081900360200190f35b610980610708565b90505b90565b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b50509d505050505050505050505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b005b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f150505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c575060115460ff16155b15610b94576011805460ff1916600117905560165460408051918252517ff381a3e2428fdda36615919e8d9c35878d9eb0cf85ac6edf575088e80e4c147e9181900360200190a15b600191505b50919050565b610002565b600f5442118015610bb8575060115460ff16155b15610de357601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040516012549051600160a060020a039190911631109050610cc9576040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f19250505015610de35733600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a03168152602001908152602001600020600050819055505b565b4262054600600f60005054031115610e13576201518062127500600f60005054034203046014019050610983565b50601e610983565b60001415610e2857610002565b6000341115610e3657610002565b6000805485908110156100025750600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb05750600c810160205260406000205460ff165b80610ebf575060038101544210155b15610ec957610002565b8215610f0f5733600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b565b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff191660011790555b33600160a060020a03166000908152600b60205260408120541415610f77576040600020849055610feb565b33600160a060020a03166000908152600b60205260408120548154811015610002579080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb5733600160a060020a03166000908152600b602052604090208490555b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a35092915050565b6000805487908110156100025750808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816005016000505414915050949350505050565b600014156110ce57610002565b82801561111857508660001415806110e857508451600014155b806111005750600354600160a060020a038981169116145b8061110b5750600034115b80611118575062093a8084105b1561112257610002565b8215801561114257506111348861115c565b158061114257506212750084105b156111fe57610002565b83546118e590600160a060020a03165b600160a060020a03811660009081526004602052604081205460ff16806111f15750601254600160a060020a039081169083161480156111f15750601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051516006541190505b156129a157506001610606565b6249d40084111561120e57610002565b60115460ff1615806112215750600f5442105b806112365750600c5434108015611236575082155b1561124057610002565b42844201101561124f57610002565b30600160a060020a031633600160a060020a0316141561126e57610002565b60008054600181018083559091908280158290116112a557600e0281600e0283600052602060002091820191016112a5919061136a565b505060008054929450918491508110156100025750808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257805160ff19168380011785555b5061149292915061144a565b5050600060098201819055600a820155600d81018054600160a060020a03191690556001015b8082111561145e578054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057505b506000600383018190556004808401805461ffff19169055600584018290556006840182905560078401805460ff191690556008840180548382559083526020909220611344929091028101905b8082111561145e57600080825560018201818155600283019190915560039091018054600160a060020a03191690556113fc565b601f0160209004906000526020600020908101906113ae91905b8082111561145e576000815560010161144a565b5090565b82800160010185558215611338579182015b82811115611338578251826000505591602001919060010190611474565b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857600881018054600181018083559091908280158290116115735760040281600402836000526020600020918201910161157391906113fc565b505050505b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f150905090810190601f1680156116485780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2509695505050505050565b6040805186815260208101839052815189927fdfc78bdca8e3e0b18c16c5c99323c6cb9eb5e00afde190b4e7273f5158702b07928290030190a25b5050505092915050565b6000805488908110156100025750808052600e8802600080516020612a36833981519152019050600781015490945060ff166116e757620d2f006116ec565b622398805b600485015490935060ff16801561170857506003840154830142115b15611716576117b887611890565b600384015442108061172d5750600484015460ff16155b806117ae57508360000160009054906101000a9004600160a060020a03168460010160005054876040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020846005016000505414155b1561114c57610002565b61169e565b60048401805461ff001916610100179055835460019550600160a060020a03908116309091161480159061180157508354600754600160a060020a03908116911614155b801561181d57506008548454600160a060020a03908116911614155b801561183957508354601254600160a060020a03908116911614155b801561185557506003548454600160a060020a03908116911614155b1561188b5760018401805430600160a060020a031660009081526005602052604090208054919091019055546006805490910190555b611663875b6000600060005082815481101561000257908052600e02600080516020612a36833981519152018150600481015490915060ff16156118d757600d80546006830154900390555b600401805460ff1916905550565b15156118f45761190087611890565b6001915061193161047f565b604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050505061169e565b6001850154111561194157600091505b50600a8301546009840154865191019060049010801590611986575085600081518110156100025790602001015160f860020a900460f860020a02606860f860020a02145b80156119b6575085600181518110156100025790602001015160f860020a900460f860020a02603760f860020a02145b80156119e6575085600281518110156100025790602001015160f860020a900460f860020a0260ff60f860020a02145b8015611a16575085600381518110156100025790602001015160f860020a900460f860020a02601e60f860020a02145b8015611a45575030600160a060020a0316600090815260056020526040902054611a4290611a5d61047f565b81105b15611a4f57600091505b6001840154611a8090611a5f565b015b30600160a060020a03166000908152600560205260408120546129a961047f565b8110611ad457604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050501515611abc57610002565b4260025560165460059004811115611ad45760056001555b6001840154611ae290611a5f565b8110158015611af85750600a8401546009850154115b8015611b015750815b1561188b578360000160009054906101000a9004600160a060020a0316600160a060020a0316846001016000505487604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611b7d5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f19250505015156117bd57610002565b611baa336105ec565b60001415611bb757610002565b60008054889081101561000257508052600e87027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566810154600080516020612a36833981519152919091019450421080611c1957506003840154622398800142115b80611c3257508354600160a060020a0390811690871614155b80611c425750600784015460ff16155b80611c68575033600160a060020a03166000908152600b8501602052604090205460ff16155b80611c9c575033600160a060020a03166000908152600b60205260409020548714801590611c9c5750604060009081205414155b15611ca657610002565b600884018054600090811015610002579081526020812060030154600160a060020a03161415611e1257611efc86604051600090600160a060020a038316907f9046fefd66f538ab35263248a44217dcb70e2eb2cd136629e141b8b8f9f03b60908390a260408051600e547fe2faf044000000000000000000000000000000000000000000000000000000008252600160a060020a03858116600484015260248301859052604483018590526223988042016064840152925192169163e2faf04491608480820192602092909190829003018187876161da5a03f1156100025750506040515191506106069050565b6008850180546000908110156100025781815260208082209390935530600160a060020a031681526005909252604082205481549092908110156100025790815260208120905060020155601654600885018054600090811015610002579081526020812090506001015560048401805461ff0019166101001790555b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090505433600160a060020a031660009081526014602052604081205460088801805493909102939093049550908110156100025790815260208120905060030154604080517fbaac530000000000000000000000000000000000000000000000000000000000815233600160a060020a0390811660048301529151929091169163baac53009186916024808301926020929190829003018185886185025a03f11561000257505060405151600014159150611f78905057610002565b60088501805460009081101561000257818152602081206003018054600160a060020a03191690931790925580549091908110156100025790815260208120905060030154600160a060020a031660001415611f5757610002565b600d5430600160a060020a0316311015611f7057610002565b611d9561047f565b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090506002015433600160a060020a0390811660009081526014602090815260408083205430909416835260058083528184205460099093529083205460088b018054969095029690960497509487020494508593929091908290811015610002575260208120815060030154600160a060020a0390811682526020828101939093526040918201600090812080549095019094553016835260059091529020548290101561205357610002565b30600160a060020a031660009081526005602052604081208054849003905560088501805483926009929091829081101561000257508152602080822060030154600160a060020a039081168352929052604080822080549094019093553090911681522054819010156120c657610002565b30600160a060020a0390811660009081526009602090815260408083208054869003905533909316808352601482528383205484519081529351929390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36121383361086c565b5033600160a060020a03166000908152601460209081526040808320805460168054919091039055839055600a9091528120556001945061169e565b30600160a060020a0390811660008181526005602090815260408083208054958716808552828520805490970190965584845283905560099091528082208054948352908220805490940190935590815290555b50565b604051600160a060020a0382811691309091163190600081818185876185025a03f192505050151561217457610002565b33600160a060020a03818116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f028352935197995091969195929092169363d2cc718f936004848101949193929183900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a03168152602001908152602001600020600050540204101561229d57610002565b600160a060020a03338116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f02835293519296909593169363d2cc718f93600483810194929383900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a0316815260200190815260200160002060005054020403905083156123ec57600860009054906101000a9004600160a060020a0316600160a060020a0316630221038a83600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a031660048201526024810186905290516044808301935060209282900301816000876161da5a03f115610002575050604051511515905061245457610002565b6040805160085460e160020a63011081c5028252600160a060020a038581166004840152602483018590529251921691630221038a9160448082019260209290919082900301816000876161da5a03f115610002575050604051511515905061245457610002565b600160a060020a03331660009081526009602052604090208054909101905550600192915050565b6109803361086c565b155b80156124a257506124a23384845b6000600061293a856105ec565b80156124be57506124be83836000600034111561261c57610002565b15610b9f5750600161033f565b15156124d657610002565b6124e08383610719565b905061033f565b155b80156124fb57506124fb848484612495565b80156125185750612518848484600060003411156126c157610002565b15610b9f57506001612528565b90505b9392505050565b151561253a57610002565b61252584848461041b565b30600160a060020a031633600160a060020a031614158061258a575030600160a060020a031660009081526005602052604090205460649061258561047f565b010481115b1561259457610002565b600c55565b600354600160a060020a0390811633909116146125b557610002565b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f565b506000610983565b33600160a060020a03166000908152601460205260409020548290108015906126455750600082115b156126b957600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f565b50600061033f565b600160a060020a03841660009081526014602052604090205482901080159061270a5750601560209081526040600081812033600160a060020a03168252909252902054829010155b80156127165750600082115b156127a457600160a060020a03838116600081815260146020908152604080832080548801905588851680845281842080548990039055601583528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001612528565b506000612528565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f11561000257505060405151905061281a866105ec565b0204101561282757610002565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f115610002575050604051519050612895866105ec565b0204039050600760009054906101000a9004600160a060020a0316600160a060020a0316630221038a84836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061291357610002565b600160a060020a0383166000908152600a6020526040902080548201905560019150610b99565b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857610002565b600160a060020a038581166000908152600a60205260408082208054859003905591861681522080548201905560019150509392505050565b506000610606565b0160030260166000505483020460016000505460166000505404019050610606565b600160a060020a0383166000908152600b6020526040812054815481101561000257818052600e02600080516020612a368339815191520190506003810154909150421115610b9457600160a060020a0383166000908152600b602052604081208190559150610b9956290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563",
- "nonce": "3",
- "storage": {
- "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000057495e10",
- "0x0000000000000000000000000000000000000000000000000000000000000012": "0x000000000000000000000000807640a13483f8ac783c557fcdf27be11ea4ac7a"
- }
- },
- "0xcf1476387d780169410d4e936d75a206fda2a68c": {
- "balance": "0x15fd0ad66ea7000",
- "code": "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e1461015f5780634123cb6b146101875780635c52c2f5146101905780637065cb48146101ba578063746c9171146101e7578063797af627146101f0578063b20d30a914610203578063b61d27f614610230578063b75c7dc614610251578063ba51a6df14610280578063c2cf7326146102ad578063cbf0b0c0146102eb578063f00d4b5d14610318578063f1736d861461034a575b61035460003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610354600435600060003660405180838380828437820191505092505050604051809103902061064a815b600160a060020a03331660009081526101026020526040812054818082811415610c6657610dbf565b6103566004355b600160a060020a03811660009081526101026020526040812054115b919050565b61035660015481565b61035460003660405180838380828437820191505092505050604051809103902061078b81610136565b6103546004356000366040518083838082843782019150509250505060405180910390206105c681610136565b61035660005481565b6103566004355b600081610a2781610136565b61035460043560003660405180838380828437820191505092505050604051809103902061077f81610136565b6103566004803590602480359160443591820191013560006107aa33610166565b610354600435600160a060020a03331660009081526101026020526040812054908082811415610368576103e7565b61035460043560003660405180838380828437820191505092505050604051809103902061070881610136565b610356600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054828181141561076157610776565b61035460043560003660405180838380828437820191505092505050604051809103902061079981610136565b610354600435602435600060003660405180838380828437820191505092505050604051809103902061047281610136565b6103566101055481565b005b60408051918252519081900360200190f35b50506000828152610103602052604081206001810154600284900a9290831611156103e75780546001828101805492909101835590839003905560408051600160a060020a03331681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b50505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a1505b505050565b156103e75761048083610166565b1561048b575061046d565b600160a060020a0384166000908152610102602052604081205492508214156104b4575061046d565b6103ed5b6101045460005b81811015610f0b57610104805461010891600091849081101561000257600080516020610fd88339815191520154825250602091909152604081208054600160a060020a0319168155600181810183905560028281018054858255939493909281161561010002600019011604601f819010610f9057505b5050506001016104bf565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005055600154600160a060020a03831660008181526101026020908152604091829020939093558051918252517f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3929181900390910190a15b505b50565b156105c1576105d482610166565b156105df57506105c3565b6105e76104b8565b60015460fa90106105fa576105fa61060f565b60015460fa901061054257506105c3565b6106c75b60015b6001548110156105c3575b6001548110801561063d5750600281610100811015610002570154600014155b15610dc75760010161061d565b1561046d57600160a060020a03831660009081526101026020526040812054925082141561067857506105c1565b600160016000505403600060005054111561069357506105c1565b600060028361010081101561000257508301819055600160a060020a0384168152610102602052604081205561060b6104b8565b60408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b156105c15760015482111561071d57506105c3565b600082905561072a6104b8565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001820154600282900a9081166000141593505b50505092915050565b156105c1575061010555565b156105c35760006101065550565b156105c15781600160a060020a0316ff5b156109eb576107be846000610ea133610166565b1561087d577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843782019150509250505060006040518083038185876185025a03f150600093506109eb92505050565b6000364360405180848480828437820191505082815260200193505050506040518091039020905080506108b0816101f7565b1580156108d3575060008181526101086020526040812054600160a060020a0316145b156109eb5760008181526101086020908152604082208054600160a060020a0319168817815560018181018890556002918201805481865294849020909491821615610100026000190190911691909104601f9081019290920481019185919087908390106109f35760ff198135168380011785555b506109659291505b80821115610a235760008155600101610951565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b82800160010185558215610949579182015b82811115610949578235826000505591602001919060010190610a05565b5090565b15610aaa5760008381526101086020526040812054600160a060020a031614610aaa5760408051600091909120805460018281015460029384018054600160a060020a0394909416959194909391928392859291811615610100026000190116048015610adb5780601f10610ab057610100808354040283529160200191610adb565b50919050565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505091505060006040518083038185876185025a03f1505050600084815261010860209081526040918290208054600180830154855133600160a060020a0381811683529682018c9052968101829052929094166060830181905260a06080840181815260029586018054948516156101000260001901909416959095049084018190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a97508a95949193919060c083019084908015610bdd5780601f10610bb257610100808354040283529160200191610bdd565b820191906000526020600020905b815481529060010190602001808311610bc057829003601f168201915b5050965050505050505060405180910390a16000838152610108602052604081208054600160a060020a0319168155600181810183905560028281018054858255939493909281161561010002600019011604601f819010610c4857505b5050506001915050610182565b601f016020900490600052602060002090810190610c3b9190610951565b60008581526101036020526040812080549093501415610cee576000805483556001838101919091556101048054918201808255828015829011610cbd57818360005260206000209182019101610cbd9190610951565b50505060028301819055610104805487929081101561000257600091909152600080516020610fd883398151915201555b506001810154600283900a90811660001415610dbf5760408051600160a060020a03331681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1815460019011610dac576000858152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610fd8833981519152929092018190558082556001828101829055600292909201559450610dbf9050565b8154600019018255600182018054821790555b505050919050565b5b60018054118015610dea57506001546002906101008110156100025701546000145b15610dfe5760018054600019019055610dc8565b60015481108015610e215750600154600290610100811015610002570154600014155b8015610e3b57506002816101008110156100025701546000145b15610e9c57600154600290610100811015610002578101549082610100811015610002579090016000505580610102600060028361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b610612565b156101825761010754610eb75b62015180420490565b1115610ed057600061010655610ecb610eae565b610107555b6101065480830110801590610eed57506101055461010654830111155b15610f0357506101068054820190556001610182565b506000610182565b6105c16101045460005b81811015610fae5761010480548290811015610002576000918252600080516020610fd8833981519152015414610f8857610104805461010391600091849081101561000257600080516020610fd883398151915201548252506020919091526040812081815560018101829055600201555b600101610f15565b601f0160209004906000526020600020908101906105379190610951565b610104805460008083559190915261046d90600080516020610fd883398151915290810190610951564c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000105": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000106": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000107": "0x000000000000000000000000000000000000000000000000000000000000423d",
- "0xcabd288dcb1ace4f49c34e8ac2d843772952b4226b3c832bdb4ac1ddca0f7c05": "0x0000000000000000000000000000000000000000000000000000000000000002"
- }
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "1646452",
- "difficulty": "45328493887096",
- "timestamp": "1465103894",
- "gasLimit": "4712388",
- "miner": "0x61c808d82a3ac53231750dadc13c777b59310bd9"
- },
- "input": "0xf9018b178504a817c80083030d4094cf1476387d780169410d4e936d75a206fda2a68c80b90124b61d27f6000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c189413000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000088613930353963626230303030303030303030303030303030303030303030303039306433633138313264653236363962663830376264373735386365623165333439376163376534303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316336626635323633343030300000000000000000000000000000000000000000000000001ca0f1ae5ea07b1d00eb5e06fc854124ee0234ec61c8b393147f9d030804a75c98daa01d045d7633012cca74e30e975c3d00d11b4243dd8648f2e78d652f3a8aaafceb",
- "tracerConfig": {
- "withLog": true
- },
- "result": {
- "from": "0x01115b41bd2731353dd3e6abf44818fdc035aaf1",
- "gas": "0x30d40",
- "gasUsed": "0x288c9",
- "to": "0xcf1476387d780169410d4e936d75a206fda2a68c",
- "input": "0xb61d27f6000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c18941300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008861393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030000000000000000000000000000000000000000000000000",
- "output": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "calls": [
- {
- "from": "0xcf1476387d780169410d4e936d75a206fda2a68c",
- "gas": "0x1e30b",
- "gasUsed": "0x1e30b",
- "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
- "input": "0x61393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030",
- "error": "invalid jump destination",
- "value": "0x0",
- "type": "CALL"
- }
- ],
- "logs": [
- {
- "address": "0xcf1476387d780169410d4e936d75a206fda2a68c",
- "topics": [
- "0x92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004"
- ],
- "data": "0x00000000000000000000000001115b41bd2731353dd3e6abf44818fdc035aaf10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c1894130000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008861393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030",
- "position": "0x0"
- }
- ],
- "value": "0x0",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json
deleted file mode 100644
index e73081107f..0000000000
--- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json
+++ /dev/null
@@ -1,89 +0,0 @@
-{
- "genesis": {
- "difficulty": "11934798510088",
- "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773",
- "gasLimit": "3141592",
- "hash": "0xfc543a4a551afbd4a6c5d6d49041371e6bb58b1108c12aaec7f487ce656bb97f",
- "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
- "mixHash": "0xa6a1e67fc68da76b8d9cc3ce1c45d5e1f4bbd96b5dcfddbe0017d7fa99903ead",
- "nonce": "0x5f00c600268b4659",
- "number": "995200",
- "stateRoot": "0x3579328470dd2aef5b9da69f5480cbe0d375e653b530ab3c1aee0da5e1ff4c94",
- "timestamp": "1455322761",
- "totalDifficulty": "7077231809278509672",
- "alloc": {
- "0x200edd17f30485a8735878661960cd7a9a95733f": {
- "balance": "0x0",
- "code": "0x3660008037602060003660003473273930d21e01ee25e4c219b63259d214872220a261235a5a03f21560015760206000f3",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "0x0000000000000000000000000000000000000000000000000000000000000104": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf04": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf05": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf06": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xa611e7c895a426c0477bc9e280db9c3b1e456dc6310ffcf23926ef5186c1facc": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c410e": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c410f": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c4110": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x273930d21e01ee25e4c219b63259d214872220a2": {
- "balance": "0x0",
- "code": "0x606060405236156100da5760e060020a6000350463173825d9811461012c5780632f54bf6e146101875780634123cb6b146101af57806352375093146101b857806354fd4d50146101c25780635c52c2f5146101cc578063659010e7146101fd5780637065cb4814610207578063746c91711461023b578063797af62714610244578063b20d30a914610257578063b61d27f61461028b578063b75c7dc6146102ac578063ba51a6df146102db578063c2cf73261461030f578063cbf0b0c01461034d578063f00d4b5d14610381578063f1736d86146103ba575b6103c4600034111561012a5760408051600160a060020a033216815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b6103c46004356000600036436040518084848082843750505090910190815260405190819003602001902090506106c9815b600160a060020a03321660009081526101026020526040812054818082811415610c3f57610d97565b6103c66004355b600160a060020a03811660009081526101026020526040812054115b919050565b6103c660015481565b6103c66101075481565b6103c66101085481565b6103c46000364360405180848480828437505050909101908152604051908190036020019020905061081a8161015e565b6103c66101065481565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506106418161015e565b6103c660005481565b6103c66004355b600081610a7d8161015e565b6103c46004356000364360405180848480828437505050909101908152604051908190036020019020905061080e8161015e565b6103c66004803590602480359160443591820191013560006108393261018e565b6103c4600435600160a060020a033216600090815261010260205260408120549080828114156103d857610457565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506107888161015e565b6103c6600435602435600082815261010360209081526040808320600160a060020a038516845261010290925282205482818114156107e157610805565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506108288161015e565b6103c46004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104e28161015e565b6103c66101055481565b005b60408051918252519081900360200190f35b50506000828152610103602052604081206001810154600284900a9290831611156104575780546001828101805492909101835590839003905560408051600160a060020a03321681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b50505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a1505b505050565b15610457576104f08361018e565b156104fb57506104dd565b600160a060020a03841660009081526101026020526040812054925082141561052457506104dd565b61045d5b6101045460005b81811015610ee457610104805461010991600091849081101561000257600080516020610f9f83398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f6992601f9290920104810190610a65565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561063c5761064f8261018e565b1561065a575061063e565b610662610528565b60015460fa90106106775761067561068c565b505b60015460fa90106105a2575061063e565b6107465b600060015b600154811015610a79575b600154811080156106bc5750600281610100811015610002570154600014155b15610d9f5760010161069c565b156104dd57600160a060020a0383166000908152610102602052604081205492508214156106f7575061063c565b6001600160005054036000600050541115610712575061063c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610688610528565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561063c5760015482111561079d575061063e565b60008290556107aa610528565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001820154600282900a908116600014156108005760009350610805565b600193505b50505092915050565b1561063c575061010555565b1561063e5760006101065550565b1561063c5781600160a060020a0316ff5b15610a555761084d846000610e793261018e565b15610909577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00432858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a5592505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061093990508161024b565b15801561095c575060008181526101096020526040812054600160a060020a0316145b15610a555760008181526101096020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a5d579182015b82811115610a5d5782358260005055916020019190600101906109b1565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328132868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b506109cf9291505b80821115610a795760008155600101610a65565b5090565b15610c2c5760008381526101096020526040812054600160a060020a031614610c2c5760408051600091909120805460018201546002929092018054600160a060020a0392909216939091819083908015610afd57820191906000526020600020905b815481529060010190602001808311610ae057829003601f168201915b505091505060006040518083038185876185025a03f150505060008481526101096020908152604080519281902080546001820154600160a060020a033281811688529587018b905293860181905292166060850181905260a06080860181815260029390930180549187018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a975094958a959293909160c083019084908015610bcf57820191906000526020600020905b815481529060010190602001808311610bb257829003601f168201915b5050965050505050505060405180910390a160008381526101096020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c3292601f9290920104810190610a65565b50919050565b50505060019150506101aa565b60008581526101036020526040812080549093501415610cc7576000805483556001838101919091556101048054918201808255828015829011610c9657818360005260206000209182019101610c969190610a65565b50505060028301819055610104805487929081101561000257600091909152600080516020610f9f83398151915201555b506001810154600283900a90811660001415610d975760408051600160a060020a03321681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1815460019011610d84576000858152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f9f8339815191529290920181905580825560018083018290556002909201559450610d979050565b8154600019018255600182018054821790555b505050919050565b5b60018054118015610dc257506001546002906101008110156100025701546000145b15610dd65760018054600019019055610da0565b60015481108015610df95750600154600290610100811015610002570154600014155b8015610e1357506002816101008110156100025701546000145b15610e7457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b610691565b156101aa5761010754610e8f5b62015180420490565b1115610ea857600061010655610ea3610e86565b610107555b6101065480830110801590610ec65750610106546101055490830111155b15610edc575061010680548201905560016101aa565b5060006101aa565b61063c6101045460005b81811015610f745761010480548290811015610002576000918252600080516020610f9f833981519152015414610f6157610104805461010391600091849081101561000257600080516020610f9f83398151915201548252506020919091526040812081815560018101829055600201555b600101610eee565b50505060010161052f565b61010480546000808355919091526104dd90600080516020610f9f83398151915290810190610a6556004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe"
- },
- "0x4f5777744b500616697cb655dcb02ee6cd51deb5": {
- "balance": "0xb0983f1b83eec290",
- "nonce": "2"
- },
- "0xf8b483dba2c3b7176a3da549ad41a48bb3121069": {
- "balance": "0x16969a0ba2c2d384d07",
- "nonce": "67521"
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "995201",
- "difficulty": "11940626048551",
- "timestamp": "1455322773",
- "gasLimit": "3141592",
- "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069"
- },
- "input": "0xf89102850a954d522e8303308594200edd17f30485a8735878661960cd7a9a95733f888ac7230489e80000a4ba51a6df00000000000000000000000000000000000000000000000000000000000000001ca04f2cc45b96f965296382b2e9b657e90808301d5179035a5d91a2de7b912def20a056e19271ea4e19e4e034f38e925e312beed4d300c267160eeb2f565c42deb578",
- "tracerConfig": {
- "withLog": true,
- "onlyTopCall": true
- },
- "result": {
- "from": "0x4f5777744b500616697cb655dcb02ee6cd51deb5",
- "gas": "0x33085",
- "gasUsed": "0x1a9e5",
- "to": "0x200edd17f30485a8735878661960cd7a9a95733f",
- "input": "0xba51a6df0000000000000000000000000000000000000000000000000000000000000000",
- "output": "0xba51a6df00000000000000000000000000000000000000000000000000000000",
- "value": "0x8ac7230489e80000",
- "type": "CALL"
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json
deleted file mode 100644
index a34d3b759e..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json
+++ /dev/null
@@ -1,85 +0,0 @@
-{
- "genesis": {
- "difficulty": "6217248151198",
- "extraData": "0xd783010103844765746887676f312e342e32856c696e7578",
- "gasLimit": "3141592",
- "hash": "0xe8bff55fe3e61936ef321cf3afaeb1ba2f7234e1e89535fa8ae39963caebe9c3",
- "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5",
- "mixHash": "0x03da00d5a15a064e5ebddf53cd0aaeb9a8aff0f40c0fb031a74f463d11ec83b8",
- "nonce": "0x6575fe08c4167044",
- "number": "243825",
- "stateRoot": "0x47182fe2e6e740b8a76f82fe5c527d6ad548f805274f21792cf4047235b24fbf",
- "timestamp": "1442424328",
- "totalDifficulty": "1035061827427752845",
- "alloc": {
- "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": {
- "balance": "0xc820f93200f4000",
- "nonce": "0x5E",
- "code": "0x"
- },
- "0x332b656504f4eabb44c8617a42af37461a34e9dc": {
- "balance": "0x11faea4f35e5af80000",
- "code": "0x"
- },
- "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": {
- "balance": "0xbf681825be002ac452",
- "nonce": "0x70FA",
- "code": "0x"
- },
- "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": {
- "balance": "0xb3d0ac5cb94df6f6b0",
- "nonce": "0x1",
- "code": "0x"
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "243826",
- "difficulty": "6214212385501",
- "timestamp": "1442424353",
- "gasLimit": "3141592",
- "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5"
- },
- "input": "0xf8e85e850ba43b7400830f42408080b89660606040527382effbaaaf28614e55b2ba440fb198e0e5789b0f600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600a80608c6000396000f30060606040526008565b001ca0340b21661e5bb85a46319a15f33a362e5c0f02faa7cdbf9c5808b2134da968eaa0226e6788f8c20e211d436ab7f6298ef32fa4c23a509eeeaac0880d115c17bc3f",
- "result": {
- "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": {
- "balance": "0xc820f93200f4000",
- "nonce": 94
- },
- "0x332b656504f4eabb44c8617a42af37461a34e9dc": {
- "balance": "0x11faea4f35e5af80000",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": {
- "balance": "0xbf681825be002ac452",
- "nonce": 28922
- },
- "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": {
- "balance": "0xb3d0ac5cb94df6f6b0",
- "nonce": 1
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json
deleted file mode 100644
index 7204bfcbfe..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json
+++ /dev/null
@@ -1,83 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "result": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "nonce": 22
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "nonce": 1,
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "nonce": 29072
- },
- "0x1585936b53834b021f68cc13eeefdec2efc8e724": {
- "balance": "0x0"
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json
deleted file mode 100644
index 44b1f08dd3..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "result": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": 22,
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": 1,
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": 29072,
- "storage": {}
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json
deleted file mode 100644
index 1b09622474..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json
+++ /dev/null
@@ -1,102 +0,0 @@
-{
- "genesis": {
- "difficulty": "13756228101629",
- "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773",
- "gasLimit": "3141592",
- "hash": "0x58b7a87b6ba10b46b4e251d64ebc3d9822dd82218eaf24dff6796f6f1f687251",
- "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
- "mixHash": "0x5984b9a316116bd890e6e5f4c52d655184b0d7aa74821e1382d7760f9803c1dd",
- "nonce": "0xea4bb4997242c681",
- "number": "1061221",
- "stateRoot": "0x5402c04d481414248d824c3b61e924e0c9307adbc9fbaae774a74cce30a4163d",
- "timestamp": "1456458069",
- "totalDifficulty": "7930751135586064334",
- "alloc": {
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x9fb6b81e112638b886",
- "nonce": "217865",
- "code": "0x"
- },
- "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
- "balance": "0x15b6828e22bb12188",
- "nonce": "747",
- "code": "0x"
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "ethash": {}
- }
- },
- "context": {
- "number": "1061222",
- "difficulty": "13749511193633",
- "timestamp": "1456458097",
- "gasLimit": "3141592",
- "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
- },
- "input": "0xf905498202eb850ba43b7400830f42408080b904f460606040526040516102b43803806102b48339016040526060805160600190602001505b5b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b806001600050908051906020019082805482825590600052602060002090601f01602090048101928215609e579182015b82811115609d5782518260005055916020019190600101906081565b5b50905060c5919060a9565b8082111560c1576000818150600090555060010160a9565b5090565b50505b506101dc806100d86000396000f30060606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001ee7b225f6964223a225a473466784a7245323639384866623839222c22666f726d5f736f75726365223a22434c54523031222c22636f6d6d69746d656e745f64617465223a22222c22626f72726f7765725f6e616d65223a22222c22626f72726f7765725f616464726573735f6c696e6531223a22222c22626f72726f7765725f616464726573735f6c696e6532223a22222c22626f72726f7765725f636f6e74616374223a22222c22626f72726f7765725f7374617465223a22222c22626f72726f7765725f74797065223a22222c2270726f70657274795f61646472657373223a22222c226c6f616e5f616d6f756e745f7772697474656e223a22222c226c6f616e5f616d6f756e74223a22222c224c54565f7772697474656e223a22222c224c5456223a22222c2244534352223a22222c2270726f70657274795f74797065223a22222c2270726f70657274795f6465736372697074696f6e223a22222c226c656e646572223a22222c2267756172616e746f7273223a22222c226c696d69746564223a22222c226361705f616d6f756e74223a22222c226361705f70657263656e745f7772697474656e223a22222c226361705f70657263656e74616765223a22222c227465726d5f7772697474656e223a22222c227465726d223a22222c22657874656e64223a22227d0000000000000000000000000000000000001ba027d54712289af34f0ec0f06092745104d68e5801cd17097bc1104111f855258da070ec9f1c942d9bedf89f9660a684d3bb8cd9c2ac7f6dd883cb3e26a193180244",
- "tracerConfig": {
- "diffMode": true
- },
- "result": {
- "pre": {
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x9fb6b81e112638b886",
- "nonce": 217865
- },
- "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
- "balance": "0x15b6828e22bb12188",
- "nonce": 747
- }
- },
- "post": {
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x9fb71abdd2621d8886"
- },
- "0x40f2f445da6c9047554683fb382fba6769717116": {
- "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f0c5cef39b17c213cfe090a46b8c7760ffb7928a",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000000000000000001ee",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": "0x7b225f6964223a225a473466784a7245323639384866623839222c22666f726d",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7": "0x5f736f75726365223a22434c54523031222c22636f6d6d69746d656e745f6461",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8": "0x7465223a22222c22626f72726f7765725f6e616d65223a22222c22626f72726f",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9": "0x7765725f616464726573735f6c696e6531223a22222c22626f72726f7765725f",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa": "0x616464726573735f6c696e6532223a22222c22626f72726f7765725f636f6e74",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfb": "0x616374223a22222c22626f72726f7765725f7374617465223a22222c22626f72",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfc": "0x726f7765725f74797065223a22222c2270726f70657274795f61646472657373",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfd": "0x223a22222c226c6f616e5f616d6f756e745f7772697474656e223a22222c226c",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfe": "0x6f616e5f616d6f756e74223a22222c224c54565f7772697474656e223a22222c",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cff": "0x224c5456223a22222c2244534352223a22222c2270726f70657274795f747970",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d00": "0x65223a22222c2270726f70657274795f6465736372697074696f6e223a22222c",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d01": "0x226c656e646572223a22222c2267756172616e746f7273223a22222c226c696d",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d02": "0x69746564223a22222c226361705f616d6f756e74223a22222c226361705f7065",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d03": "0x7263656e745f7772697474656e223a22222c226361705f70657263656e746167",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d04": "0x65223a22222c227465726d5f7772697474656e223a22222c227465726d223a22",
- "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d05": "0x222c22657874656e64223a22227d000000000000000000000000000000000000"
- }
- },
- "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": {
- "balance": "0x15b058920efcc5188",
- "nonce": 748
- }
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json
deleted file mode 100644
index e80dad5667..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json
+++ /dev/null
@@ -1,94 +0,0 @@
-{
- "genesis": {
- "baseFeePerGas": "51088069741",
- "difficulty": "14315558652874667",
- "extraData": "0xd883010a10846765746888676f312e31362e35856c696e7578",
- "gasLimit": "30058590",
- "hash": "0xdf6b95183f99054fb6541e3b482c0109c9f6be40553cff24efa3ac76736adbf5",
- "miner": "0xb7e390864a90b7b923c9f9310c6f98aafe43f707",
- "mixHash": "0x8d76b0d32e42ab277dbf00836eabef76674cd70ae2bb53718175069ad6b6147e",
- "nonce": "0x8d3a1c010ad2c687",
- "number": "14707767",
- "stateRoot": "0x8a50c896a6f7eb1f3479337db981fa10ce316281cb4dd2f07487be9ca27dae6b",
- "timestamp": "1651623275",
- "alloc": {
- "0x0000000000000000000000000000000000000000": {
- "balance": "0x268fd0b894b8c4f6d1f"
- },
- "0x13b152c9f50878ffaf3de41e192653bda545d889": {
- "balance": "0x0",
- "nonce": "1",
- "code": "0x363d3d373d3d3d363d73059ffafdc6ef594230de44f824e2bd0a51ca5ded5af43d82803e903d91602b57fd5bf3"
- },
- "0x808b4da0be6c9512e948521452227efc619bea52": {
- "balance": "0x2cdb96c56db040b43",
- "nonce": "1223932"
- },
- "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7": {
- "balance": "0x38079b28689d40240e",
- "nonce": "44"
- },
- "0xffa397285ce46fb78c588a9e993286aac68c37cd": {
- "balance": "0x0",
- "nonce": "747319",
- "code": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063b97a23191461003b578063fb90b3201461006f575b600080fd5b6100436100bd565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100bb6004803603604081101561008557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506100e1565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008282604051602001808373ffffffffffffffffffffffffffffffffffffffff1660601b815260140182815260200192505050604051602081830303815290604052805190602001209050600061015960008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168361024d565b90508073ffffffffffffffffffffffffffffffffffffffff166319ab453c856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156101c457600080fd5b505af11580156101d8573d6000803e3d6000fd5b505050507fa35ea2cc726861482a50a162c72aad60965cc64641d419cd4d675036238b52048185604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150505050565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152836037826000f5925050509291505056fea2646970667358221220c87b2492828fdd7dad3175a32a98ff07fc0eedf106536f2eddd9a016971c56a764736f6c63430007050033",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000059ffafdc6ef594230de44f824e2bd0a51ca5ded"
- }
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "terminalTotalDifficultyPassed": true,
- "ethash": {}
- }
- },
- "context": {
- "number": "14707768",
- "difficulty": "14322823549655084",
- "timestamp": "1651623279",
- "gasLimit": "30029237",
- "miner": "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7"
- },
- "input": "0x02f8b4018312acfc8459682f00851a46bcf47a8302b1a194ffa397285ce46fb78c588a9e993286aac68c37cd80b844fb90b3200000000000000000000000002a549b4af9ec39b03142da6dc32221fc390b553300000000000000000000000000000000000000000000000000000000000cb3d5c001a03002079d2873f7963c4278200c43aa71efad262b2150bc8524480acfc38b5faaa077d44aa09d56b9cf99443c7f55aaad1bbae9cfb5bbb9de31eaf7a8f9e623e980",
- "tracerConfig": {
- "diffMode": true
- },
- "result": {
- "pre": {
- "0x808b4da0be6c9512e948521452227efc619bea52": {
- "balance": "0x2cdb96c56db040b43",
- "nonce": 1223932
- },
- "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7": {
- "balance": "0x38079b28689d40240e",
- "nonce": 44
- }
- },
- "post": {
- "0x808b4da0be6c9512e948521452227efc619bea52": {
- "balance": "0x2cd72a36dd031f089",
- "nonce": 1223933
- },
- "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7": {
- "balance": "0x38079c19423e44b30e"
- }
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json
deleted file mode 100644
index fdeb0e5067..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "genesis": {
- "difficulty": "6217248151198",
- "extraData": "0xd783010103844765746887676f312e342e32856c696e7578",
- "gasLimit": "3141592",
- "hash": "0xe8bff55fe3e61936ef321cf3afaeb1ba2f7234e1e89535fa8ae39963caebe9c3",
- "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5",
- "mixHash": "0x03da00d5a15a064e5ebddf53cd0aaeb9a8aff0f40c0fb031a74f463d11ec83b8",
- "nonce": "0x6575fe08c4167044",
- "number": "243825",
- "stateRoot": "0x47182fe2e6e740b8a76f82fe5c527d6ad548f805274f21792cf4047235b24fbf",
- "timestamp": "1442424328",
- "totalDifficulty": "1035061827427752845",
- "alloc": {
- "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": {
- "balance": "0xc820f93200f4000",
- "nonce": "0x5E",
- "code": "0x"
- },
- "0x332b656504f4eabb44c8617a42af37461a34e9dc": {
- "balance": "0x11faea4f35e5af80000",
- "code": "0x",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": {
- "balance": "0xbf681825be002ac452",
- "nonce": "0x70FA",
- "code": "0x"
- },
- "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": {
- "balance": "0xb3d0ac5cb94df6f6b0",
- "nonce": "0x1",
- "code": "0x"
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "ethash": {}
- }
- },
- "context": {
- "number": "243826",
- "difficulty": "6214212385501",
- "timestamp": "1442424353",
- "gasLimit": "3141592",
- "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5"
- },
- "input": "0xf8e85e850ba43b7400830f42408080b89660606040527382effbaaaf28614e55b2ba440fb198e0e5789b0f600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600a80608c6000396000f30060606040526008565b001ca0340b21661e5bb85a46319a15f33a362e5c0f02faa7cdbf9c5808b2134da968eaa0226e6788f8c20e211d436ab7f6298ef32fa4c23a509eeeaac0880d115c17bc3f",
- "tracerConfig": {
- "diffMode": true
- },
- "result": {
- "pre": {
- "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": {
- "balance": "0xc820f93200f4000",
- "nonce": 94
- },
- "0x332b656504f4eabb44c8617a42af37461a34e9dc": {
- "balance": "0x11faea4f35e5af80000",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": {
- "balance": "0xbf681825be002ac452",
- "nonce": 28922
- },
- "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": {
- "balance": "0xb3d0ac5cb94df6f6b0",
- "nonce": 1
- }
- },
- "post": {
- "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": {
- "balance": "0xc7d4d88af8b4c00",
- "nonce": 95
- },
- "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": {
- "balance": "0xbf681ce7c870aeb852"
- },
- "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": {
- "balance": "0x1d37f515017a8eef6b0"
- }
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json
deleted file mode 100644
index 9c0030a0a8..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json
+++ /dev/null
@@ -1,312 +0,0 @@
-{
- "genesis": {
- "difficulty": "13707196986889",
- "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773",
- "gasLimit": "3141592",
- "hash": "0x607b38fe7e94427ee8f3b9a62375c67f953f8d49e05dbfd0145f9d3bac142193",
- "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069",
- "mixHash": "0x98c74c9e76fd0078157e1696e4334a7e787396459693a84536d8b96414dafd5d",
- "nonce": "0x77a5a0a73ad8745e",
- "number": "1062502",
- "stateRoot": "0x1df615df5fdbc8d5397bf3574f462f6d9696428eb8796d8e9252bccc8e3a8996",
- "timestamp": "1456480432",
- "totalDifficulty": "7948153536501153741",
- "alloc": {
- "0x0000000000000000000000000000000000000004": {
- "balance": "0x0",
- "code": "0x"
- },
- "0x1deeda36e15ec9e80f3d7414d67a4803ae45fc80": {
- "balance": "0x0",
- "code": "0x650200d2f18c7350606060405236156100c15760e060020a60003504630bd295e681146100c65780630fd1f94e1461017d5780630fee183d1461018c578063349501b7146101ad5780635054d98a146101c75780637c0278fc146101ef5780637e92656214610287578063a0943154146102f6578063a1873db61461030e578063a9d2293d14610355578063b5d0f16e146103ad578063c17e6817146103ce578063cc3471af1461046a578063da46be0a1461047a578063f55627531461052a575b610007565b6105d36004356024356044355b60006000600030915081600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515191505080841080610173575081600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015060ff16810184115b1561100d57610007565b6105d3600060f0610f6d61046e565b6105d3600435602435604435606435600081600202831015610ff657610fee565b6105d36004355b600081600014156109115750600161098f565b6105d36004355b6008810154600090819062010000900460ff16156105f257600691506105ec565b60408051602060248035600481810135601f81018590048502860185019096528585526105e5958135959194604494929390920191819084018382808284375094965050505050505060006004825103836001016000508181546001816001161561010002031660029004825481601f106108005782601f1061083a575b826008026101000360020a80910402828001178355610851565b6105e5600435602435604051600090600160a060020a038316907f398bd6b21ae4164ec322fb0eb8c2eb6277f36fd41903fbbed594dfe125591281908390a26007830154819010610e415760078301546005840154610e3f9162010000909104600160a060020a0316906103d8565b6105d3600435602435600060006000611064856101ce565b6105d36004356024356044356004830154600090819030908410156110e4577f4e4f545f454e4f5547485f47415300000000000000000000000000000000000091506112dd565b6105d35b60006000309050600a81600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515160091901935050505b5090565b6105d36004356024355b60008282111561099e578183606402049050610998565b6105d36004356024355b600030600160a060020a0316318211156103fa57600160a060020a0330163191505b6000821115610994577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc84846040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100075750839250610998915050565b6105d35b6000600f610f6d610359565b6105e560043560243560443560643560843560088501805461ff00191661010017905584543090600090819081908190819060a060020a900460e060020a02811480156104db575060018b8101546002918116156101000260001901160481145b156109b3578a5460028c0154600160a060020a039190911690895a60405191900391906000818181858888f193505050508b60080160006101000a81548160ff02191690830217905550610bfa565b6105d36004355b6000600060006000309250600a83600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151600919019350505081851115610eb05782600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450610ea89050565b60408051918252519081900360200190f35b005b600291505b50919050565b6008830154610100900460ff161561060d57600591506105ec565b30905080600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515143610109011015905061066457600091506105ec565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515143600a01101590506106d3576005830154620100009004600160a060020a0316600014156105e757600191506105ec565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151431015905061072357600391506105ec565b80600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015060ff1681600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519190910143101590506107bf57600491506105ec565b600791506105ec565b5081800160010183558181151161085157601f016020900481601f016020900483600052602060002091820191016108519190610826565b82601f106107c8575082600052602060002080549082601f016020900481019061090691905b808211156103a95760008155600101610826565b60ff19168360005260206000205581800160010183555b5050505060048251111561090c575060005b6001838101546002918116156101000260001901160481101561090c57818160040181518110156100075790602001015160f860020a900460f860020a02836001016000508281546001816001161561010002031660029004811015610007578154600116156108e25790600052602060002090602091828204019190065b601f036101000a81548160ff0219169060f860020a84040217905550600101610863565b5061026d565b505050565b604080517f5f5f6469672875696e74323536290000000000000000000000000000000000008152815190819003600e01812060e060020a9081900481028190049081028252600019850160048301529151600160a060020a03301692916102bc86029160248281019260009291908290030181838887f19450505050505b919050565b5060005b92915050565b818360020203836064020460c8039050610998565b8a5460a060020a900460e060020a0260001415610a23578a5460028c0154600160a060020a039190911690895a03908d6001016000506040518082805460018160011615610100020316600290048015610ae55780601f10610aba57610100808354040283529160200191610ae5565b60018b8101546002918116156101000260001901160460001415610b1a578a5460028c0154600160a060020a039190911690895a03908d60000160149054906101000a900460e060020a0260e060020a900491906040518360e060020a028152600401809050600060405180830381858988f19450505050508b60080160006101000a81548160ff02191690830217905550610bfa565b820191906000526020600020905b815481529060010190602001808311610ac857829003601f168201915b5050915050600060405180830381858888f193505050508b60080160006101000a81548160ff02191690830217905550610bfa565b8a5460028c0154600160a060020a039190911690895a03908d60000160149054906101000a900460e060020a0260e060020a900491908e6001016000506040518460e060020a0281526004018082805460018160011615610100020316600290048015610bc85780601f10610b9d57610100808354040283529160200191610bc8565b820191906000526020600020905b815481529060010190602001808311610bab57829003601f168201915b5050915050600060405180830381858988f19450505050508b60080160006101000a81548160ff021916908302179055505b85600160a060020a031663938b5f326040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750505060405180519060200150600160a060020a031660405180807f75706461746544656661756c745061796d656e742829000000000000000000008152602001506016019050604051809103902060e060020a8091040260e060020a90046040518160e060020a0281526004018090506000604051808303816000876161da5a03f15050505060038b0154610cc8903a6103b7565b60058c0154909550620100009004600160a060020a03908116908a161415610cf65760068b01549350610d38565b85600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450505b6064858502048b6007016000505401925060648587600160a060020a031663625cc4656040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505050604051805190602001500204915060008b60070160005081905550865a8b03013a029050610db7898285016103d8565b9250610dd773d3cda913deb6f67967b99d67acdfa1712c293601836103d8565b6040805160088e01548482526020820187905281830184905260ff1660608201529051919350600160a060020a038b16917f4538b7ec91dae8fada01e66a052482086d3e690c3db5a80457fbcd55457b4ae19181900360800190a25050505050505050505050565b505b309050610e8c81600160a060020a031663ae45850b6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515190316103d8565b505050600801805462ff0000191662010000179055565b600093505b505050919050565b600e19919091019081851115610f075782600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450610ea89050565b60ef19919091019081851115610ea357818503905060f08184600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015002049350610ea8565b03905090565b6006860181905560058601805475ffffffffffffffffffffffffffffffffffffffff000019166201000087021790556007860184905560408051600160a060020a0387168152602081019290925280517fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9281900390910190a15b949350505050565b610f7343610531565b600192505b50509392505050565b60108185031015610fff576005860154620100009004600160a060020a03166000148061105057506005860154620100009004600160a060020a03908116908616145b9250611004565b600092505b505092915050565b91503090506000821480156110c4575080600160a060020a031663ae45850b6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151600160a060020a039081169086161490505b156110d2576001925061105c565b6007821415611057576001925061105c565b6008860154610100900460ff161561111e577f414c52454144595f43414c4c454400000000000000000000000000000000000091506112dd565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051514310905080611206575080600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040805180517f0a16697a000000000000000000000000000000000000000000000000000000008252915160ff9092169291630a16697a9160048181019260209290919082900301816000876161da5a03f1156100075750506040515191909101431190505b15611233577f4e4f545f494e5f43414c4c5f57494e444f57000000000000000000000000000091506112dd565b61123e8686436100d3565b151561126c577f4e4f545f415554484f52495a454400000000000000000000000000000000000091506112dd565b6005860154600061ffff91909116118015611299575032600160a060020a031685600160a060020a031614155b80156112b4575060058601546112b29061ffff166101b4565b155b156112dd577f535441434b5f544f4f5f4445455000000000000000000000000000000000000091505b60008214610fff5760408051600160a060020a03871681526020810184905281517fdcb278834ca505ad219cf8e4b5d11f026080abef6ec68e249ea5e4d9bb3dc7b2929181900390910190a16000925061100456"
- },
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x98e1c608601c2496b2",
- "nonce": "218916",
- "code": "0x"
- },
- "0x651913977e8140c323997fce5e03c19e0015eebf": {
- "balance": "0x0",
- "code": "0x",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000000000e": "0x0000000000000000000000000000000000000000000000000000000000000000"
- }
- },
- "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": {
- "balance": "0x0",
- "nonce": "237",
- "code": "0x6060604052361561027c5760e060020a600035046301991313811461027e57806303d22885146102ca5780630450991814610323578063049ae734146103705780630ce46c43146103c35780630e85023914610602578063112e39a8146106755780631b4fa6ab146106c25780631e74a2d3146106d057806326a7985a146106fd5780633017fe2414610753578063346cabbc1461075c578063373a1bc3146107d55780633a9e74331461081e5780633c2c21a01461086e5780633d9ce89b146108ba578063480b70bd1461092f578063481078431461097e57806348f0518714610a0e5780634c471cde14610a865780634db3da8314610b09578063523ccfa814610b4f578063586a69fa14610be05780635a9f2def14610c3657806364ee49fe14610caf57806367beaccb14610d055780636840246014610d74578063795b9a6f14610dca5780637b55c8b514610e415780637c73f84614610ee15780638c0e156d14610f145780638c1d01c814610f605780638e46afa914610f69578063938c430714610fc0578063971c803f146111555780639772c982146111ac57806398c9cdf41461122857806398e00e541461127f5780639f927be7146112d5578063a00aede914611383578063a1c0539d146113d3578063aff21c6514611449578063b152f19e14611474578063b549793d146114cb578063b5b33eda1461154b578063bbc6eb1f1461159b578063c0f68859146115ab578063c3a2c0c314611601578063c43d05751461164b578063d8e5c04814611694578063dbfef71014611228578063e29fb547146116e7578063e6470fbe1461173a578063ea27a8811461174c578063ee77fe86146117d1578063f158458c14611851575b005b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387876020604051908101604052806000815260200150612225610f6d565b61188260043560243560443560643560843560a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338b8a6020604051908101604052806000815260200150896125196106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a026020604051908101604052806000815260200150611e4a610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503389896020604051908101604052806000815260200150886124e86106c6565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750506040805160a08082019092529597963596608435969095506101449450925060a491506005908390839080828437509095505050505050604080518082018252600160a060020a03338116825288166020820152815160c0810190925260009173e54d323f9ef17c1f0dede47ecc86a9718fe5ea349163e3042c0f91600191908a908a9089908b90808b8b9090602002015181526020018b60016005811015610002579090602002015181526020018b60026005811015610002579090602002015181526020018b60036005811015610002579090602002015181526020018b6004600581101561000257909060200201518152602001348152602001506040518860e060020a02815260040180888152602001876002602002808383829060006004602084601f0104600f02600301f150905001868152602001806020018560ff1681526020018461ffff168152602001836006602002808383829060006004602084601f0104600f02600301f1509050018281038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d25780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038160008760325a03f2156100025750506040515191506124cd9050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808787611e64610f6d565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611d28610f6d565b61189f5b6000611bf8611159565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881600060005054611a9561159f565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346326a7985a6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b760075b90565b604080516020606435600481810135601f8101849004840285018401909552848452611882948135946024803595604435956084949201919081908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160013389898861224b610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386866020604051908101604052806000815260200150611e64610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333896020604051908101604052806000815260200150886123bc6106c6565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387866020604051908101604052806000815260200150611f8d610f6d565b60408051602060248035600481810135601f810185900485028601850190965285855261188295813595919460449492939092019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808888612225610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503388886020604051908101604052806000815260200150612388610f6d565b611882600435604080517fc4144b2600000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163c4144b26916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133888888612238610f6d565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338b8b8b896126536106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333866020604051908101604052806000815260200150611e4a610f6d565b6118b76004355b604080517fed5bd7ea00000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163ed5bd7ea916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b61189f600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463586a69fa6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650509335935050606435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808989612388610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a896020604051908101604052806000815260200150886124d76106c6565b6040805160206004803580820135601f8101849004840285018401909552848452611882949193602493909291840191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808587611e4a610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a8a60206040519081016040528060008152602001508961262d6106c6565b604080516020606435600481810135601f810184900484028501840190955284845261188294813594602480359560443595608494920191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338888876120c7610f6d565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437505060408051608080820190925295979635969561010495509350608492508591508390839080828437509095505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989898961263a6106c6565b6118b7600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881858585611ba361122c565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050333388602060405190810160405280600081526020015061236e610f6d565b6118b760005481565b6118c95b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea34638e46afa96040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a43560c43560e43561010435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338e8e8d8f8e8e8e8e8e346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111195780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519b9a5050505050505050505050565b61189f5b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463971c803f6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650509335935050608435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989896123a2610f6d565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398c9cdf46040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398e00e546040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600435604080517fe6ce3a6a000000000000000000000000000000000000000000000000000000008152600160048201527f3e3d0000000000000000000000000000000000000000000000000000000000006024820152604481018390529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163e6ce3a6a916064818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a0260206040519081016040528060008152602001506121ef610f6d565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338787876120b5610f6d565b6118b7600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88183611b4561159f565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463b152f19e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808b8b8961262d6106c6565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386600060e060020a026020604051908101604052806000815260200150612200610f6d565b6118b75b60005460649004610759565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463c0f688596040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611bff610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333876020604051908101604052806000815260200150612200610f6d565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387600060e060020a026020604051908101604052806000815260200150612213610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338a60206040519081016040528060008152602001508961250c6106c6565b61027c6000600060006118e033610b56565b6118b7600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881868686866040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b949350505050565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338a8a8a886124fa6106c6565b6118b7600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88184846000611b4f61122c565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b60408051918252519081900360200190f35b6040805160ff929092168252519081900360200190f35b15611a905733925082600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fc6803622000000000000000000000000000000000000000000000000000000008252915191945063c680362291600482810192602092919082900301816000876161da5a03f11561000257505060405151905080156119d1575082600160a060020a031663d379be236040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a03166000141590505b80156119dd5750600082115b80156119ec5750600054600190115b15611a90578183600160a060020a031663830953ab6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040515160640291909104915050604281118015611a4d5750600054829011155b15611a675760008054612710612711909102049055611a90565b602181108015611a7a5750600054829010155b15611a90576000805461271061270f9091020490555b505050565b6000611a9f61122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b919050565b6000611af261122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b9392505050565b9050610759565b611c076106c6565b6000611c11611478565b611c1961122c565b600054611c2461159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611cf25780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b611d306106c6565b60008b611d3b61122c565b600054611d4661159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611e145780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b409050565b611e526106c6565b6000611e5c611478565b611d3b61122c565b611e6c6106c6565b6000611e76611478565b611e7e61122c565b600054611e8961159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611f575780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b9d9050565b611f956106c6565b8b611f9e611478565b611fa661122c565b600054611fb161159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561207f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611bf19050565b6120bd6106c6565b6000611f9e611478565b6120cf6106c6565b8b6120d8611478565b6120e061122c565b6000546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506117c99050565b6121f76106c6565b8b611e76611478565b6122086106c6565b60008b611e7e61122c565b61221b6106c6565b8a8c611fa661122c565b61222d6106c6565b60008b611fa661122c565b6122406106c6565b60008b6120e061122c565b6122536106c6565b8c8b61225d61122c565b60005461226861159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156123365780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f21561000257505060405151979650505050505050565b6123766106c6565b60008c8c600060005054611fb161159f565b6123906106c6565b60008c8c6000600050546120eb61159f565b6123aa6106c6565b60008c8c60006000505461226861159f565b60008d8d6000600050546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561249c5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150505b9695505050505050565b8e8d8d6000600050546123ce61159f565b60008d8d60006000505461226861159f565b60008d8d6000600050546123ce61159f565b60008e8e8d61226861159f565b8f8e8e8d61252561159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156125f35780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519998505050505050505050565b60008e8e8d6123ce61159f565b8a5160208c015160408d015160608e015161226861159f565b60008e8e8d61252561159f56",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000011f8119429ed3a",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe",
- "0x031b9ec274101cc3ccff4d6d98ef4513742dadbaadba538bff48b88403253234": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0x20ef51bb8ea9e8e8d5e2c17d28e47285698893c1017db4b4e40b792358a3dbc7": "0x0000000000000000000000000000000000000000000000000000000000000004",
- "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abd": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01",
- "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abf": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
- "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8ac2": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfb": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe",
- "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfc": "0x00000000000000000000000000000000000000000000000000000000000f6897",
- "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfd": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfe": "0x0000000000000000000000002859ddf2877c46d54e67b6becdb1cafb8ef4a458",
- "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dff": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9",
- "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794e00": "0x0000000000000000000000000000000000000000000000000000000000000008",
- "0x3b20a4b931bc4ae9450774ee52b8f5da1b248d23e61cd20c09b25662f73894fd": "0x0000000000000000000000000000000000000000000000000000000000000006",
- "0x3b99aee1e3090227401ac2055c861246ca6ec62f426b4b4d74df88510f841b89": "0x0000000000000000000000000000000000000000000000000000000000000007",
- "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef711": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c",
- "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef712": "0x0000000000000000000000000000000000000000000000000000000000102ce9",
- "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef713": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0",
- "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef714": "0x00000000000000000000000016917c151bb1399852a0741eb7b317b443e2cfa3",
- "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef715": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
- "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef716": "0x0000000000000000000000000000000000000000000000000000000000000004",
- "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a3fe": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1",
- "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a3ff": "0x00000000000000000000000000000000000000000000000000000000000fff67",
- "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a400": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9",
- "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a401": "0x00000000000000000000000010fc2e8ba5f40336c3576ffaa25177f1cdedf836",
- "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a402": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0",
- "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a403": "0x0000000000000000000000000000000000000000000000000000000000000006",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5ba": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bb": "0x000000000000000000000000000000000000000000000000000000000010347b",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bc": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bd": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5be": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bf": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2751": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2752": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2753": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2754": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2755": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2756": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a7": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9",
- "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a8": "0x00000000000000000000000000000000000000000000000000000000000fe13d",
- "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a9": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe",
- "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826aa": "0x00000000000000000000000063110531142fb314118164ff579ba52746504408",
- "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826ab": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1",
- "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826ac": "0x0000000000000000000000000000000000000000000000000000000000000007",
- "0xac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c890780": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xccd2cbc946692be8ade97db99353304e3af0fa6202f93649d4e185ad8b1f385c": "0x0000000000000000000000000000000000000000000000000000000000000004",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4ef": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f0": "0x00000000000000000000000000000000000000000000000000000000001030b3",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f1": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f2": "0x000000000000000000000000dd87a67740c2acf48a31829783a095a81c3628d9",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f3": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f4": "0x0000000000000000000000000000000000000000000000000000000000000003",
- "0xdabde47554d6a6cfcff3c968abb145f298585fafa9e24c10fc526269794bd626": "0x0000000000000000000000000000000000000000000000000000000000000003",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db7": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db8": "0x000000000000000000000000000000000000000000000000000000000010365c",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db9": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dba": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbb": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbc": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdec": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0",
- "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bded": "0x0000000000000000000000000000000000000000000000000000000000101dc2",
- "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdee": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1",
- "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdef": "0x000000000000000000000000173243e117a6382211b1ac91eeb262f4a7021c16",
- "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdf0": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c",
- "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdf1": "0x0000000000000000000000000000000000000000000000000000000000000005"
- }
- },
- "0x741467b251fca923d6229c4b439078b55dca233b": {
- "balance": "0x29c613529e8218f8",
- "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000002dfeff8fca5d",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000003defb9627dd677b54fc954824a7bc49bd26cbdfa12c75adf",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000ba43b7400",
- "0x0000000000000000000000000000000000000000000000000000000000000007": "0x00000000000000000000000000000000000000000000000000000000001e8480",
- "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000000000000a",
- "0x000000000000000000000000000000000000000000000000000000000000000a": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000000000000000000000",
- "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b",
- "0x000000000000000000000000000000000000000000000000000000000000000d": "0x000000000000000000000000000000000000000000000000000000000010365c",
- "0x000000000000000000000000000000000000000000000000000000000000000e": "0x00000000000000000000000000000000000000000000000000000000000000ff"
- }
- },
- "0x7c1eb207c07e7ab13cf245585bd03d0fa478d034": {
- "balance": "0x0",
- "code": "0x650200d2f18c7350606060405236156100a05760e060020a60003504630e9f1a3c81146100a55780632b4096b4146100c95780636ec13982146100eb578063a3119e571461010d578063a749f19b1461012f578063ab7366f714610151578063bacd69581461017f578063bfdf87c0146101c2578063c4144b26146101e1578063caa46c9c1461023c578063e6ce3a6a14610297578063ed5bd7ea146102b6575b610007565b6102d960043560243560008181526001830160205260409020600401545b92915050565b6102d960043560243560008181526001830160205260409020600301546100c3565b6102d960043560243560008181526001830160205260409020600201546100c3565b6102d960043560243560008181526001838101602052604090912001546100c3565b6102d960043560243560008181526001830160205260409020600501546100c3565b6102eb6004356024355b600081815260018301602052604081208054829182918291908614610790576101b9565b6102eb600435602435604435600082815260018401602052604081205481908190819086141561068a576040812060010154851415610680575b50505050505050565b6102d960043560243560008181526001830160205260409020546100c3565b6102d96004356024355b6040805160c08101825260008082526020828101829052828401829052606083018290526080830182905260a08301829052848252600186019052918220805490919083908114156102fb576102f2565b6102d96004356024355b6040805160c08101825260008082526020828101829052828401829052606083018290526080830182905260a08301829052848252600186019052918220805490919083908114156104c0576102f2565b6102d960043560243560443582546000908181811415610a6557610a8c565b6102d96004356024356000818152600183016020526040812060050154116100c3565b60408051918252519081900360200190f35b005b815193505b50505092915050565b60048301546000146103d257600483810154600090815260018881016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015460608201529181015460808301526005015460a082015291505b60608201516000146102ed57606091820151600090815260018781016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015493810193909352600481015460808401526005015460a0830152610364565b600283015460001461045b5750506002810154600081815260018681016020908152604092839020835160c081018552865481529286015491830191909152918101929092526003830154606083015260048301546080830152600583015460a08301525b81516003820154141561044d57805493506102f2565b600281015460001415610464575b600093506102f2565b6040805160c08101825282548152600183810154602083810191909152600285015483850181905260038601546060850152600486015460808501526005959095015460a0840152600094855290890190529120909150610437565b600383015460001461059757600383810154600090815260018881016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252918101546060830152600481015460808301526005015460a082015291505b60808201516000146102ed57608091820151600090815260018781016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015460608201526004820154938101939093526005015460a0830152610529565b600283015460001461045b5750506002810154600081815260018681016020908152604092839020835160c081018552865481529286015491830191909152918101929092526003830154606083015260048301546080830152600583015460a08301525b81516004820154141561061257805493506102f2565b6002810154600014156106245761045b565b6040805160c08101825282548152600183810154602083810191909152600285015483850181905260038601546060850152600486015460808501526005959095015460a08401526000948552908901905291209091506105fc565b61068a878761015b565b86546000925082141561069b578587555b508554600090815260018701602052604090205b8054600014156107255785815560028101829055600181018590556101b987875b60008181526001830160205260408120905b8154610d8e9085905b60008181526001830160205260408082206004810154835281832060059081015460038301548552929093209092015403905b5092915050565b60018101548154925085126107625760048101546000141561074957600481018690555b60040154600090815260018701602052604090206106af565b60038101546000141561077757600381018690555b60030154600090815260018701602052604090206106af565b600381015460001415806107a957506004810154600014155b156107cf576003810154600014610826578054600188019060009061083b908a90610246565b6002810154600014610a285760028101546000908152600188016020526040902060038101548254919550141561080857600060038501555b60048401548154141561081d57600060048501555b83549150610a2d565b80546001880190600090610852908a906101eb565b815260208101919091526040016000209450610865565b8152602081019190915260400160002094505b600285015460009081526001880160205260409020600381015486549195509092508214156108b9576004850154600385018190556000146108b95760048501546000908152604090208454600282015592505b60048401548554141561091357600385015460048501819055600014610913578660010160005060008660030160005054815260200190815260200160002060005092508250836000016000505483600201600050819055505b60028082015490860181905560001461098457866001016000506000826002016000505481526020019081526020016000206000509350835080600001600050548460030160005054141561096a57845460038501555b60048401548154141561097f57845460048501555b610989565b845487555b6003818101549086018190556000146109d6578660010160005060008260030160005054815260200190815260200160002060005092508250846000016000505483600201600050819055505b600481810154908601819055600014610a23578660010160005060008260040160005054815260200190815260200160002060005092508250846000016000505483600201600050819055505b610a2d565b600087555b6000808255600182018190556002820181905560038201819055600482018190556005820181905582146101b9576101b987836106d0565b50600081815260018601602052604090205b6001810154610a95908686610ad4565b805492505b50509392505050565b15610b915760fa60020a600f02851480610ab6575060f060020a613c3d0285145b15610af157600481015460001415610b3a5780549250610a8c565b86865b600060f960020a601f02831415610ce357508083135b9392505050565b60f960020a601f02851480610b0d575060f060020a613e3d0285145b80610b1f575060f060020a613d3d0285145b15610b9157600381015460001415610bc85780549250610a8c565b610b73610ad1878360040160005054600081815260018301602052604081205b600381015460001415610d61576001810154915061071e565b15610a87576004015460009081526001860160205260409020610a77565b60fa60020a600f02851480610bad575060f060020a613c3d0285145b15610c1f57600381015460001415610c565760009250610a8c565b610c01610ad1878360030160005054600081815260018301602052604081205b600481015460001415610d48576001810154915061071e565b15610a87576003015460009081526001860160205260409020610a77565b60f960020a601f02851480610c3b575060f060020a613e3d0285145b15610c6f57600481015460001415610ca25760009250610a8c565b6003015460009081526001860160205260409020610a77565b60f060020a613d3d02851415610cde57600181015484901215610cbb57600481015460001415610ca25760009250610a8c565b6004015460009081526001860160205260409020610a77565b600181015484901315610cde57600381015460001415610c565760009250610a8c565b610a77565b60fa60020a600f02831415610cfb5750808312610aea565b60f060020a613e3d02831415610d15575080831215610aea565b60f060020a613c3d02831415610d2f575080831315610aea565b60f060020a613d3d028314156100a05750828114610aea565b6004015460009081526001840160205260409020610be8565b6003015460009081526001840160205260409020610b5a565b600282015460001415610fbd575b50505050565b90508060021415610e2657610daa8483600301600050546106eb565b6000191415610dc457610dc4848360030160005054610dfe565b8154610e269085905b60008181526001830160205260408120600381015490919081908190811415610ffb57610007565b8154610e5a9085905b60008181526001830160205260408120600481015490919081908190811415610e7f57610007565b806001191415610e5a57610e418483600401600050546106eb565b60011415610df557610df5848360040160005054610dcd565b8060001913158015610e6d575060018113155b15610d7a578154610d7a908590610f7a565b6004840180546000908152600188016020526040812060028088015490820181905592829055945014610f0f57856001016000506000856002016000505481526020019081526020016000206000509150836000016000505482600301600050541415610efa57826000016000505482600301600050819055505b835460048301541415610f0f57825460048301555b6003830154600014610f40575060038201546000908152600186016020526040902080546004850155835460028201555b82546002808601919091558454600385015583015460001415610f7157826000016000505486600001600050819055505b8354610fe69087905b6000818152600183016020526040808220600381015483528183206005908101546004830154855292842001549092610fd99291908183106110fa5750816100c3565b60029091015460009081526001840160205260409020906106e2565b6001016005820155505050565b8254610ff3908790610f7a565b505050505050565b600384018054600090815260018801602052604081206002808801549082018190559282905594501461108b5785600101600050600085600201600050548152602001908152602001600020600050915083600001600050548260030160005054141561107657826000016000505482600301600050819055505b83546004830154141561108b57825460048301555b60048301546000146110bd57506004820154600081815260018701602052604090206003850191909155835460028201555b82546002808601919091558454600485015583015460001415610f7157826000016000505486600001600050819055508354610fe6908790610f7a565b50806100c356"
- },
- "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": {
- "balance": "0xd7a58f5b73b4b6c4",
- "code": "0x606060405236156100985760e060020a60003504633896002781146100e15780633defb962146100ea5780633f4be8891461010c5780634136aa351461011f5780634a420138146101a057806369c1a7121461028c5780638129fc1c146102955780638da5cb5b146102a6578063ae45850b146102b8578063af3309d8146102cc578063ea8a1af0146102d5578063ead50da3146102f4575b610308671bc16d674ec8000030600160a060020a03163110156100df57600554604051600160a060020a03918216916000913091909116319082818181858883f150505050505b565b61030a60005481565b610308671bc16d674ec8000030600160a060020a031631101561040f576100df565b61031c600454600160a060020a03165b90565b61030a5b600080548190118015610199575060408051600480547f0a16697a0000000000000000000000000000000000000000000000000000000083529251600160a060020a039390931692630a16697a928083019260209291829003018187876161da5a03f1156100025750506040515160ff01431090505b905061011c565b6103085b600354600554604080517f8c0e156d0000000000000000000000000000000000000000000000000000000081527f3defb96200000000000000000000000000000000000000000000000000000000600482015260a060020a90920461ffff1643016024830152621e8480604483015251600092600160a060020a031691638c0e156d916729a2241af62c000091606481810192602092909190829003018185886185025a03f1156100025750506040515192600160a060020a0384161491506102899050576004805473ffffffffffffffffffffffffffffffffffffffff1916821790555b50565b61030a60015481565b61030860008054146103f2576100df565b61031c600554600160a060020a031681565b61031c600354600160a060020a031661011c565b61030a60025481565b610308600554600160a060020a03908116339091161461035157610002565b61033960055460a060020a900461ffff1681565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6004546000600160a060020a03919091163111156103c75760408051600480547fea8a1af00000000000000000000000000000000000000000000000000000000083529251600160a060020a03939093169263ea8a1af0928083019260009291829003018183876161da5a03f115610002575050505b600554604051600160a060020a03918216916000913091909116319082818181858883f15050505050565b426000556100df6101a4565b600280546001908101909155429055565b600454600160a060020a03908116339091161461042b576100df565b610433610123565b151561043e576100df565b6103fe6101a456",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000056be5b99",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000056d0009b",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000008b",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b",
- "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000001e0d3cda913deb6f67967b99d67acdfa1712c293601"
- }
- },
- "0x89efe605e9ecbe22849cd85d5449cc946c26f8f3": {
- "balance": "0x0",
- "code": "0x650200d2f18c73506060604052361561007f5760e060020a600035046312c82bcc81146100845780635548c837146100a55780635c54305e146101015780636b103966146101555780637fcf532c14610189578063b1df3d80146101d5578063b5bc6dbb146101ee578063c6ab451414610225578063e62af6c114610293575b610007565b6102c56004356024356000620186a05a10156103855761030083835a610232565b6102d760043560243560443581600160a060020a031683600160a060020a03167f47a08955ce2b7f21ea62ff0024e1ea0ad87430953554a87e6bc65d777f18e639836040518082815260200191505060405180910390a3505050565b6102d760043560243560443560408051838152602081018390528151600160a060020a038616927f9b24879829bed3003de08d5c5d7e18dcbb8dc76faebd95cafc5d4dec8c61a3a5928290030190a2505050565b6102d76004356024356044355b600160a060020a03821660009081526020849052604090205480820110156102d957610007565b6102d7600435602435604080518281529051600160a060020a038416917fd0c5cf41ee8ebf084ad0bce53de7cbc6e4693d9b53a4019ca36a2f91cdc20b3a919081900360200190a25050565b6102c560043560243560443560006102fc848484610162565b6102c5600435602435604435600160a060020a03821660009081526020849052604081205482901061032b576103338484846102a0565b6102c56004356024356044355b60006000831180156102605750604051600160a060020a038516908290859082818181858883f19350505050155b156102fc57604051600160a060020a03851690839085906000818181858888f1935050505015156102fc57506000610300565b6102d76004356024356044355b600160a060020a03821660009081526020849052604090205481111561030757610007565b60408051918252519081900360200190f35b005b600160a060020a0382166000908152602084905260409020805482019055505050565b5060015b9392505050565b600160a060020a038216600090815260208490526040902080548290039055505050565b506000610300565b604051600160a060020a03841690600090849082818181858883f1935050505015156102fc57604051600160a060020a038416908390600081818185876185025a03f19250505015156102fc57610007565b6103008383620186a061023256"
- },
- "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": {
- "balance": "0xffe9b09a5c474dca",
- "nonce": "975",
- "code": "0x"
- },
- "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
- "balance": "0x4f5807198e238f13e",
- "nonce": "283",
- "code": "0x"
- },
- "0xe54d323f9ef17c1f0dede47ecc86a9718fe5ea34": {
- "balance": "0x0",
- "code": "0x650200d2f18c7350606060405236156100ab5760e060020a600035046326a7985a81146100b057806350d4e411146100be57806354fd4d501461023d578063586a69fa1461025d5780638e46afa91461026857806396cff3df14610272578063971c803f1461029657806398c9cdf4146102a157806398e00e54146102ae578063b152f19e146102b8578063c0f68859146102c4578063e3042c0f146102cf578063ea27a88114610461575b610007565b6102845b60006104cb6102a5565b604080516020601f60843560048181013592830184900484028501840190955281845261047f948035946024803595604435956064359560a494930191819084018382808284375094965050933593505060c43591505060e435610104356101243561014435610164356101843560006101806040519081016040528060008152602001600081526020016000815260200160206040519081016040528060008152602001508152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200150610180604051908101604052808f81526020018e81526020018d81526020018c81526020018981526020018b81526020018a81526020018881526020018781526020018681526020018581526020018481526020015090506104d48f825b600060006000600a43018460e0015110156105de577f544f4f5f534f4f4e0000000000000000000000000000000000000000000000009150610524565b604080516000808252600760208301528183015290519081900360600190f35b61049c5b6103e85b90565b6104b460ff610265565b62030d403a0260026024356004350102015b60408051918252519081900360200190f35b61049c5b600a610265565b6102845b62030d40610265565b6102846010610265565b61028443600a01610265565b6102845b6020610265565b60408051808201825261047f916004803592909160649190602490600290839083908082843780516020601f608435808c01359182018390048302840183019094528083529499983598975060a49650909450910191908190840183828082843750506040805160c0818101909252959796359660c435969095506101a49450925060e491506006908390839080828437509095505050505050604080516101808181018352600080835260208381018290528385018290528451908101855281815260608401526080830181905260a0830181905260c0830181905260e0830181905261010083018190526101208301819052610140830181905261016083018190528351918201909352808984505181526020018960015060209081015182528101899052604081018890526060018484505181526020810187905260408101869052606001846001506020908101518252018460025060400151815260200184600350606001518152602001846004506080015181526020018460055060a00151905290506104e78982610200565b6102846004356024356044356064355b3a0291909201600202010190565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6040805160ff929092168252519081900360200190f35b45039050610265565b9f9e505050505050505050505050505050565b9998505050505050505050565b8461016001511015610524577f494e53554646494349454e545f46554e4453000000000000000000000000000091505b600082146106ed576040805185518482529151600160a060020a0392909216917f513485fc54ef019ef1bc1ea683ef7d5d522f2865224ae10871ff992749c0ba4f9181900360200190a27389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc85600001518661016001516040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f215610007575050505b505092915050565b8360c0015161ffff166105ef61029a565b61ffff1611806106115750610602610261565b61ffff168460c0015161ffff16115b1561063e577f535441434b5f434845434b5f4f55545f4f465f52414e474500000000000000009150610524565b6106466102c8565b8460a0015160ff16101561067c577f47524143455f544f4f5f53484f525400000000000000000000000000000000009150610524565b6106846102a5565b84610100015110806106a157506106996100b4565b846101000151115b156106ce577f52455155495245445f4741535f4f55545f4f465f52414e4745000000000000009150610524565b6104f48461012001518561014001518660800151876101000151610471565b83610160015184600001518560e001518660a001518760200151886040015189606001518a608001518b61010001518c60c001518d61012001518e6101400151604051611078806108fa833901808c600160a060020a031681526020018b81526020018a60ff16815260200189600160a060020a03168152602001888152602001806020018781526020018681526020018561ffff1681526020018481526020018381526020018281038252888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b509c505050505050505050505050506040518091039082f090509050737c1eb207c07e7ab13cf245585bd03d0fa478d03463bacd69588683600160a060020a031660010284600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505050604051805190602001506040518460e060020a02815260040180848152602001838152602001828152602001935050505060006040518083038160008760325a03f21561000757505060408051600160a060020a038416815290517f2b05d346f0b0b9fd470024751c52d3b5dac5c37796f077c1a66241f2eada44b792509081900360200190a18092506105d656606060405260405161107838038061107883398101604052805160805160a05160c05160e05161010051610120516101405161016051610180516101a051999a98999798969795969490940194929391929091908a84848a8a8a8a88886101008051600c8054600160a060020a031990811633179091556000805482168d1781556001868155600286815560078e90556008805461ffff19168e1790553a600655600380547c01000000000000000000000000000000000000000000000000000000008d04740100000000000000000000000000000000000000000260a060020a63ffffffff0219919096168e17169490941790935588516004805493819052956020601f9385161590910260001901909316939093048101919091047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b908101939091608091909101908390106101ee57805160ff19168380011785555b5061017a9291505b8082111561021e5760008155600101610166565b5050826003600050600201600050819055505050505050505050508a600060006101000a815481600160a060020a030219169083021790555089600d6000508190555088600e60006101000a81548160ff021916908302179055505050505050505050505050610e56806102226000396000f35b8280016001018555821561015e579182015b8281111561015e578251826000505591602001919060010190610200565b509056606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256"
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "ethash": {}
- }
- },
- "context": {
- "number": "1062503",
- "difficulty": "13700504019867",
- "timestamp": "1456480446",
- "gasLimit": "3141592",
- "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
- },
- "input": "0xf86b8203cf850ba43b740083200b2094741467b251fca923d6229c4b439078b55dca233b8084614619541ca078293714f69a810356f1ee29dc686ec2ca3a0e5448e1ef6322c77369ebdd26c2a01c3836fa363548959554ee5360361be9db4aea9eb7c31f61550f0e9a10138adf",
- "tracerConfig": {
- "diffMode": true
- },
- "result": {
- "pre": {
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x98e1c608601c2496b2",
- "nonce": 218916
- },
- "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": {
- "balance": "0x0",
- "nonce": 237,
- "code": "0x6060604052361561027c5760e060020a600035046301991313811461027e57806303d22885146102ca5780630450991814610323578063049ae734146103705780630ce46c43146103c35780630e85023914610602578063112e39a8146106755780631b4fa6ab146106c25780631e74a2d3146106d057806326a7985a146106fd5780633017fe2414610753578063346cabbc1461075c578063373a1bc3146107d55780633a9e74331461081e5780633c2c21a01461086e5780633d9ce89b146108ba578063480b70bd1461092f578063481078431461097e57806348f0518714610a0e5780634c471cde14610a865780634db3da8314610b09578063523ccfa814610b4f578063586a69fa14610be05780635a9f2def14610c3657806364ee49fe14610caf57806367beaccb14610d055780636840246014610d74578063795b9a6f14610dca5780637b55c8b514610e415780637c73f84614610ee15780638c0e156d14610f145780638c1d01c814610f605780638e46afa914610f69578063938c430714610fc0578063971c803f146111555780639772c982146111ac57806398c9cdf41461122857806398e00e541461127f5780639f927be7146112d5578063a00aede914611383578063a1c0539d146113d3578063aff21c6514611449578063b152f19e14611474578063b549793d146114cb578063b5b33eda1461154b578063bbc6eb1f1461159b578063c0f68859146115ab578063c3a2c0c314611601578063c43d05751461164b578063d8e5c04814611694578063dbfef71014611228578063e29fb547146116e7578063e6470fbe1461173a578063ea27a8811461174c578063ee77fe86146117d1578063f158458c14611851575b005b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387876020604051908101604052806000815260200150612225610f6d565b61188260043560243560443560643560843560a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338b8a6020604051908101604052806000815260200150896125196106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a026020604051908101604052806000815260200150611e4a610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503389896020604051908101604052806000815260200150886124e86106c6565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750506040805160a08082019092529597963596608435969095506101449450925060a491506005908390839080828437509095505050505050604080518082018252600160a060020a03338116825288166020820152815160c0810190925260009173e54d323f9ef17c1f0dede47ecc86a9718fe5ea349163e3042c0f91600191908a908a9089908b90808b8b9090602002015181526020018b60016005811015610002579090602002015181526020018b60026005811015610002579090602002015181526020018b60036005811015610002579090602002015181526020018b6004600581101561000257909060200201518152602001348152602001506040518860e060020a02815260040180888152602001876002602002808383829060006004602084601f0104600f02600301f150905001868152602001806020018560ff1681526020018461ffff168152602001836006602002808383829060006004602084601f0104600f02600301f1509050018281038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d25780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038160008760325a03f2156100025750506040515191506124cd9050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808787611e64610f6d565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611d28610f6d565b61189f5b6000611bf8611159565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881600060005054611a9561159f565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346326a7985a6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b760075b90565b604080516020606435600481810135601f8101849004840285018401909552848452611882948135946024803595604435956084949201919081908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160013389898861224b610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386866020604051908101604052806000815260200150611e64610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333896020604051908101604052806000815260200150886123bc6106c6565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387866020604051908101604052806000815260200150611f8d610f6d565b60408051602060248035600481810135601f810185900485028601850190965285855261188295813595919460449492939092019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808888612225610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503388886020604051908101604052806000815260200150612388610f6d565b611882600435604080517fc4144b2600000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163c4144b26916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133888888612238610f6d565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338b8b8b896126536106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333866020604051908101604052806000815260200150611e4a610f6d565b6118b76004355b604080517fed5bd7ea00000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163ed5bd7ea916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b61189f600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463586a69fa6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650509335935050606435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808989612388610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a896020604051908101604052806000815260200150886124d76106c6565b6040805160206004803580820135601f8101849004840285018401909552848452611882949193602493909291840191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808587611e4a610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a8a60206040519081016040528060008152602001508961262d6106c6565b604080516020606435600481810135601f810184900484028501840190955284845261188294813594602480359560443595608494920191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338888876120c7610f6d565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437505060408051608080820190925295979635969561010495509350608492508591508390839080828437509095505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989898961263a6106c6565b6118b7600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881858585611ba361122c565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050333388602060405190810160405280600081526020015061236e610f6d565b6118b760005481565b6118c95b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea34638e46afa96040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a43560c43560e43561010435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338e8e8d8f8e8e8e8e8e346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111195780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519b9a5050505050505050505050565b61189f5b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463971c803f6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650509335935050608435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989896123a2610f6d565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398c9cdf46040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398e00e546040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600435604080517fe6ce3a6a000000000000000000000000000000000000000000000000000000008152600160048201527f3e3d0000000000000000000000000000000000000000000000000000000000006024820152604481018390529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163e6ce3a6a916064818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a0260206040519081016040528060008152602001506121ef610f6d565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338787876120b5610f6d565b6118b7600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88183611b4561159f565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463b152f19e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808b8b8961262d6106c6565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386600060e060020a026020604051908101604052806000815260200150612200610f6d565b6118b75b60005460649004610759565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463c0f688596040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611bff610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333876020604051908101604052806000815260200150612200610f6d565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387600060e060020a026020604051908101604052806000815260200150612213610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338a60206040519081016040528060008152602001508961250c6106c6565b61027c6000600060006118e033610b56565b6118b7600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881868686866040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b949350505050565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338a8a8a886124fa6106c6565b6118b7600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88184846000611b4f61122c565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b60408051918252519081900360200190f35b6040805160ff929092168252519081900360200190f35b15611a905733925082600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fc6803622000000000000000000000000000000000000000000000000000000008252915191945063c680362291600482810192602092919082900301816000876161da5a03f11561000257505060405151905080156119d1575082600160a060020a031663d379be236040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a03166000141590505b80156119dd5750600082115b80156119ec5750600054600190115b15611a90578183600160a060020a031663830953ab6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040515160640291909104915050604281118015611a4d5750600054829011155b15611a675760008054612710612711909102049055611a90565b602181108015611a7a5750600054829010155b15611a90576000805461271061270f9091020490555b505050565b6000611a9f61122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b919050565b6000611af261122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b9392505050565b9050610759565b611c076106c6565b6000611c11611478565b611c1961122c565b600054611c2461159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611cf25780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b611d306106c6565b60008b611d3b61122c565b600054611d4661159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611e145780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b409050565b611e526106c6565b6000611e5c611478565b611d3b61122c565b611e6c6106c6565b6000611e76611478565b611e7e61122c565b600054611e8961159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611f575780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b9d9050565b611f956106c6565b8b611f9e611478565b611fa661122c565b600054611fb161159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561207f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611bf19050565b6120bd6106c6565b6000611f9e611478565b6120cf6106c6565b8b6120d8611478565b6120e061122c565b6000546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506117c99050565b6121f76106c6565b8b611e76611478565b6122086106c6565b60008b611e7e61122c565b61221b6106c6565b8a8c611fa661122c565b61222d6106c6565b60008b611fa661122c565b6122406106c6565b60008b6120e061122c565b6122536106c6565b8c8b61225d61122c565b60005461226861159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156123365780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f21561000257505060405151979650505050505050565b6123766106c6565b60008c8c600060005054611fb161159f565b6123906106c6565b60008c8c6000600050546120eb61159f565b6123aa6106c6565b60008c8c60006000505461226861159f565b60008d8d6000600050546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561249c5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150505b9695505050505050565b8e8d8d6000600050546123ce61159f565b60008d8d60006000505461226861159f565b60008d8d6000600050546123ce61159f565b60008e8e8d61226861159f565b8f8e8e8d61252561159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156125f35780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519998505050505050505050565b60008e8e8d6123ce61159f565b8a5160208c015160408d015160608e015161226861159f565b60008e8e8d61252561159f56",
- "storage": {
- "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abf": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
- "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef715": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bc": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bd": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bf": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f1": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f3": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f4": "0x0000000000000000000000000000000000000000000000000000000000000003",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbc": "0x0000000000000000000000000000000000000000000000000000000000000001"
- }
- },
- "0x741467b251fca923d6229c4b439078b55dca233b": {
- "balance": "0x29c613529e8218f8",
- "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256"
- },
- "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": {
- "balance": "0xd7a58f5b73b4b6c4",
- "code": "0x606060405236156100985760e060020a60003504633896002781146100e15780633defb962146100ea5780633f4be8891461010c5780634136aa351461011f5780634a420138146101a057806369c1a7121461028c5780638129fc1c146102955780638da5cb5b146102a6578063ae45850b146102b8578063af3309d8146102cc578063ea8a1af0146102d5578063ead50da3146102f4575b610308671bc16d674ec8000030600160a060020a03163110156100df57600554604051600160a060020a03918216916000913091909116319082818181858883f150505050505b565b61030a60005481565b610308671bc16d674ec8000030600160a060020a031631101561040f576100df565b61031c600454600160a060020a03165b90565b61030a5b600080548190118015610199575060408051600480547f0a16697a0000000000000000000000000000000000000000000000000000000083529251600160a060020a039390931692630a16697a928083019260209291829003018187876161da5a03f1156100025750506040515160ff01431090505b905061011c565b6103085b600354600554604080517f8c0e156d0000000000000000000000000000000000000000000000000000000081527f3defb96200000000000000000000000000000000000000000000000000000000600482015260a060020a90920461ffff1643016024830152621e8480604483015251600092600160a060020a031691638c0e156d916729a2241af62c000091606481810192602092909190829003018185886185025a03f1156100025750506040515192600160a060020a0384161491506102899050576004805473ffffffffffffffffffffffffffffffffffffffff1916821790555b50565b61030a60015481565b61030860008054146103f2576100df565b61031c600554600160a060020a031681565b61031c600354600160a060020a031661011c565b61030a60025481565b610308600554600160a060020a03908116339091161461035157610002565b61033960055460a060020a900461ffff1681565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6004546000600160a060020a03919091163111156103c75760408051600480547fea8a1af00000000000000000000000000000000000000000000000000000000083529251600160a060020a03939093169263ea8a1af0928083019260009291829003018183876161da5a03f115610002575050505b600554604051600160a060020a03918216916000913091909116319082818181858883f15050505050565b426000556100df6101a4565b600280546001908101909155429055565b600454600160a060020a03908116339091161461042b576100df565b610433610123565b151561043e576100df565b6103fe6101a456",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000056d0009b",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000008b",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b"
- }
- },
- "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": {
- "balance": "0xffe9b09a5c474dca",
- "nonce": 975
- },
- "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
- "balance": "0x4f5807198e238f13e",
- "nonce": 283
- }
- },
- "post": {
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x98e2b02f14529b1eb2"
- },
- "0x651913977e8140c323997fce5e03c19e0015eebf": {
- "balance": "0x29a2241af62c0000",
- "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000011f8119429ed3a",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000002e002d006b55",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000003defb9627dd677b54fc954824a7bc49bd26cbdfa12c75adf",
- "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000ba43b7400",
- "0x0000000000000000000000000000000000000000000000000000000000000007": "0x00000000000000000000000000000000000000000000000000000000001e8480",
- "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000000000000a",
- "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b",
- "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000103847",
- "0x000000000000000000000000000000000000000000000000000000000000000e": "0x00000000000000000000000000000000000000000000000000000000000000ff"
- }
- },
- "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": {
- "nonce": 238,
- "storage": {
- "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abf": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
- "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef715": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bc": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bd": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3",
- "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bf": "0x0000000000000000000000000000000000000000000000000000000000000003",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2751": "0x000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2752": "0x0000000000000000000000000000000000000000000000000000000000103847",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2753": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b",
- "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2756": "0x0000000000000000000000000000000000000000000000000000000000000001",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f1": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f3": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01",
- "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f4": "0x0000000000000000000000000000000000000000000000000000000000000002",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbb": "0x000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf",
- "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbc": "0x0000000000000000000000000000000000000000000000000000000000000002"
- }
- },
- "0x741467b251fca923d6229c4b439078b55dca233b": {
- "balance": "0x0",
- "storage": {
- "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000000000000000000101"
- }
- },
- "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": {
- "balance": "0xd6c5f42b8502a0e3",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000056d020be",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000008c",
- "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf"
- }
- },
- "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": {
- "balance": "0x10002e64ebd492a46",
- "nonce": 976
- },
- "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
- "balance": "0x4f5809f97e1c8bb9b"
- }
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json
deleted file mode 100644
index 01cc3c5058..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json
+++ /dev/null
@@ -1,103 +0,0 @@
-{
- "context": {
- "difficulty": "3502894804",
- "gasLimit": "4722976",
- "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724",
- "number": "2289806",
- "timestamp": "1513601314"
- },
- "genesis": {
- "alloc": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "code": "0x",
- "nonce": "22",
- "storage": {}
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "nonce": "1",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000",
- "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c",
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "code": "0x",
- "nonce": "29072",
- "storage": {}
- }
- },
- "config": {
- "byzantiumBlock": 1700000,
- "chainId": 3,
- "daoForkSupport": true,
- "eip150Block": 0,
- "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d",
- "eip155Block": 10,
- "eip158Block": 10,
- "ethash": {},
- "homesteadBlock": 0
- },
- "difficulty": "3509749784",
- "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444",
- "gasLimit": "4727564",
- "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440",
- "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3",
- "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada",
- "nonce": "0x4eb12e19c16d43da",
- "number": "2289805",
- "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f",
- "timestamp": "1513601261",
- "totalDifficulty": "7143276353481064"
- },
- "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4",
- "tracerConfig": {
- "diffMode": true
- },
- "result": {
- "pre": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x0",
- "nonce": 22
- },
- "0x1585936b53834b021f68cc13eeefdec2efc8e724": {
- "balance": "0x0"
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d87094125a369d9bd5",
- "nonce": 1,
- "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d77678137ac1b775",
- "nonce": 29072
- }
- },
- "post": {
- "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": {
- "balance": "0x6f05b59d3b20000"
- },
- "0x1585936b53834b021f68cc13eeefdec2efc8e724": {
- "balance": "0x420eed1bd6c00"
- },
- "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": {
- "balance": "0x4d869a3b70062eb9bd5",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b95e"
- }
- },
- "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": {
- "balance": "0x1780d7725724a9044b75",
- "nonce": 29073
- }
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json
deleted file mode 100644
index 5021bda192..0000000000
--- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json
+++ /dev/null
@@ -1,107 +0,0 @@
-{
- "genesis": {
- "difficulty": "5697691613344",
- "extraData": "0xd783010202844765746887676f312e342e32856c696e7578",
- "gasLimit": "3141592",
- "hash": "0x2004021ae3545cf8abba1ec97a7e401157cee9e847131e2f4c75ce38610040cc",
- "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5",
- "mixHash": "0x651f01d13fb801c602e1544ab80b3bc32888ea40ef298efa52ec3df983b558ee",
- "nonce": "0xdf23f0da925518a6",
- "number": "422908",
- "stateRoot": "0xd914c6440edf9f4a6f997a9b3ecb6e1a9ca2310f74b0b6890c0d0d4a3c28e4d3",
- "timestamp": "1445530335",
- "totalDifficulty": "2148894717741690476",
- "alloc": {
- "0x2861bf89b6c640c79040d357c1e9513693ef5d3f": {
- "balance": "0x0",
- "code": "0x606060405236156100825760e060020a600035046312055e8f8114610084578063185061da146100b157806322beb9b9146100d5578063245a03ec146101865780633fa4f245146102a657806341c0e1b5146102af578063890eba68146102cb578063b29f0835146102de578063d6b4485914610308578063dd012a15146103b9575b005b6001805474ff0000000000000000000000000000000000000000191660a060020a60043502179055610082565b6100826001805475ff00000000000000000000000000000000000000000019169055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527fb29f0835000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b6100826004356024356001547fb0f07e440000000000000000000000000000000000000000000000000000000060609081526064839052600160a060020a039091169063b0f07e449060849060009060248183876161da5a03f150604080516001547f73657449742875696e74323536290000000000000000000000000000000000008252825191829003600e018220878352835192839003602001832060e060020a6352afbc33028452600160a060020a03308116600486015260e060020a9283900490920260248501526044840152438901606484015260a060020a820460ff1694830194909452600060a483018190529251931694506352afbc33935060c48181019391829003018183876161da5a03f115610002575050505050565b6103c460025481565b61008260005433600160a060020a039081169116146103ce575b565b6103c460015460a860020a900460ff1681565b6100826001805475ff000000000000000000000000000000000000000000191660a860020a179055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527f185061da000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b600435600255610082565b6060908152602090f35b6001547f6ff96d17000000000000000000000000000000000000000000000000000000006060908152600160a060020a0330811660645290911690632e1a7d4d908290636ff96d17906084906020906024816000876161da5a03f1156100025750506040805180517f2e1a7d4d0000000000000000000000000000000000000000000000000000000082526004820152905160248281019350600092829003018183876161da5a03f115610002575050600054600160a060020a03169050ff",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000ff30c9e568f133adce1f1ea91e189613223fc461b9"
- }
- },
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x326601cc6cf364f6b9",
- "nonce": "12122",
- "code": "0x"
- },
- "0x30c9e568f133adce1f1ea91e189613223fc461b9": {
- "balance": "0x8b83c417dd78000",
- "nonce": "2",
- "code": "0x606060405236156102ea5760e060020a6000350463022bc71f81146102f757806303d6d7b61461037f578063086ae9e4146103ec57806309c975df146104595780631145a20f146104c657806312d67c5f146104e75780631302188c146104f15780631ae460e5146104fc57806323306ed614610573578063234917d4146105ca57806329917954146106375780632a472ae81461071d5780632e1a7d4d1461078a578063306b031d1461087f57806333613cbe1461089d57806334c19b93146108c257806335b281531461092f5780633664a0ea146109b85780633c941423146109c35780633cbfed7414610a3b57806350a3bd3914610a4957806352afbc3314610a735780635539d40014610c2a5780635a5383ac14610c3e57806360b831e514610cb55780636164947214610d7f578063685c234a14610d8a5780636ffc089614610de0578063741b3c3914610e4d5780637542861514610ed25780637772a38014610f5557806377b19cd514610ff057806378bc64601461105d5780638b37e656146110ca5780638baced64146111375780638dd5e298146111b157806393423e9c146111de57806394d2b21b1461120257806394f3f81d1461121657806398e00e54146112665780639f927be7146112bc578063a502aae81461136a578063a6c01cfd146113e8578063a9743c68146113fa578063aa4cc01f14611467578063b010d94a146114d4578063b0171fa41461154e578063b0ac4c8c146115cc578063b0f07e4414611635578063b35594601461171c578063c0f6885914611739578063c3daab961461178f578063c630f92b146117bb578063c831391d146117e5578063cd062734146117f0578063d0e30db01461185d578063db681e5414611865578063e40986551461190c578063e850f3ae14611979578063ed2b8e0b146119e6578063f340fa01146119f1578063f828c3fa14611ae8578063f8b1185314611b07578063f9f447eb14611b24578063fc30052214611b91578063fcf3691814611bfe575b6112645b611c86336119f8565b611c88600435604080517fc4144b260000000000000000000000000000000000000000000000000000000081526010600482015260248101839052905160009173ce642b6a82e72147ceade0e72c786ba8eaeb31d79163c4144b26916044818101926020929091908290030181878760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b637d613b346000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63da40fd616000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c9a60043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63c68efc486000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b61126460043560243560443560643560843561200185858585856000610a89565b611c886004545b90565b611c886005546104ee565b611c886040805160e160020a6333f8a36702815260066004820152600160a060020a0333166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f916367f146ce916044818101926020929091908290030181878760325a03f2156100025750506040515191506104ee9050565b611c885b60007327b1b436e4699a012cc8698e33c8f3e1c035c28b6323306ed66040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506104ee9050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63e99a66856000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264604080517f317c152d00000000000000000000000000000000000000000000000000000000815260066004820152600160a060020a0333166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163317c152d916044818101926020929091908290030181878760325a03f2156100025750506040805180517ff1173928000000000000000000000000000000000000000000000000000000008252600160a060020a0333166004830152602482018190529151919363f1173928926044838101938290030181838760325a03f2156100025750505050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63707378396000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264600435604080517fb5bc6dbb00000000000000000000000000000000000000000000000000000000815260126004820152600160a060020a033316602482015260448101839052905173d3cb18959b0435864ff33010fa83be60afc04b229163b5bc6dbb916064828101926020929190829003018160008760325a03f21561000257505060405151159050611d255773d3cb18959b0435864ff33010fa83be60afc04b22637fcf532c33836040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060006040518083038160008760325a03f21561000257505050611ae5565b611c886004356000818152600e60205260409020600201545b919050565b611c886004355b600160a060020a0381166000908152600f6020526040902054610898565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63fc4730126000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264600435604080517fa95d3e76000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a0384811660248401523316604483015291517327b1b436e4699a012cc8698e33c8f3e1c035c28b9263a95d3e7692606481810193918290030181838760325a03f2156100025750505050565b611c886002546104ee565b611c9a60043560243560007327b1b436e4699a012cc8698e33c8f3e1c035c28b6398213db6600060005085856040518460e060020a02815260040180848152602001838152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150610dda9050565b611c886000611e0a336108a4565b611264600073c895c144d0b0f88417cf9e14e03e6abc82c0af3f635748147e600633611ec2610577565b61126460043560243560443560643560843560a4355b604080517ff1924efb000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a03338116602484015289166044830152606482018890526084820187905260a4820186905260ff851660c483015260e48201849052915182917327b1b436e4699a012cc8698e33c8f3e1c035c28b9163f1924efb91610104818101926020929091908290030181878760325a03f2156100025750506040805180517f5a1230bf000000000000000000000000000000000000000000000000000000008252600160a060020a0333811660048401528c166024830152604482018b9052606482018a90526084820189905260ff881660a483015260c482018790529151919450635a1230bf9160e48083019260209291908290030181878760325a03f215610002575050604051519183149050612008577327b1b436e4699a012cc8698e33c8f3e1c035c28b6318b753ab82846040518360e060020a028152600401808381526020018281526020019250505060006040518083038160008760325a03f21561000257505050612056565b611c9a600154600160a060020a03166104ee565b611c886040805160e560020a6304b47bb902815260066004820152600160a060020a0333166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163968f7720916044818101926020929091908290030181878760325a03f2156100025750506040515191506104ee9050565b6112646004357327b1b436e4699a012cc8698e33c8f3e1c035c28b637e853f3d600060005083336040518460e060020a0281526004018084815260200183815260200182600160a060020a03168152602001935050505060206040518083038160008760325a03f21561000257505060405151159050611ae5577327b1b436e4699a012cc8698e33c8f3e1c035c28b63ab2af349826040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f2156100025750505050565b611c886008546104ee565b611c88600435602435604080516c01000000000000000000000000600160a060020a03858116820283528416026014820152815160289181900391909101902060009081526015602052205460ff165b92915050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63b506054f6000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264604080517f068e3ef100000000000000000000000000000000000000000000000000000000815260066004820152600160a060020a0333166024820152346044820152905173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163068e3ef19160648281019260009291908290030181838760325a03f21561000257505050565b611cb76004356040805160208181018352600080835284815260138252838120600d0154815260148252835190849020805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015611fb85780601f10611f8d57610100808354040283529160200191611fb8565b611c886004356024355b604080517fa163a32500000000000000000000000000000000000000000000000000000000815260066004820152600160a060020a038416602482015260448101839052905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163a163a325916064818101926020929091908290030181878760325a03f215610002575050604051519150610dda9050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63775f20f96000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b637517a7c96000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c9a60043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63250687836000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c886004356040805160e160020a6333f8a36702815260066004820152600160a060020a0383166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f916367f146ce916044818101926020929091908290030181878760325a03f2156100025750506040515191506108989050565b611c88600435600073c895c144d0b0f88417cf9e14e03e6abc82c0af3f6354e37911600684611e6d610577565b611c88600435600160a060020a038116600090815260126020526040902054610898565b611c9a600054600160a060020a03166104ee565b604080516c01000000000000000000000000600435600160a060020a0390811682028352331602601482015281516028918190039190910190206000908152601560205220805460ff191690555b005b611c8860007327b1b436e4699a012cc8698e33c8f3e1c035c28b6398e00e546040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506104ee9050565b611c88600435604080517fe6ce3a6a000000000000000000000000000000000000000000000000000000008152601060048201527f3e3d000000000000000000000000000000000000000000000000000000000000602482015260448101839052905160009173ce642b6a82e72147ceade0e72c786ba8eaeb31d79163e6ce3a6a916064818101926020929091908290030181878760325a03f2156100025750506040515191506108989050565b611c88604080517f8f00e61a00000000000000000000000000000000000000000000000000000000815260066004820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f91638f00e61a916024818101926020929091908290030181878760325a03f2156100025750506040515191506104ee9050565b611c886004356000611e113383610f5f565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63dd382dd36000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63aebd65476000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c886004356040805160e560020a6304b47bb902815260066004820152600160a060020a0383166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163968f7720916044818101926020929091908290030181878760325a03f2156100025750506040515191506108989050565b611c88604080517fc75e8f8800000000000000000000000000000000000000000000000000000000815260066004820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163c75e8f88916024818101926020929091908290030181878760325a03f2156100025750506040515191506104ee9050565b611cb760408051602081810183526000825282516003805460026000196001831615610100020190911604601f81018490048402830184019095528482529293909291830182828015611fef5780601f10611fc457610100808354040283529160200191611fef565b611264604080517fa89713750000000000000000000000000000000000000000000000000000000081526000600482018181526024830193845236604484018190527327b1b436e4699a012cc8698e33c8f3e1c035c28b9463a89713759484939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050604080516005547f321f45840000000000000000000000000000000000000000000000000000000082526004820152905163321f4584916024818101926000929091908290030181838760325a03f21561000257505050565b611c886004356000818152600e6020526040902060030154610898565b611c8860007327b1b436e4699a012cc8698e33c8f3e1c035c28b63c0f688596040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506104ee9050565b61126460043573c895c144d0b0f88417cf9e14e03e6abc82c0af3f63dd8abb6c60063384611db7610577565b611c88600073c895c144d0b0f88417cf9e14e03e6abc82c0af3f6354e37911600633611e18610577565b611c886007546104ee565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63125935846000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b6112646102ee565b611c886004356000818152601360209081526040805181842060038101546004828101547f38f4c9eb0000000000000000000000000000000000000000000000000000000085526006918501919091526024840182905260ff160160448301529151919273c895c144d0b0f88417cf9e14e03e6abc82c0af3f926338f4c9eb9260648181019392918290030181888760325a03f21561000257505060405151949350505050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63fae644646000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63b3a5e2556000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c886006546104ee565b6112646004355b604080517fb1df3d8000000000000000000000000000000000000000000000000000000000815260126004820152600160a060020a0383166024820152346044820152905173d3cb18959b0435864ff33010fa83be60afc04b229163b1df3d80916064828101926020929190829003018160008760325a03f215610002575050604080517f5548c837000000000000000000000000000000000000000000000000000000008152600160a060020a033381166004830152841660248201523460448201529051635548c837916064818101926000929091908290030181838760325a03f215610002575050505b50565b611264600435602435604435606435611ffb8484848460ff6000610a89565b611c886004356000818152600e6020526040902060010154610898565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63c9abdb7c6000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b6386b0aac96000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264600435604080517f25fea09900000000000000000000000000000000000000000000000000000000815260006004820181905260248201849052600160a060020a033316604483015291517327b1b436e4699a012cc8698e33c8f3e1c035c28b926325fea09992606481810193918290030181838760325a03f2156100025750505050565b565b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015611d175780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600160a060020a0333166000818152601260205260408051818320547f5c54305e00000000000000000000000000000000000000000000000000000000825260048201949094526024810185905260448101939093525173d3cb18959b0435864ff33010fa83be60afc04b2292635c54305e9260648281019391928290030181838760325a03f2156100025750505050565b6040518560e060020a0281526004018085815260200184600160a060020a0316815260200183815260200182815260200194505050505060006040518083038160008760325a03f2156100025750505050565b90506104ee565b9050610898565b6040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506104ee9050565b6040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506108989050565b6040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040805180517f6a704d7b000000000000000000000000000000000000000000000000000000008252600160a060020a033316600483015260248201819052915191935073c895c144d0b0f88417cf9e14e03e6abc82c0af3f9250636a704d7b9160448281019260009291908290030181838760325a03f2156100025750505050565b820191906000526020600020905b815481529060010190602001808311611f9b57829003601f168201915b50505050509050610898565b820191906000526020600020905b815481529060010190602001808311611fd257829003601f168201915b505050505090506104ee565b50505050565b5050505050565b7327b1b436e4699a012cc8698e33c8f3e1c035c28b635ca1bad5826040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f215610002575050505b505050505050505056",
- "storage": {
- "0x18b039f13c5f33908f0960616cb3e44029c716366508c54d555096d6e1fa5145": "0x00000000000000000000000000000000000000000000000008b83c417dd78000"
- }
- },
- "0xd3cb18959b0435864ff33010fa83be60afc04b22": {
- "balance": "0x0",
- "code": "0x650105e11e10f850606060405236156100695760e060020a60003504635548c837811461006e5780635c54305e146100ca5780636b1039661461011e5780637fcf532c14610152578063b1df3d801461019e578063b5bc6dbb146101b7578063e62af6c1146101ee575b610007565b61022060043560243560443581600160a060020a031683600160a060020a03167f47a08955ce2b7f21ea62ff0024e1ea0ad87430953554a87e6bc65d777f18e639836040518082815260200191505060405180910390a3505050565b61022060043560243560443560408051838152602081018390528151600160a060020a038616927f9b24879829bed3003de08d5c5d7e18dcbb8dc76faebd95cafc5d4dec8c61a3a5928290030190a2505050565b6102206004356024356044355b600160a060020a038216600090815260208490526040902054808201101561023457610007565b610220600435602435604080518281529051600160a060020a038416917fd0c5cf41ee8ebf084ad0bce53de7cbc6e4693d9b53a4019ca36a2f91cdc20b3a919081900360200190a25050565b610222600435602435604435600061025784848461012b565b610222600435602435604435600160a060020a0382166000908152602084905260408120548290106102865761028e8484846101fb565b6102206004356024356044355b600160a060020a03821660009081526020849052604090205481111561026257610007565b005b60408051918252519081900360200190f35b600160a060020a0382166000908152602084905260409020805482019055505050565b5060015b9392505050565b600160a060020a038216600090815260208490526040902080548290039055505050565b50600061025b565b604051600160a060020a03841690600090849082818181858883f19350505050151561025757604051600160a060020a038416908390600081818185876185025a03f19250505015156102575761000756"
- },
- "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
- "balance": "0x1ff0509d9d6821e26",
- "nonce": "138",
- "code": "0x"
- }
- },
- "config": {
- "chainId": 1,
- "homesteadBlock": 1150000,
- "daoForkBlock": 1920000,
- "daoForkSupport": true,
- "eip150Block": 2463000,
- "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
- "eip155Block": 2675000,
- "eip158Block": 2675000,
- "byzantiumBlock": 4370000,
- "constantinopleBlock": 7280000,
- "petersburgBlock": 7280000,
- "istanbulBlock": 9069000,
- "muirGlacierBlock": 9200000,
- "berlinBlock": 12244000,
- "londonBlock": 12965000,
- "arrowGlacierBlock": 13773000,
- "grayGlacierBlock": 15050000,
- "ethash": {}
- }
- },
- "context": {
- "number": "422909",
- "difficulty": "5694909537365",
- "timestamp": "1445530357",
- "gasLimit": "3141592",
- "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
- },
- "input": "0xf86a818a850ba43b7400832d8a40942861bf89b6c640c79040d357c1e9513693ef5d3f808441c0e1b51ca0b8de64a9a04d699f5938efa5431ca7c80500f6accb329da43aadabd4eab84f17a035b969c198f694be991a2a5b287250e19e852efd0ccba30bd50707277bfbc9aa",
- "tracerConfig": {
- "diffMode": true
- },
- "result": {
- "pre": {
- "0x2861bf89b6c640c79040d357c1e9513693ef5d3f": {
- "balance": "0x0",
- "code": "0x606060405236156100825760e060020a600035046312055e8f8114610084578063185061da146100b157806322beb9b9146100d5578063245a03ec146101865780633fa4f245146102a657806341c0e1b5146102af578063890eba68146102cb578063b29f0835146102de578063d6b4485914610308578063dd012a15146103b9575b005b6001805474ff0000000000000000000000000000000000000000191660a060020a60043502179055610082565b6100826001805475ff00000000000000000000000000000000000000000019169055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527fb29f0835000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b6100826004356024356001547fb0f07e440000000000000000000000000000000000000000000000000000000060609081526064839052600160a060020a039091169063b0f07e449060849060009060248183876161da5a03f150604080516001547f73657449742875696e74323536290000000000000000000000000000000000008252825191829003600e018220878352835192839003602001832060e060020a6352afbc33028452600160a060020a03308116600486015260e060020a9283900490920260248501526044840152438901606484015260a060020a820460ff1694830194909452600060a483018190529251931694506352afbc33935060c48181019391829003018183876161da5a03f115610002575050505050565b6103c460025481565b61008260005433600160a060020a039081169116146103ce575b565b6103c460015460a860020a900460ff1681565b6100826001805475ff000000000000000000000000000000000000000000191660a860020a179055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527f185061da000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b600435600255610082565b6060908152602090f35b6001547f6ff96d17000000000000000000000000000000000000000000000000000000006060908152600160a060020a0330811660645290911690632e1a7d4d908290636ff96d17906084906020906024816000876161da5a03f1156100025750506040805180517f2e1a7d4d0000000000000000000000000000000000000000000000000000000082526004820152905160248281019350600092829003018183876161da5a03f115610002575050600054600160a060020a03169050ff",
- "storage": {
- "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601",
- "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000ff30c9e568f133adce1f1ea91e189613223fc461b9"
- }
- },
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x326601cc6cf364f6b9",
- "nonce": 12122
- },
- "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
- "balance": "0x1ff0509d9d6821e26",
- "nonce": 138
- }
- },
- "post": {
- "0x2a65aca4d5fc5b5c859090a6c34d164135398226": {
- "balance": "0x326604ee5f5eecd2b9"
- },
- "0xd3cda913deb6f67967b99d67acdfa1712c293601": {
- "balance": "0x1ff01e7e76afa4226",
- "nonce": 139
- }
- }
- }
-}
diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go
deleted file mode 100644
index 95d292c924..0000000000
--- a/eth/tracers/internal/tracetest/util.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package tracetest
-
-import (
- "strings"
- "unicode"
-
- // Force-load native and js packages, to trigger registration
- _ "github.com/ethereum/go-ethereum/eth/tracers/js"
- _ "github.com/ethereum/go-ethereum/eth/tracers/native"
-)
-
-// To generate a new callTracer test, copy paste the makeTest method below into
-// a Geth console and call it with a transaction hash you which to export.
-
-/*
-// makeTest generates a callTracer test by running a prestate reassembled and a
-// call trace run, assembling all the gathered information into a test case.
-var makeTest = function(tx, rewind) {
- // Generate the genesis block from the block, transaction and prestate data
- var block = eth.getBlock(eth.getTransaction(tx).blockHash);
- var genesis = eth.getBlock(block.parentHash);
-
- delete genesis.gasUsed;
- delete genesis.logsBloom;
- delete genesis.parentHash;
- delete genesis.receiptsRoot;
- delete genesis.sha3Uncles;
- delete genesis.size;
- delete genesis.transactions;
- delete genesis.transactionsRoot;
- delete genesis.uncles;
-
- genesis.gasLimit = genesis.gasLimit.toString();
- genesis.number = genesis.number.toString();
- genesis.timestamp = genesis.timestamp.toString();
-
- genesis.alloc = debug.traceTransaction(tx, {tracer: "prestateTracer", rewind: rewind});
- for (var key in genesis.alloc) {
- var nonce = genesis.alloc[key].nonce;
- if (nonce) {
- genesis.alloc[key].nonce = nonce.toString();
- }
- }
- genesis.config = admin.nodeInfo.protocols.eth.config;
-
- // Generate the call trace and produce the test input
- var result = debug.traceTransaction(tx, {tracer: "callTracer", rewind: rewind});
- delete result.time;
-
- console.log(JSON.stringify({
- genesis: genesis,
- context: {
- number: block.number.toString(),
- difficulty: block.difficulty,
- timestamp: block.timestamp.toString(),
- gasLimit: block.gasLimit.toString(),
- miner: block.miner,
- },
- input: eth.getRawTransaction(tx),
- result: result,
- }, null, 2));
-}
-*/
-
-// camel converts a snake cased input string into a camel cased output.
-func camel(str string) string {
- pieces := strings.Split(str, "_")
- for i := 1; i < len(pieces); i++ {
- pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:]
- }
- return strings.Join(pieces, "")
-}
diff --git a/eth/tracers/js/bigint.go b/eth/tracers/js/bigint.go
deleted file mode 100644
index 9aeb330420..0000000000
--- a/eth/tracers/js/bigint.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2021 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 js
-
-// bigIntegerJS is the minified version of https://github.com/peterolson/BigInteger.js.
-const bigIntegerJS = `var bigInt=function(undefined){"use strict";var BASE=1e7,LOG_BASE=7,MAX_INT=9007199254740992,MAX_INT_ARR=smallToArray(MAX_INT),LOG_MAX_INT=Math.log(MAX_INT);function Integer(v,radix){if(typeof v==="undefined")return Integer[0];if(typeof radix!=="undefined")return+radix===10?parseValue(v):parseBase(v,radix);return parseValue(v)}function BigInteger(value,sign){this.value=value;this.sign=sign;this.isSmall=false}BigInteger.prototype=Object.create(Integer.prototype);function SmallInteger(value){this.value=value;this.sign=value<0;this.isSmall=true}SmallInteger.prototype=Object.create(Integer.prototype);function isPrecise(n){return-MAX_INT0)return Math.floor(n);return Math.ceil(n)}function add(a,b){var l_a=a.length,l_b=b.length,r=new Array(l_a),carry=0,base=BASE,sum,i;for(i=0;i=base?1:0;r[i]=sum-carry*base}while(i0)r.push(carry);return r}function addAny(a,b){if(a.length>=b.length)return add(a,b);return add(b,a)}function addSmall(a,carry){var l=a.length,r=new Array(l),base=BASE,sum,i;for(i=0;i0){r[i++]=carry%base;carry=Math.floor(carry/base)}return r}BigInteger.prototype.add=function(v){var n=parseValue(v);if(this.sign!==n.sign){return this.subtract(n.negate())}var a=this.value,b=n.value;if(n.isSmall){return new BigInteger(addSmall(a,Math.abs(b)),this.sign)}return new BigInteger(addAny(a,b),this.sign)};BigInteger.prototype.plus=BigInteger.prototype.add;SmallInteger.prototype.add=function(v){var n=parseValue(v);var a=this.value;if(a<0!==n.sign){return this.subtract(n.negate())}var b=n.value;if(n.isSmall){if(isPrecise(a+b))return new SmallInteger(a+b);b=smallToArray(Math.abs(b))}return new BigInteger(addSmall(b,Math.abs(a)),a<0)};SmallInteger.prototype.plus=SmallInteger.prototype.add;function subtract(a,b){var a_l=a.length,b_l=b.length,r=new Array(a_l),borrow=0,base=BASE,i,difference;for(i=0;i=0){value=subtract(a,b)}else{value=subtract(b,a);sign=!sign}value=arrayToSmall(value);if(typeof value==="number"){if(sign)value=-value;return new SmallInteger(value)}return new BigInteger(value,sign)}function subtractSmall(a,b,sign){var l=a.length,r=new Array(l),carry=-b,base=BASE,i,difference;for(i=0;i=0)};SmallInteger.prototype.minus=SmallInteger.prototype.subtract;BigInteger.prototype.negate=function(){return new BigInteger(this.value,!this.sign)};SmallInteger.prototype.negate=function(){var sign=this.sign;var small=new SmallInteger(-this.value);small.sign=!sign;return small};BigInteger.prototype.abs=function(){return new BigInteger(this.value,false)};SmallInteger.prototype.abs=function(){return new SmallInteger(Math.abs(this.value))};function multiplyLong(a,b){var a_l=a.length,b_l=b.length,l=a_l+b_l,r=createArray(l),base=BASE,product,carry,i,a_i,b_j;for(i=0;i0){r[i++]=carry%base;carry=Math.floor(carry/base)}return r}function shiftLeft(x,n){var r=[];while(n-- >0)r.push(0);return r.concat(x)}function multiplyKaratsuba(x,y){var n=Math.max(x.length,y.length);if(n<=30)return multiplyLong(x,y);n=Math.ceil(n/2);var b=x.slice(n),a=x.slice(0,n),d=y.slice(n),c=y.slice(0,n);var ac=multiplyKaratsuba(a,c),bd=multiplyKaratsuba(b,d),abcd=multiplyKaratsuba(addAny(a,b),addAny(c,d));var product=addAny(addAny(ac,shiftLeft(subtract(subtract(abcd,ac),bd),n)),shiftLeft(bd,2*n));trim(product);return product}function useKaratsuba(l1,l2){return-.012*l1-.012*l2+15e-6*l1*l2>0}BigInteger.prototype.multiply=function(v){var n=parseValue(v),a=this.value,b=n.value,sign=this.sign!==n.sign,abs;if(n.isSmall){if(b===0)return Integer[0];if(b===1)return this;if(b===-1)return this.negate();abs=Math.abs(b);if(abs=0;shift--){quotientDigit=base-1;if(remainder[shift+b_l]!==divisorMostSignificantDigit){quotientDigit=Math.floor((remainder[shift+b_l]*base+remainder[shift+b_l-1])/divisorMostSignificantDigit)}carry=0;borrow=0;l=divisor.length;for(i=0;ib_l){highx=(highx+1)*base}guess=Math.ceil(highx/highy);do{check=multiplySmall(b,guess);if(compareAbs(check,part)<=0)break;guess--}while(guess);result.push(guess);part=subtract(part,check)}result.reverse();return[arrayToSmall(result),arrayToSmall(part)]}function divModSmall(value,lambda){var length=value.length,quotient=createArray(length),base=BASE,i,q,remainder,divisor;remainder=0;for(i=length-1;i>=0;--i){divisor=remainder*base+value[i];q=truncate(divisor/lambda);remainder=divisor-q*lambda;quotient[i]=q|0}return[quotient,remainder|0]}function divModAny(self,v){var value,n=parseValue(v);var a=self.value,b=n.value;var quotient;if(b===0)throw new Error("Cannot divide by zero");if(self.isSmall){if(n.isSmall){return[new SmallInteger(truncate(a/b)),new SmallInteger(a%b)]}return[Integer[0],self]}if(n.isSmall){if(b===1)return[self,Integer[0]];if(b==-1)return[self.negate(),Integer[0]];var abs=Math.abs(b);if(absb.length?1:-1}for(var i=a.length-1;i>=0;i--){if(a[i]!==b[i])return a[i]>b[i]?1:-1}return 0}BigInteger.prototype.compareAbs=function(v){var n=parseValue(v),a=this.value,b=n.value;if(n.isSmall)return 1;return compareAbs(a,b)};SmallInteger.prototype.compareAbs=function(v){var n=parseValue(v),a=Math.abs(this.value),b=n.value;if(n.isSmall){b=Math.abs(b);return a===b?0:a>b?1:-1}return-1};BigInteger.prototype.compare=function(v){if(v===Infinity){return-1}if(v===-Infinity){return 1}var n=parseValue(v),a=this.value,b=n.value;if(this.sign!==n.sign){return n.sign?1:-1}if(n.isSmall){return this.sign?-1:1}return compareAbs(a,b)*(this.sign?-1:1)};BigInteger.prototype.compareTo=BigInteger.prototype.compare;SmallInteger.prototype.compare=function(v){if(v===Infinity){return-1}if(v===-Infinity){return 1}var n=parseValue(v),a=this.value,b=n.value;if(n.isSmall){return a==b?0:a>b?1:-1}if(a<0!==n.sign){return a<0?-1:1}return a<0?1:-1};SmallInteger.prototype.compareTo=SmallInteger.prototype.compare;BigInteger.prototype.equals=function(v){return this.compare(v)===0};SmallInteger.prototype.eq=SmallInteger.prototype.equals=BigInteger.prototype.eq=BigInteger.prototype.equals;BigInteger.prototype.notEquals=function(v){return this.compare(v)!==0};SmallInteger.prototype.neq=SmallInteger.prototype.notEquals=BigInteger.prototype.neq=BigInteger.prototype.notEquals;BigInteger.prototype.greater=function(v){return this.compare(v)>0};SmallInteger.prototype.gt=SmallInteger.prototype.greater=BigInteger.prototype.gt=BigInteger.prototype.greater;BigInteger.prototype.lesser=function(v){return this.compare(v)<0};SmallInteger.prototype.lt=SmallInteger.prototype.lesser=BigInteger.prototype.lt=BigInteger.prototype.lesser;BigInteger.prototype.greaterOrEquals=function(v){return this.compare(v)>=0};SmallInteger.prototype.geq=SmallInteger.prototype.greaterOrEquals=BigInteger.prototype.geq=BigInteger.prototype.greaterOrEquals;BigInteger.prototype.lesserOrEquals=function(v){return this.compare(v)<=0};SmallInteger.prototype.leq=SmallInteger.prototype.lesserOrEquals=BigInteger.prototype.leq=BigInteger.prototype.lesserOrEquals;BigInteger.prototype.isEven=function(){return(this.value[0]&1)===0};SmallInteger.prototype.isEven=function(){return(this.value&1)===0};BigInteger.prototype.isOdd=function(){return(this.value[0]&1)===1};SmallInteger.prototype.isOdd=function(){return(this.value&1)===1};BigInteger.prototype.isPositive=function(){return!this.sign};SmallInteger.prototype.isPositive=function(){return this.value>0};BigInteger.prototype.isNegative=function(){return this.sign};SmallInteger.prototype.isNegative=function(){return this.value<0};BigInteger.prototype.isUnit=function(){return false};SmallInteger.prototype.isUnit=function(){return Math.abs(this.value)===1};BigInteger.prototype.isZero=function(){return false};SmallInteger.prototype.isZero=function(){return this.value===0};BigInteger.prototype.isDivisibleBy=function(v){var n=parseValue(v);var value=n.value;if(value===0)return false;if(value===1)return true;if(value===2)return this.isEven();return this.mod(n).equals(Integer[0])};SmallInteger.prototype.isDivisibleBy=BigInteger.prototype.isDivisibleBy;function isBasicPrime(v){var n=v.abs();if(n.isUnit())return false;if(n.equals(2)||n.equals(3)||n.equals(5))return true;if(n.isEven()||n.isDivisibleBy(3)||n.isDivisibleBy(5))return false;if(n.lesser(25))return true}BigInteger.prototype.isPrime=function(){var isPrime=isBasicPrime(this);if(isPrime!==undefined)return isPrime;var n=this.abs(),nPrev=n.prev();var a=[2,3,5,7,11,13,17,19],b=nPrev,d,t,i,x;while(b.isEven())b=b.divide(2);for(i=0;i-MAX_INT)return new SmallInteger(value-1);return new BigInteger(MAX_INT_ARR,true)};var powersOfTwo=[1];while(2*powersOfTwo[powersOfTwo.length-1]<=BASE)powersOfTwo.push(2*powersOfTwo[powersOfTwo.length-1]);var powers2Length=powersOfTwo.length,highestPower2=powersOfTwo[powers2Length-1];function shift_isSmall(n){return(typeof n==="number"||typeof n==="string")&&+Math.abs(n)<=BASE||n instanceof BigInteger&&n.value.length<=1}BigInteger.prototype.shiftLeft=function(n){if(!shift_isSmall(n)){throw new Error(String(n)+" is too large for shifting.")}n=+n;if(n<0)return this.shiftRight(-n);var result=this;while(n>=powers2Length){result=result.multiply(highestPower2);n-=powers2Length-1}return result.multiply(powersOfTwo[n])};SmallInteger.prototype.shiftLeft=BigInteger.prototype.shiftLeft;BigInteger.prototype.shiftRight=function(n){var remQuo;if(!shift_isSmall(n)){throw new Error(String(n)+" is too large for shifting.")}n=+n;if(n<0)return this.shiftLeft(-n);var result=this;while(n>=powers2Length){if(result.isZero())return result;remQuo=divModAny(result,highestPower2);result=remQuo[1].isNegative()?remQuo[0].prev():remQuo[0];n-=powers2Length-1}remQuo=divModAny(result,powersOfTwo[n]);return remQuo[1].isNegative()?remQuo[0].prev():remQuo[0]};SmallInteger.prototype.shiftRight=BigInteger.prototype.shiftRight;function bitwise(x,y,fn){y=parseValue(y);var xSign=x.isNegative(),ySign=y.isNegative();var xRem=xSign?x.not():x,yRem=ySign?y.not():y;var xDigit=0,yDigit=0;var xDivMod=null,yDivMod=null;var result=[];while(!xRem.isZero()||!yRem.isZero()){xDivMod=divModAny(xRem,highestPower2);xDigit=xDivMod[1].toJSNumber();if(xSign){xDigit=highestPower2-1-xDigit}yDivMod=divModAny(yRem,highestPower2);yDigit=yDivMod[1].toJSNumber();if(ySign){yDigit=highestPower2-1-yDigit}xRem=xDivMod[0];yRem=yDivMod[0];result.push(fn(xDigit,yDigit))}var sum=fn(xSign?1:0,ySign?1:0)!==0?bigInt(-1):bigInt(0);for(var i=result.length-1;i>=0;i-=1){sum=sum.multiply(highestPower2).add(bigInt(result[i]))}return sum}BigInteger.prototype.not=function(){return this.negate().prev()};SmallInteger.prototype.not=BigInteger.prototype.not;BigInteger.prototype.and=function(n){return bitwise(this,n,function(a,b){return a&b})};SmallInteger.prototype.and=BigInteger.prototype.and;BigInteger.prototype.or=function(n){return bitwise(this,n,function(a,b){return a|b})};SmallInteger.prototype.or=BigInteger.prototype.or;BigInteger.prototype.xor=function(n){return bitwise(this,n,function(a,b){return a^b})};SmallInteger.prototype.xor=BigInteger.prototype.xor;var LOBMASK_I=1<<30,LOBMASK_BI=(BASE&-BASE)*(BASE&-BASE)|LOBMASK_I;function roughLOB(n){var v=n.value,x=typeof v==="number"?v|LOBMASK_I:v[0]+v[1]*BASE|LOBMASK_BI;return x&-x}function max(a,b){a=parseValue(a);b=parseValue(b);return a.greater(b)?a:b}function min(a,b){a=parseValue(a);b=parseValue(b);return a.lesser(b)?a:b}function gcd(a,b){a=parseValue(a).abs();b=parseValue(b).abs();if(a.equals(b))return a;if(a.isZero())return b;if(b.isZero())return a;var c=Integer[1],d,t;while(a.isEven()&&b.isEven()){d=Math.min(roughLOB(a),roughLOB(b));a=a.divide(d);b=b.divide(d);c=c.multiply(d)}while(a.isEven()){a=a.divide(roughLOB(a))}do{while(b.isEven()){b=b.divide(roughLOB(b))}if(a.greater(b)){t=b;b=a;a=t}b=b.subtract(a)}while(!b.isZero());return c.isUnit()?a:a.multiply(c)}function lcm(a,b){a=parseValue(a).abs();b=parseValue(b).abs();return a.divide(gcd(a,b)).multiply(b)}function randBetween(a,b){a=parseValue(a);b=parseValue(b);var low=min(a,b),high=max(a,b);var range=high.subtract(low).add(1);if(range.isSmall)return low.add(Math.floor(Math.random()*range));var length=range.value.length-1;var result=[],restricted=true;for(var i=length;i>=0;i--){var top=restricted?range.value[i]:BASE;var digit=truncate(Math.random()*top);result.unshift(digit);if(digit=absBase){if(c==="1"&&absBase===1)continue;throw new Error(c+" is not a valid digit in base "+base+".")}else if(c.charCodeAt(0)-87>=absBase){throw new Error(c+" is not a valid digit in base "+base+".")}}}if(2<=base&&base<=36){if(length<=LOG_MAX_INT/Math.log(base)){var result=parseInt(text,base);if(isNaN(result)){throw new Error(c+" is not a valid digit in base "+base+".")}return new SmallInteger(parseInt(text,base))}}base=parseValue(base);var digits=[];var isNegative=text[0]==="-";for(i=isNegative?1:0;i");digits.push(parseValue(text.slice(start+1,i)))}else throw new Error(c+" is not a valid character")}return parseBaseFromArray(digits,base,isNegative)};function parseBaseFromArray(digits,base,isNegative){var val=Integer[0],pow=Integer[1],i;for(i=digits.length-1;i>=0;i--){val=val.add(digits[i].times(pow));pow=pow.times(base)}return isNegative?val.negate():val}function stringify(digit){var v=digit.value;if(typeof v==="number")v=[v];if(v.length===1&&v[0]<=35){return"0123456789abcdefghijklmnopqrstuvwxyz".charAt(v[0])}return"<"+v+">"}function toBase(n,base){base=bigInt(base);if(base.isZero()){if(n.isZero())return"0";throw new Error("Cannot convert nonzero numbers to base 0.")}if(base.equals(-1)){if(n.isZero())return"0";if(n.isNegative())return new Array(1-n).join("10");return"1"+new Array(+n).join("01")}var minusSign="";if(n.isNegative()&&base.isPositive()){minusSign="-";n=n.abs()}if(base.equals(1)){if(n.isZero())return"0";return minusSign+new Array(+n+1).join(1)}var out=[];var left=n,divmod;while(left.isNegative()||left.compareAbs(base)>=0){divmod=left.divmod(base);left=divmod.quotient;var digit=divmod.remainder;if(digit.isNegative()){digit=base.minus(digit).abs();left=left.next()}out.push(stringify(digit))}out.push(stringify(left));return minusSign+out.reverse().join("")}BigInteger.prototype.toString=function(radix){if(radix===undefined)radix=10;if(radix!==10)return toBase(this,radix);var v=this.value,l=v.length,str=String(v[--l]),zeros="0000000",digit;while(--l>=0){digit=String(v[l]);str+=zeros.slice(digit.length)+digit}var sign=this.sign?"-":"";return sign+str};SmallInteger.prototype.toString=function(radix){if(radix===undefined)radix=10;if(radix!=10)return toBase(this,radix);return String(this.value)};BigInteger.prototype.toJSON=SmallInteger.prototype.toJSON=function(){return this.toString()};BigInteger.prototype.valueOf=function(){return+this.toString()};BigInteger.prototype.toJSNumber=BigInteger.prototype.valueOf;SmallInteger.prototype.valueOf=function(){return this.value};SmallInteger.prototype.toJSNumber=SmallInteger.prototype.valueOf;function parseStringValue(v){if(isPrecise(+v)){var x=+v;if(x===truncate(x))return new SmallInteger(x);throw"Invalid integer: "+v}var sign=v[0]==="-";if(sign)v=v.slice(1);var split=v.split(/e/i);if(split.length>2)throw new Error("Invalid integer: "+split.join("e"));if(split.length===2){var exp=split[1];if(exp[0]==="+")exp=exp.slice(1);exp=+exp;if(exp!==truncate(exp)||!isPrecise(exp))throw new Error("Invalid integer: "+exp+" is not a valid exponent.");var text=split[0];var decimalPlace=text.indexOf(".");if(decimalPlace>=0){exp-=text.length-decimalPlace-1;text=text.slice(0,decimalPlace)+text.slice(decimalPlace+1)}if(exp<0)throw new Error("Cannot include negative exponent part for integers");text+=new Array(exp+1).join("0");v=text}var isValid=/^([0-9][0-9]*)$/.test(v);if(!isValid)throw new Error("Invalid integer: "+v);var r=[],max=v.length,l=LOG_BASE,min=max-l;while(max>0){r.push(+v.slice(min,max));min-=l;if(min<0)min=0;max-=l}trim(r);return new BigInteger(r,sign)}function parseNumberValue(v){if(isPrecise(v)){if(v!==truncate(v))throw new Error(v+" is not an integer.");return new SmallInteger(v)}return parseStringValue(v.toString())}function parseValue(v){if(typeof v==="number"){return parseNumberValue(v)}if(typeof v==="string"){return parseStringValue(v)}return v}for(var i=0;i<1e3;i++){Integer[i]=new SmallInteger(i);if(i>0)Integer[-i]=new SmallInteger(-i)}Integer.one=Integer[1];Integer.zero=Integer[0];Integer.minusOne=Integer[-1];Integer.max=max;Integer.min=min;Integer.gcd=gcd;Integer.lcm=lcm;Integer.isInstance=function(x){return x instanceof BigInteger||x instanceof SmallInteger};Integer.randBetween=randBetween;Integer.fromArray=function(digits,base,isNegative){return parseBaseFromArray(digits.map(parseValue),parseValue(base||10),isNegative)};return Integer}();if(typeof module!=="undefined"&&module.hasOwnProperty("exports")){module.exports=bigInt}if(typeof define==="function"&&define.amd){define("big-integer",[],function(){return bigInt})}; bigInt`
diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go
deleted file mode 100644
index 07c138bae4..0000000000
--- a/eth/tracers/js/goja.go
+++ /dev/null
@@ -1,992 +0,0 @@
-// 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 js
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
-
- "github.com/dop251/goja"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/eth/tracers"
- jsassets "github.com/ethereum/go-ethereum/eth/tracers/js/internal/tracers"
-)
-
-var assetTracers = make(map[string]string)
-
-// init retrieves the JavaScript transaction tracers included in go-ethereum.
-func init() {
- var err error
- assetTracers, err = jsassets.Load()
- if err != nil {
- panic(err)
- }
- type ctorFn = func(*tracers.Context, json.RawMessage) (tracers.Tracer, error)
- lookup := func(code string) ctorFn {
- return func(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
- return newJsTracer(code, ctx, cfg)
- }
- }
- for name, code := range assetTracers {
- tracers.DefaultDirectory.Register(name, lookup(code), true)
- }
- tracers.DefaultDirectory.RegisterJSEval(newJsTracer)
-}
-
-// bigIntProgram is compiled once and the exported function mostly invoked to convert
-// hex strings into big ints.
-var bigIntProgram = goja.MustCompile("bigInt", bigIntegerJS, false)
-
-type toBigFn = func(vm *goja.Runtime, val string) (goja.Value, error)
-type toBufFn = func(vm *goja.Runtime, val []byte) (goja.Value, error)
-type fromBufFn = func(vm *goja.Runtime, buf goja.Value, allowString bool) ([]byte, error)
-
-func toBuf(vm *goja.Runtime, bufType goja.Value, val []byte) (goja.Value, error) {
- // bufType is usually Uint8Array. This is equivalent to `new Uint8Array(val)` in JS.
- return vm.New(bufType, vm.ToValue(vm.NewArrayBuffer(val)))
-}
-
-func fromBuf(vm *goja.Runtime, bufType goja.Value, buf goja.Value, allowString bool) ([]byte, error) {
- obj := buf.ToObject(vm)
- switch obj.ClassName() {
- case "String":
- if !allowString {
- break
- }
- return common.FromHex(obj.String()), nil
-
- case "Array":
- var b []byte
- if err := vm.ExportTo(buf, &b); err != nil {
- return nil, err
- }
- return b, nil
-
- case "Object":
- if !obj.Get("constructor").SameAs(bufType) {
- break
- }
- b := obj.Export().([]byte)
- return b, nil
- }
- return nil, errors.New("invalid buffer type")
-}
-
-// jsTracer is an implementation of the Tracer interface which evaluates
-// JS functions on the relevant EVM hooks. It uses Goja as its JS engine.
-type jsTracer struct {
- vm *goja.Runtime
- env *vm.EVM
- toBig toBigFn // Converts a hex string into a JS bigint
- toBuf toBufFn // Converts a []byte into a JS buffer
- fromBuf fromBufFn // Converts an array, hex string or Uint8Array to a []byte
- ctx map[string]goja.Value // KV-bag passed to JS in `result`
- activePrecompiles []common.Address // List of active precompiles at current block
- traceStep bool // True if tracer object exposes a `step()` method
- traceFrame bool // True if tracer object exposes the `enter()` and `exit()` methods
- gasLimit uint64 // Amount of gas bought for the whole tx
- err error // Any error that should stop tracing
- obj *goja.Object // Trace object
-
- // Methods exposed by tracer
- result goja.Callable
- fault goja.Callable
- step goja.Callable
- enter goja.Callable
- exit goja.Callable
-
- // Underlying structs being passed into JS
- log *steplog
- frame *callframe
- frameResult *callframeResult
-
- // Goja-wrapping of types prepared for JS consumption
- logValue goja.Value
- dbValue goja.Value
- frameValue goja.Value
- frameResultValue goja.Value
-}
-
-// newJsTracer instantiates a new JS tracer instance. code is a
-// Javascript snippet which evaluates to an expression returning
-// an object with certain methods:
-//
-// The methods `result` and `fault` are required to be present.
-// The methods `step`, `enter`, and `exit` are optional, but note that
-// `enter` and `exit` always go together.
-func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
- vm := goja.New()
- // By default field names are exported to JS as is, i.e. capitalized.
- vm.SetFieldNameMapper(goja.UncapFieldNameMapper())
- t := &jsTracer{
- vm: vm,
- ctx: make(map[string]goja.Value),
- }
-
- t.setTypeConverters()
- t.setBuiltinFunctions()
-
- if ctx == nil {
- ctx = new(tracers.Context)
- }
- if ctx.BlockHash != (common.Hash{}) {
- blockHash, err := t.toBuf(vm, ctx.BlockHash.Bytes())
- if err != nil {
- return nil, err
- }
- t.ctx["blockHash"] = blockHash
- if ctx.TxHash != (common.Hash{}) {
- t.ctx["txIndex"] = vm.ToValue(ctx.TxIndex)
- txHash, err := t.toBuf(vm, ctx.TxHash.Bytes())
- if err != nil {
- return nil, err
- }
- t.ctx["txHash"] = txHash
- }
- }
-
- ret, err := vm.RunString("(" + code + ")")
- if err != nil {
- return nil, err
- }
- // Check tracer's interface for required and optional methods.
- obj := ret.ToObject(vm)
- result, ok := goja.AssertFunction(obj.Get("result"))
- if !ok {
- return nil, errors.New("trace object must expose a function result()")
- }
- fault, ok := goja.AssertFunction(obj.Get("fault"))
- if !ok {
- return nil, errors.New("trace object must expose a function fault()")
- }
- step, ok := goja.AssertFunction(obj.Get("step"))
- t.traceStep = ok
- enter, hasEnter := goja.AssertFunction(obj.Get("enter"))
- exit, hasExit := goja.AssertFunction(obj.Get("exit"))
- if hasEnter != hasExit {
- return nil, errors.New("trace object must expose either both or none of enter() and exit()")
- }
- t.traceFrame = hasEnter
- t.obj = obj
- t.step = step
- t.enter = enter
- t.exit = exit
- t.result = result
- t.fault = fault
-
- // Pass in config
- if setup, ok := goja.AssertFunction(obj.Get("setup")); ok {
- cfgStr := "{}"
- if cfg != nil {
- cfgStr = string(cfg)
- }
- if _, err := setup(obj, vm.ToValue(cfgStr)); err != nil {
- return nil, err
- }
- }
- // Setup objects carrying data to JS. These are created once and re-used.
- t.log = &steplog{
- vm: vm,
- op: &opObj{vm: vm},
- memory: &memoryObj{vm: vm, toBig: t.toBig, toBuf: t.toBuf},
- stack: &stackObj{vm: vm, toBig: t.toBig},
- contract: &contractObj{vm: vm, toBig: t.toBig, toBuf: t.toBuf},
- }
- t.frame = &callframe{vm: vm, toBig: t.toBig, toBuf: t.toBuf}
- t.frameResult = &callframeResult{vm: vm, toBuf: t.toBuf}
- t.frameValue = t.frame.setupObject()
- t.frameResultValue = t.frameResult.setupObject()
- t.logValue = t.log.setupObject()
- return t, nil
-}
-
-// CaptureTxStart implements the Tracer interface and is invoked at the beginning of
-// transaction processing.
-func (t *jsTracer) CaptureTxStart(gasLimit uint64) {
- t.gasLimit = gasLimit
-}
-
-// CaptureTxEnd implements the Tracer interface and is invoked at the end of
-// transaction processing.
-func (t *jsTracer) CaptureTxEnd(restGas uint64) {
- t.ctx["gasUsed"] = t.vm.ToValue(t.gasLimit - restGas)
-}
-
-// CaptureStart implements the Tracer interface to initialize the tracing operation.
-func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- cancel := func(err error) {
- t.err = err
- t.env.Cancel()
- }
- t.env = env
- db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf}
- t.dbValue = db.setupObject()
- if create {
- t.ctx["type"] = t.vm.ToValue("CREATE")
- } else {
- t.ctx["type"] = t.vm.ToValue("CALL")
- }
- fromVal, err := t.toBuf(t.vm, from.Bytes())
- if err != nil {
- cancel(err)
- return
- }
- t.ctx["from"] = fromVal
- toVal, err := t.toBuf(t.vm, to.Bytes())
- if err != nil {
- cancel(err)
- return
- }
- t.ctx["to"] = toVal
- inputVal, err := t.toBuf(t.vm, input)
- if err != nil {
- cancel(err)
- return
- }
- t.ctx["input"] = inputVal
- t.ctx["gas"] = t.vm.ToValue(t.gasLimit)
- gasPriceBig, err := t.toBig(t.vm, env.TxContext.GasPrice.String())
- if err != nil {
- cancel(err)
- return
- }
- t.ctx["gasPrice"] = gasPriceBig
- valueBig, err := t.toBig(t.vm, value.String())
- if err != nil {
- cancel(err)
- return
- }
- t.ctx["value"] = valueBig
- t.ctx["block"] = t.vm.ToValue(env.Context.BlockNumber.Uint64())
- // Update list of precompiles based on current block
- rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time)
- t.activePrecompiles = vm.ActivePrecompiles(rules)
-}
-
-// CaptureState implements the Tracer interface to trace a single step of VM execution.
-func (t *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- if !t.traceStep {
- return
- }
- if t.err != nil {
- return
- }
-
- log := t.log
- log.op.op = op
- log.memory.memory = scope.Memory
- log.stack.stack = scope.Stack
- log.contract.contract = scope.Contract
- log.pc = pc
- log.gas = gas
- log.cost = cost
- log.refund = t.env.StateDB.GetRefund()
- log.depth = depth
- log.err = err
- if _, err := t.step(t.obj, t.logValue, t.dbValue); err != nil {
- t.onError("step", err)
- }
-}
-
-// CaptureFault implements the Tracer interface to trace an execution fault
-func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
- if t.err != nil {
- return
- }
- // Other log fields have been already set as part of the last CaptureState.
- t.log.err = err
- if _, err := t.fault(t.obj, t.logValue, t.dbValue); err != nil {
- t.onError("fault", err)
- }
-}
-
-// CaptureEnd is called after the call finishes to finalize the tracing.
-func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
- if err != nil {
- t.ctx["error"] = t.vm.ToValue(err.Error())
- }
- outputVal, err := t.toBuf(t.vm, output)
- if err != nil {
- t.err = err
- return
- }
- t.ctx["output"] = outputVal
-}
-
-// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
-func (t *jsTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
- if !t.traceFrame {
- return
- }
- if t.err != nil {
- return
- }
-
- t.frame.typ = typ.String()
- t.frame.from = from
- t.frame.to = to
- t.frame.input = common.CopyBytes(input)
- t.frame.gas = uint(gas)
- t.frame.value = nil
- if value != nil {
- t.frame.value = new(big.Int).SetBytes(value.Bytes())
- }
-
- if _, err := t.enter(t.obj, t.frameValue); err != nil {
- t.onError("enter", err)
- }
-}
-
-// CaptureExit is called when EVM exits a scope, even if the scope didn't
-// execute any code.
-func (t *jsTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
- if !t.traceFrame {
- return
- }
-
- t.frameResult.gasUsed = uint(gasUsed)
- t.frameResult.output = common.CopyBytes(output)
- t.frameResult.err = err
-
- if _, err := t.exit(t.obj, t.frameResultValue); err != nil {
- t.onError("exit", err)
- }
-}
-
-// GetResult calls the Javascript 'result' function and returns its value, or any accumulated error
-func (t *jsTracer) GetResult() (json.RawMessage, error) {
- ctx := t.vm.ToValue(t.ctx)
- res, err := t.result(t.obj, ctx, t.dbValue)
- if err != nil {
- return nil, wrapError("result", err)
- }
- encoded, err := json.Marshal(res)
- if err != nil {
- return nil, err
- }
- return json.RawMessage(encoded), t.err
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (t *jsTracer) Stop(err error) {
- t.vm.Interrupt(err)
-}
-
-// onError is called anytime the running JS code is interrupted
-// and returns an error. It in turn pings the EVM to cancel its
-// execution.
-func (t *jsTracer) onError(context string, err error) {
- t.err = wrapError(context, err)
- // `env` is set on CaptureStart which comes before any JS execution.
- // So it should be non-nil.
- t.env.Cancel()
-}
-
-func wrapError(context string, err error) error {
- return fmt.Errorf("%v in server-side tracer function '%v'", err, context)
-}
-
-// setBuiltinFunctions injects Go functions which are available to tracers into the environment.
-// It depends on type converters having been set up.
-func (t *jsTracer) setBuiltinFunctions() {
- vm := t.vm
- // TODO: load console from goja-nodejs
- vm.Set("toHex", func(v goja.Value) string {
- b, err := t.fromBuf(vm, v, false)
- if err != nil {
- vm.Interrupt(err)
- return ""
- }
- return hexutil.Encode(b)
- })
- vm.Set("toWord", func(v goja.Value) goja.Value {
- // TODO: add test with []byte len < 32 or > 32
- b, err := t.fromBuf(vm, v, true)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- b = common.BytesToHash(b).Bytes()
- res, err := t.toBuf(vm, b)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- return res
- })
- vm.Set("toAddress", func(v goja.Value) goja.Value {
- a, err := t.fromBuf(vm, v, true)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- a = common.BytesToAddress(a).Bytes()
- res, err := t.toBuf(vm, a)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- return res
- })
- vm.Set("toContract", func(from goja.Value, nonce uint) goja.Value {
- a, err := t.fromBuf(vm, from, true)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- addr := common.BytesToAddress(a)
- b := crypto.CreateAddress(addr, uint64(nonce)).Bytes()
- res, err := t.toBuf(vm, b)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- return res
- })
- vm.Set("toContract2", func(from goja.Value, salt string, initcode goja.Value) goja.Value {
- a, err := t.fromBuf(vm, from, true)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- addr := common.BytesToAddress(a)
- code, err := t.fromBuf(vm, initcode, true)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- code = common.CopyBytes(code)
- codeHash := crypto.Keccak256(code)
- b := crypto.CreateAddress2(addr, common.HexToHash(salt), codeHash).Bytes()
- res, err := t.toBuf(vm, b)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- return res
- })
- vm.Set("isPrecompiled", func(v goja.Value) bool {
- a, err := t.fromBuf(vm, v, true)
- if err != nil {
- vm.Interrupt(err)
- return false
- }
- addr := common.BytesToAddress(a)
- for _, p := range t.activePrecompiles {
- if p == addr {
- return true
- }
- }
- return false
- })
- vm.Set("slice", func(slice goja.Value, start, end int64) goja.Value {
- b, err := t.fromBuf(vm, slice, false)
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- if start < 0 || start > end || end > int64(len(b)) {
- vm.Interrupt(fmt.Sprintf("Tracer accessed out of bound memory: available %d, offset %d, size %d", len(b), start, end-start))
- return nil
- }
- res, err := t.toBuf(vm, b[start:end])
- if err != nil {
- vm.Interrupt(err)
- return nil
- }
- return res
- })
-}
-
-// setTypeConverters sets up utilities for converting Go types into those
-// suitable for JS consumption.
-func (t *jsTracer) setTypeConverters() error {
- // Inject bigint logic.
- // TODO: To be replaced after goja adds support for native JS bigint.
- toBigCode, err := t.vm.RunProgram(bigIntProgram)
- if err != nil {
- return err
- }
- // Used to create JS bigint objects from go.
- toBigFn, ok := goja.AssertFunction(toBigCode)
- if !ok {
- return errors.New("failed to bind bigInt func")
- }
- toBigWrapper := func(vm *goja.Runtime, val string) (goja.Value, error) {
- return toBigFn(goja.Undefined(), vm.ToValue(val))
- }
- t.toBig = toBigWrapper
- // NOTE: We need this workaround to create JS buffers because
- // goja doesn't at the moment expose constructors for typed arrays.
- //
- // Cache uint8ArrayType once to be used every time for less overhead.
- uint8ArrayType := t.vm.Get("Uint8Array")
- toBufWrapper := func(vm *goja.Runtime, val []byte) (goja.Value, error) {
- return toBuf(vm, uint8ArrayType, val)
- }
- t.toBuf = toBufWrapper
- fromBufWrapper := func(vm *goja.Runtime, buf goja.Value, allowString bool) ([]byte, error) {
- return fromBuf(vm, uint8ArrayType, buf, allowString)
- }
- t.fromBuf = fromBufWrapper
- return nil
-}
-
-type opObj struct {
- vm *goja.Runtime
- op vm.OpCode
-}
-
-func (o *opObj) ToNumber() int {
- return int(o.op)
-}
-
-func (o *opObj) ToString() string {
- return o.op.String()
-}
-
-func (o *opObj) IsPush() bool {
- return o.op.IsPush()
-}
-
-func (o *opObj) setupObject() *goja.Object {
- obj := o.vm.NewObject()
- obj.Set("toNumber", o.vm.ToValue(o.ToNumber))
- obj.Set("toString", o.vm.ToValue(o.ToString))
- obj.Set("isPush", o.vm.ToValue(o.IsPush))
- return obj
-}
-
-type memoryObj struct {
- memory *vm.Memory
- vm *goja.Runtime
- toBig toBigFn
- toBuf toBufFn
-}
-
-func (mo *memoryObj) Slice(begin, end int64) goja.Value {
- b, err := mo.slice(begin, end)
- if err != nil {
- mo.vm.Interrupt(err)
- return nil
- }
- res, err := mo.toBuf(mo.vm, b)
- if err != nil {
- mo.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-// slice returns the requested range of memory as a byte slice.
-func (mo *memoryObj) slice(begin, end int64) ([]byte, error) {
- if end == begin {
- return []byte{}, nil
- }
- if end < begin || begin < 0 {
- return nil, fmt.Errorf("tracer accessed out of bound memory: offset %d, end %d", begin, end)
- }
- slice, err := tracers.GetMemoryCopyPadded(mo.memory, begin, end-begin)
- if err != nil {
- return nil, err
- }
- return slice, nil
-}
-
-func (mo *memoryObj) GetUint(addr int64) goja.Value {
- value, err := mo.getUint(addr)
- if err != nil {
- mo.vm.Interrupt(err)
- return nil
- }
- res, err := mo.toBig(mo.vm, value.String())
- if err != nil {
- mo.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-// getUint returns the 32 bytes at the specified address interpreted as a uint.
-func (mo *memoryObj) getUint(addr int64) (*big.Int, error) {
- if mo.memory.Len() < int(addr)+32 || addr < 0 {
- return nil, fmt.Errorf("tracer accessed out of bound memory: available %d, offset %d, size %d", mo.memory.Len(), addr, 32)
- }
- return new(big.Int).SetBytes(mo.memory.GetPtr(addr, 32)), nil
-}
-
-func (mo *memoryObj) Length() int {
- return mo.memory.Len()
-}
-
-func (m *memoryObj) setupObject() *goja.Object {
- o := m.vm.NewObject()
- o.Set("slice", m.vm.ToValue(m.Slice))
- o.Set("getUint", m.vm.ToValue(m.GetUint))
- o.Set("length", m.vm.ToValue(m.Length))
- return o
-}
-
-type stackObj struct {
- stack *vm.Stack
- vm *goja.Runtime
- toBig toBigFn
-}
-
-func (s *stackObj) Peek(idx int) goja.Value {
- value, err := s.peek(idx)
- if err != nil {
- s.vm.Interrupt(err)
- return nil
- }
- res, err := s.toBig(s.vm, value.String())
- if err != nil {
- s.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-// peek returns the nth-from-the-top element of the stack.
-func (s *stackObj) peek(idx int) (*big.Int, error) {
- if len(s.stack.Data()) <= idx || idx < 0 {
- return nil, fmt.Errorf("tracer accessed out of bound stack: size %d, index %d", len(s.stack.Data()), idx)
- }
- return s.stack.Back(idx).ToBig(), nil
-}
-
-func (s *stackObj) Length() int {
- return len(s.stack.Data())
-}
-
-func (s *stackObj) setupObject() *goja.Object {
- o := s.vm.NewObject()
- o.Set("peek", s.vm.ToValue(s.Peek))
- o.Set("length", s.vm.ToValue(s.Length))
- return o
-}
-
-type dbObj struct {
- db vm.StateDB
- vm *goja.Runtime
- toBig toBigFn
- toBuf toBufFn
- fromBuf fromBufFn
-}
-
-func (do *dbObj) GetBalance(addrSlice goja.Value) goja.Value {
- a, err := do.fromBuf(do.vm, addrSlice, false)
- if err != nil {
- do.vm.Interrupt(err)
- return nil
- }
- addr := common.BytesToAddress(a)
- value := do.db.GetBalance(addr)
- res, err := do.toBig(do.vm, value.String())
- if err != nil {
- do.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (do *dbObj) GetNonce(addrSlice goja.Value) uint64 {
- a, err := do.fromBuf(do.vm, addrSlice, false)
- if err != nil {
- do.vm.Interrupt(err)
- return 0
- }
- addr := common.BytesToAddress(a)
- return do.db.GetNonce(addr)
-}
-
-func (do *dbObj) GetCode(addrSlice goja.Value) goja.Value {
- a, err := do.fromBuf(do.vm, addrSlice, false)
- if err != nil {
- do.vm.Interrupt(err)
- return nil
- }
- addr := common.BytesToAddress(a)
- code := do.db.GetCode(addr)
- res, err := do.toBuf(do.vm, code)
- if err != nil {
- do.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (do *dbObj) GetState(addrSlice goja.Value, hashSlice goja.Value) goja.Value {
- a, err := do.fromBuf(do.vm, addrSlice, false)
- if err != nil {
- do.vm.Interrupt(err)
- return nil
- }
- addr := common.BytesToAddress(a)
- h, err := do.fromBuf(do.vm, hashSlice, false)
- if err != nil {
- do.vm.Interrupt(err)
- return nil
- }
- hash := common.BytesToHash(h)
- state := do.db.GetState(addr, hash).Bytes()
- res, err := do.toBuf(do.vm, state)
- if err != nil {
- do.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (do *dbObj) Exists(addrSlice goja.Value) bool {
- a, err := do.fromBuf(do.vm, addrSlice, false)
- if err != nil {
- do.vm.Interrupt(err)
- return false
- }
- addr := common.BytesToAddress(a)
- return do.db.Exist(addr)
-}
-
-func (do *dbObj) setupObject() *goja.Object {
- o := do.vm.NewObject()
- o.Set("getBalance", do.vm.ToValue(do.GetBalance))
- o.Set("getNonce", do.vm.ToValue(do.GetNonce))
- o.Set("getCode", do.vm.ToValue(do.GetCode))
- o.Set("getState", do.vm.ToValue(do.GetState))
- o.Set("exists", do.vm.ToValue(do.Exists))
- return o
-}
-
-type contractObj struct {
- contract *vm.Contract
- vm *goja.Runtime
- toBig toBigFn
- toBuf toBufFn
-}
-
-func (co *contractObj) GetCaller() goja.Value {
- caller := co.contract.Caller().Bytes()
- res, err := co.toBuf(co.vm, caller)
- if err != nil {
- co.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (co *contractObj) GetAddress() goja.Value {
- addr := co.contract.Address().Bytes()
- res, err := co.toBuf(co.vm, addr)
- if err != nil {
- co.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (co *contractObj) GetValue() goja.Value {
- value := co.contract.Value()
- res, err := co.toBig(co.vm, value.String())
- if err != nil {
- co.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (co *contractObj) GetInput() goja.Value {
- input := common.CopyBytes(co.contract.Input)
- res, err := co.toBuf(co.vm, input)
- if err != nil {
- co.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (c *contractObj) setupObject() *goja.Object {
- o := c.vm.NewObject()
- o.Set("getCaller", c.vm.ToValue(c.GetCaller))
- o.Set("getAddress", c.vm.ToValue(c.GetAddress))
- o.Set("getValue", c.vm.ToValue(c.GetValue))
- o.Set("getInput", c.vm.ToValue(c.GetInput))
- return o
-}
-
-type callframe struct {
- vm *goja.Runtime
- toBig toBigFn
- toBuf toBufFn
-
- typ string
- from common.Address
- to common.Address
- input []byte
- gas uint
- value *big.Int
-}
-
-func (f *callframe) GetType() string {
- return f.typ
-}
-
-func (f *callframe) GetFrom() goja.Value {
- from := f.from.Bytes()
- res, err := f.toBuf(f.vm, from)
- if err != nil {
- f.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (f *callframe) GetTo() goja.Value {
- to := f.to.Bytes()
- res, err := f.toBuf(f.vm, to)
- if err != nil {
- f.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (f *callframe) GetInput() goja.Value {
- input := f.input
- res, err := f.toBuf(f.vm, input)
- if err != nil {
- f.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (f *callframe) GetGas() uint {
- return f.gas
-}
-
-func (f *callframe) GetValue() goja.Value {
- if f.value == nil {
- return goja.Undefined()
- }
- res, err := f.toBig(f.vm, f.value.String())
- if err != nil {
- f.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (f *callframe) setupObject() *goja.Object {
- o := f.vm.NewObject()
- o.Set("getType", f.vm.ToValue(f.GetType))
- o.Set("getFrom", f.vm.ToValue(f.GetFrom))
- o.Set("getTo", f.vm.ToValue(f.GetTo))
- o.Set("getInput", f.vm.ToValue(f.GetInput))
- o.Set("getGas", f.vm.ToValue(f.GetGas))
- o.Set("getValue", f.vm.ToValue(f.GetValue))
- return o
-}
-
-type callframeResult struct {
- vm *goja.Runtime
- toBuf toBufFn
-
- gasUsed uint
- output []byte
- err error
-}
-
-func (r *callframeResult) GetGasUsed() uint {
- return r.gasUsed
-}
-
-func (r *callframeResult) GetOutput() goja.Value {
- res, err := r.toBuf(r.vm, r.output)
- if err != nil {
- r.vm.Interrupt(err)
- return nil
- }
- return res
-}
-
-func (r *callframeResult) GetError() goja.Value {
- if r.err != nil {
- return r.vm.ToValue(r.err.Error())
- }
- return goja.Undefined()
-}
-
-func (r *callframeResult) setupObject() *goja.Object {
- o := r.vm.NewObject()
- o.Set("getGasUsed", r.vm.ToValue(r.GetGasUsed))
- o.Set("getOutput", r.vm.ToValue(r.GetOutput))
- o.Set("getError", r.vm.ToValue(r.GetError))
- return o
-}
-
-type steplog struct {
- vm *goja.Runtime
-
- op *opObj
- memory *memoryObj
- stack *stackObj
- contract *contractObj
-
- pc uint64
- gas uint64
- cost uint64
- depth int
- refund uint64
- err error
-}
-
-func (l *steplog) GetPC() uint64 { return l.pc }
-func (l *steplog) GetGas() uint64 { return l.gas }
-func (l *steplog) GetCost() uint64 { return l.cost }
-func (l *steplog) GetDepth() int { return l.depth }
-func (l *steplog) GetRefund() uint64 { return l.refund }
-
-func (l *steplog) GetError() goja.Value {
- if l.err != nil {
- return l.vm.ToValue(l.err.Error())
- }
- return goja.Undefined()
-}
-
-func (l *steplog) setupObject() *goja.Object {
- o := l.vm.NewObject()
- // Setup basic fields.
- o.Set("getPC", l.vm.ToValue(l.GetPC))
- o.Set("getGas", l.vm.ToValue(l.GetGas))
- o.Set("getCost", l.vm.ToValue(l.GetCost))
- o.Set("getDepth", l.vm.ToValue(l.GetDepth))
- o.Set("getRefund", l.vm.ToValue(l.GetRefund))
- o.Set("getError", l.vm.ToValue(l.GetError))
- // Setup nested objects.
- o.Set("op", l.op.setupObject())
- o.Set("stack", l.stack.setupObject())
- o.Set("memory", l.memory.setupObject())
- o.Set("contract", l.contract.setupObject())
- return o
-}
diff --git a/eth/tracers/js/internal/tracers/4byte_tracer_legacy.js b/eth/tracers/js/internal/tracers/4byte_tracer_legacy.js
deleted file mode 100644
index e4714b8bfb..0000000000
--- a/eth/tracers/js/internal/tracers/4byte_tracer_legacy.js
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2017 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 .
-
-// 4byteTracer searches for 4byte-identifiers, and collects them for post-processing.
-// It collects the methods identifiers along with the size of the supplied data, so
-// a reversed signature can be matched against the size of the data.
-//
-// Example:
-// > debug.traceTransaction( "0x214e597e35da083692f5386141e69f47e973b2c56e7a8073b1ea08fd7571e9de", {tracer: "4byteTracer"})
-// {
-// 0x27dc297e-128: 1,
-// 0x38cc4831-0: 2,
-// 0x524f3889-96: 1,
-// 0xadf59f99-288: 1,
-// 0xc281d19e-0: 1
-// }
-{
- // ids aggregates the 4byte ids found.
- ids : {},
-
- // callType returns 'false' for non-calls, or the peek-index for the first param
- // after 'value', i.e. meminstart.
- callType: function(opstr){
- switch(opstr){
- case "CALL": case "CALLCODE":
- // gas, addr, val, memin, meminsz, memout, memoutsz
- return 3; // stack ptr to memin
-
- case "DELEGATECALL": case "STATICCALL":
- // gas, addr, memin, meminsz, memout, memoutsz
- return 2; // stack ptr to memin
- }
- return false;
- },
-
- // store save the given identifier and datasize.
- store: function(id, size){
- var key = "" + toHex(id) + "-" + size;
- this.ids[key] = this.ids[key] + 1 || 1;
- },
-
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) {
- // Skip any opcodes that are not internal calls
- var ct = this.callType(log.op.toString());
- if (!ct) {
- return;
- }
- // Skip any pre-compile invocations, those are just fancy opcodes
- if (isPrecompiled(toAddress(log.stack.peek(1).toString(16)))) {
- return;
- }
- // Gather internal call details
- var inSz = log.stack.peek(ct + 1).valueOf();
- if (inSz >= 4) {
- var inOff = log.stack.peek(ct).valueOf();
- this.store(log.memory.slice(inOff, inOff + 4), inSz-4);
- }
- },
-
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) { },
-
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function(ctx) {
- // Save the outer calldata also
- if (ctx.input.length >= 4) {
- this.store(slice(ctx.input, 0, 4), ctx.input.length-4)
- }
- return this.ids;
- },
-}
diff --git a/eth/tracers/js/internal/tracers/bigram_tracer.js b/eth/tracers/js/internal/tracers/bigram_tracer.js
deleted file mode 100644
index 421c360af9..0000000000
--- a/eth/tracers/js/internal/tracers/bigram_tracer.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 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 .
-
-{
- // hist is the counters of opcode bigrams
- hist: {},
- // lastOp is last operation
- lastOp: '',
- // execution depth of last op
- lastDepth: 0,
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) {
- var op = log.op.toString();
- var depth = log.getDepth();
- if (depth == this.lastDepth){
- var key = this.lastOp+'-'+op;
- if (this.hist[key]){
- this.hist[key]++;
- }
- else {
- this.hist[key] = 1;
- }
- }
- this.lastOp = op;
- this.lastDepth = depth;
- },
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) {},
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function(ctx) {
- return this.hist;
- },
-}
diff --git a/eth/tracers/js/internal/tracers/call_tracer_legacy.js b/eth/tracers/js/internal/tracers/call_tracer_legacy.js
deleted file mode 100644
index 451a644b91..0000000000
--- a/eth/tracers/js/internal/tracers/call_tracer_legacy.js
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2017 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 .
-
-// callTracer is a full blown transaction tracer that extracts and reports all
-// the internal calls made by a transaction, along with any useful information.
-{
- // callstack is the current recursive call stack of the EVM execution.
- callstack: [{}],
-
- // descended tracks whether we've just descended from an outer transaction into
- // an inner call.
- descended: false,
-
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) {
- // Capture any errors immediately
- var error = log.getError();
- if (error !== undefined) {
- this.fault(log, db);
- return;
- }
- // We only care about system opcodes, faster if we pre-check once
- var syscall = (log.op.toNumber() & 0xf0) == 0xf0;
- if (syscall) {
- var op = log.op.toString();
- }
- // If a new contract is being created, add to the call stack
- if (syscall && (op == 'CREATE' || op == "CREATE2")) {
- var inOff = log.stack.peek(1).valueOf();
- var inEnd = inOff + log.stack.peek(2).valueOf();
-
- // Assemble the internal call report and store for completion
- var call = {
- type: op,
- from: toHex(log.contract.getAddress()),
- input: toHex(log.memory.slice(inOff, inEnd)),
- gasIn: log.getGas(),
- gasCost: log.getCost(),
- value: '0x' + log.stack.peek(0).toString(16)
- };
- this.callstack.push(call);
- this.descended = true
- return;
- }
- // If a contract is being self destructed, gather that as a subcall too
- if (syscall && op == 'SELFDESTRUCT') {
- var left = this.callstack.length;
- if (this.callstack[left-1].calls === undefined) {
- this.callstack[left-1].calls = [];
- }
- this.callstack[left-1].calls.push({
- type: op,
- from: toHex(log.contract.getAddress()),
- to: toHex(toAddress(log.stack.peek(0).toString(16))),
- gasIn: log.getGas(),
- gasCost: log.getCost(),
- value: '0x' + db.getBalance(log.contract.getAddress()).toString(16)
- });
- return
- }
- // If a new method invocation is being done, add to the call stack
- if (syscall && (op == 'CALL' || op == 'CALLCODE' || op == 'DELEGATECALL' || op == 'STATICCALL')) {
- // Skip any pre-compile invocations, those are just fancy opcodes
- var to = toAddress(log.stack.peek(1).toString(16));
- if (isPrecompiled(to)) {
- return
- }
- var off = (op == 'DELEGATECALL' || op == 'STATICCALL' ? 0 : 1);
-
- var inOff = log.stack.peek(2 + off).valueOf();
- var inEnd = inOff + log.stack.peek(3 + off).valueOf();
-
- // Assemble the internal call report and store for completion
- var call = {
- type: op,
- from: toHex(log.contract.getAddress()),
- to: toHex(to),
- input: toHex(log.memory.slice(inOff, inEnd)),
- gasIn: log.getGas(),
- gasCost: log.getCost(),
- outOff: log.stack.peek(4 + off).valueOf(),
- outLen: log.stack.peek(5 + off).valueOf()
- };
- if (op != 'DELEGATECALL' && op != 'STATICCALL') {
- call.value = '0x' + log.stack.peek(2).toString(16);
- }
- this.callstack.push(call);
- this.descended = true
- return;
- }
- // If we've just descended into an inner call, retrieve it's true allowance. We
- // need to extract if from within the call as there may be funky gas dynamics
- // with regard to requested and actually given gas (2300 stipend, 63/64 rule).
- if (this.descended) {
- if (log.getDepth() >= this.callstack.length) {
- this.callstack[this.callstack.length - 1].gas = log.getGas();
- } else {
- // TODO(karalabe): The call was made to a plain account. We currently don't
- // have access to the true gas amount inside the call and so any amount will
- // mostly be wrong since it depends on a lot of input args. Skip gas for now.
- }
- this.descended = false;
- }
- // If an existing call is returning, pop off the call stack
- if (syscall && op == 'REVERT') {
- this.callstack[this.callstack.length - 1].error = "execution reverted";
- return;
- }
- if (log.getDepth() == this.callstack.length - 1) {
- // Pop off the last call and get the execution results
- var call = this.callstack.pop();
-
- if (call.type == 'CREATE' || call.type == "CREATE2") {
- // If the call was a CREATE, retrieve the contract address and output code
- call.gasUsed = '0x' + bigInt(call.gasIn - call.gasCost - log.getGas()).toString(16);
- delete call.gasIn; delete call.gasCost;
-
- var ret = log.stack.peek(0);
- if (!ret.equals(0)) {
- call.to = toHex(toAddress(ret.toString(16)));
- call.output = toHex(db.getCode(toAddress(ret.toString(16))));
- } else if (call.error === undefined) {
- call.error = "internal failure"; // TODO(karalabe): surface these faults somehow
- }
- } else {
- // If the call was a contract call, retrieve the gas usage and output
- if (call.gas !== undefined) {
- call.gasUsed = '0x' + bigInt(call.gasIn - call.gasCost + call.gas - log.getGas()).toString(16);
- }
- var ret = log.stack.peek(0);
- if (!ret.equals(0)) {
- call.output = toHex(log.memory.slice(call.outOff, call.outOff + call.outLen));
- } else if (call.error === undefined) {
- call.error = "internal failure"; // TODO(karalabe): surface these faults somehow
- }
- delete call.gasIn; delete call.gasCost;
- delete call.outOff; delete call.outLen;
- }
- if (call.gas !== undefined) {
- call.gas = '0x' + bigInt(call.gas).toString(16);
- }
- // Inject the call into the previous one
- var left = this.callstack.length;
- if (this.callstack[left-1].calls === undefined) {
- this.callstack[left-1].calls = [];
- }
- this.callstack[left-1].calls.push(call);
- }
- },
-
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) {
- // If the topmost call already reverted, don't handle the additional fault again
- if (this.callstack[this.callstack.length - 1].error !== undefined) {
- return;
- }
- // Pop off the just failed call
- var call = this.callstack.pop();
- call.error = log.getError();
-
- // Consume all available gas and clean any leftovers
- if (call.gas !== undefined) {
- call.gas = '0x' + bigInt(call.gas).toString(16);
- call.gasUsed = call.gas
- }
- delete call.gasIn; delete call.gasCost;
- delete call.outOff; delete call.outLen;
-
- // Flatten the failed call into its parent
- var left = this.callstack.length;
- if (left > 0) {
- if (this.callstack[left-1].calls === undefined) {
- this.callstack[left-1].calls = [];
- }
- this.callstack[left-1].calls.push(call);
- return;
- }
- // Last call failed too, leave it in the stack
- this.callstack.push(call);
- },
-
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function(ctx, db) {
- var result = {
- type: ctx.type,
- from: toHex(ctx.from),
- to: toHex(ctx.to),
- value: '0x' + ctx.value.toString(16),
- gas: '0x' + bigInt(ctx.gas).toString(16),
- gasUsed: '0x' + bigInt(ctx.gasUsed).toString(16),
- input: toHex(ctx.input),
- output: toHex(ctx.output),
- };
- if (this.callstack[0].calls !== undefined) {
- result.calls = this.callstack[0].calls;
- }
- if (this.callstack[0].error !== undefined) {
- result.error = this.callstack[0].error;
- } else if (ctx.error !== undefined) {
- result.error = ctx.error;
- }
- if (result.error !== undefined && (result.error !== "execution reverted" || result.output ==="0x")) {
- delete result.output;
- }
- return this.finalize(result);
- },
-
- // finalize recreates a call object using the final desired field oder for json
- // serialization. This is a nicety feature to pass meaningfully ordered results
- // to users who don't interpret it, just display it.
- finalize: function(call) {
- var sorted = {
- type: call.type,
- from: call.from,
- to: call.to,
- value: call.value,
- gas: call.gas,
- gasUsed: call.gasUsed,
- input: call.input,
- output: call.output,
- error: call.error,
- calls: call.calls,
- }
- for (var key in sorted) {
- if (sorted[key] === undefined) {
- delete sorted[key];
- }
- }
- if (sorted.calls !== undefined) {
- for (var i=0; i.
-
-// evmdisTracer returns sufficient information from a trace to perform evmdis-style
-// disassembly.
-{
- stack: [{ops: []}],
-
- npushes: {0: 0, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1, 10: 1, 11: 1, 16: 1, 17: 1, 18: 1, 19: 1, 20: 1, 21: 1, 22: 1, 23: 1, 24: 1, 25: 1, 26: 1, 32: 1, 48: 1, 49: 1, 50: 1, 51: 1, 52: 1, 53: 1, 54: 1, 55: 0, 56: 1, 57: 0, 58: 1, 59: 1, 60: 0, 64: 1, 65: 1, 66: 1, 67: 1, 68: 1, 69: 1, 80: 0, 81: 1, 82: 0, 83: 0, 84: 1, 85: 0, 86: 0, 87: 0, 88: 1, 89: 1, 90: 1, 91: 0, 96: 1, 97: 1, 98: 1, 99: 1, 100: 1, 101: 1, 102: 1, 103: 1, 104: 1, 105: 1, 106: 1, 107: 1, 108: 1, 109: 1, 110: 1, 111: 1, 112: 1, 113: 1, 114: 1, 115: 1, 116: 1, 117: 1, 118: 1, 119: 1, 120: 1, 121: 1, 122: 1, 123: 1, 124: 1, 125: 1, 126: 1, 127: 1, 128: 2, 129: 3, 130: 4, 131: 5, 132: 6, 133: 7, 134: 8, 135: 9, 136: 10, 137: 11, 138: 12, 139: 13, 140: 14, 141: 15, 142: 16, 143: 17, 144: 2, 145: 3, 146: 4, 147: 5, 148: 6, 149: 7, 150: 8, 151: 9, 152: 10, 153: 11, 154: 12, 155: 13, 156: 14, 157: 15, 158: 16, 159: 17, 160: 0, 161: 0, 162: 0, 163: 0, 164: 0, 240: 1, 241: 1, 242: 1, 243: 0, 244: 0, 255: 0},
-
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function() { return this.stack[0].ops; },
-
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) { },
-
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) {
- var frame = this.stack[this.stack.length - 1];
-
- var error = log.getError();
- if (error) {
- frame["error"] = error;
- } else if (log.getDepth() == this.stack.length) {
- opinfo = {
- op: log.op.toNumber(),
- depth : log.getDepth(),
- result: [],
- };
- if (frame.ops.length > 0) {
- var prevop = frame.ops[frame.ops.length - 1];
- for(var i = 0; i < this.npushes[prevop.op]; i++)
- prevop.result.push(log.stack.peek(i).toString(16));
- }
- switch(log.op.toString()) {
- case "CALL": case "CALLCODE":
- var instart = log.stack.peek(3).valueOf();
- var insize = log.stack.peek(4).valueOf();
- opinfo["gas"] = log.stack.peek(0).valueOf();
- opinfo["to"] = log.stack.peek(1).toString(16);
- opinfo["value"] = log.stack.peek(2).toString();
- opinfo["input"] = log.memory.slice(instart, instart + insize);
- opinfo["error"] = null;
- opinfo["return"] = null;
- opinfo["ops"] = [];
- this.stack.push(opinfo);
- break;
- case "DELEGATECALL": case "STATICCALL":
- var instart = log.stack.peek(2).valueOf();
- var insize = log.stack.peek(3).valueOf();
- opinfo["op"] = log.op.toString();
- opinfo["gas"] = log.stack.peek(0).valueOf();
- opinfo["to"] = log.stack.peek(1).toString(16);
- opinfo["input"] = log.memory.slice(instart, instart + insize);
- opinfo["error"] = null;
- opinfo["return"] = null;
- opinfo["ops"] = [];
- this.stack.push(opinfo);
- break;
- case "RETURN": case "REVERT":
- var out = log.stack.peek(0).valueOf();
- var outsize = log.stack.peek(1).valueOf();
- frame.return = log.memory.slice(out, out + outsize);
- break;
- case "STOP": case "SELFDESTRUCT":
- frame.return = log.memory.slice(0, 0);
- break;
- case "JUMPDEST":
- opinfo["pc"] = log.getPC();
- }
- if(log.op.isPush()) {
- opinfo["len"] = log.op.toNumber() - 0x5e;
- }
- frame.ops.push(opinfo);
- } else {
- this.stack = this.stack.slice(0, log.getDepth());
- }
- }
-}
diff --git a/eth/tracers/js/internal/tracers/noop_tracer_legacy.js b/eth/tracers/js/internal/tracers/noop_tracer_legacy.js
deleted file mode 100644
index fe7ddc85ab..0000000000
--- a/eth/tracers/js/internal/tracers/noop_tracer_legacy.js
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2017 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 .
-
-// noopTracer is just the barebone boilerplate code required from a JavaScript
-// object to be usable as a transaction tracer.
-{
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) { },
-
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) { },
-
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function(ctx, db) { return {}; }
-}
diff --git a/eth/tracers/js/internal/tracers/opcount_tracer.js b/eth/tracers/js/internal/tracers/opcount_tracer.js
deleted file mode 100644
index f7984c741a..0000000000
--- a/eth/tracers/js/internal/tracers/opcount_tracer.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2017 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 .
-
-// opcountTracer is a sample tracer that just counts the number of instructions
-// executed by the EVM before the transaction terminated.
-{
- // count tracks the number of EVM instructions executed.
- count: 0,
-
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) { this.count++ },
-
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) { },
-
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function(ctx, db) { return this.count }
-}
diff --git a/eth/tracers/js/internal/tracers/prestate_tracer_legacy.js b/eth/tracers/js/internal/tracers/prestate_tracer_legacy.js
deleted file mode 100644
index 2757b8b141..0000000000
--- a/eth/tracers/js/internal/tracers/prestate_tracer_legacy.js
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2017 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 .
-
-// prestateTracer outputs sufficient information to create a local execution of
-// the transaction from a custom assembled genesis block.
-{
- // prestate is the genesis that we're building.
- prestate: null,
-
- // lookupAccount injects the specified account into the prestate object.
- lookupAccount: function(addr, db){
- var acc = toHex(addr);
- if (this.prestate[acc] === undefined) {
- this.prestate[acc] = {
- balance: '0x' + db.getBalance(addr).toString(16),
- nonce: db.getNonce(addr),
- code: toHex(db.getCode(addr)),
- storage: {}
- };
- }
- },
-
- // lookupStorage injects the specified storage entry of the given account into
- // the prestate object.
- lookupStorage: function(addr, key, db){
- var acc = toHex(addr);
- var idx = toHex(key);
-
- if (this.prestate[acc].storage[idx] === undefined) {
- this.prestate[acc].storage[idx] = toHex(db.getState(addr, key));
- }
- },
-
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function(ctx, db) {
- if (this.prestate === null) {
- this.prestate = {};
- // If tx is transfer-only, the recipient account
- // hasn't been populated.
- this.lookupAccount(ctx.to, db);
- }
-
- // At this point, we need to deduct the 'value' from the
- // outer transaction, and move it back to the origin
- this.lookupAccount(ctx.from, db);
-
- var fromBal = bigInt(this.prestate[toHex(ctx.from)].balance.slice(2), 16);
- var toBal = bigInt(this.prestate[toHex(ctx.to)].balance.slice(2), 16);
-
- this.prestate[toHex(ctx.to)].balance = '0x'+toBal.subtract(ctx.value).toString(16);
- this.prestate[toHex(ctx.from)].balance = '0x'+fromBal.add(ctx.value).add(ctx.gasUsed * ctx.gasPrice).toString(16);
-
- // Decrement the caller's nonce, and remove empty create targets
- this.prestate[toHex(ctx.from)].nonce--;
- if (ctx.type == 'CREATE') {
- // We can blibdly delete the contract prestate, as any existing state would
- // have caused the transaction to be rejected as invalid in the first place.
- delete this.prestate[toHex(ctx.to)];
- }
- // Return the assembled allocations (prestate)
- return this.prestate;
- },
-
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) {
- // Add the current account if we just started tracing
- if (this.prestate === null){
- this.prestate = {};
- // Balance will potentially be wrong here, since this will include the value
- // sent along with the message. We fix that in 'result()'.
- this.lookupAccount(log.contract.getAddress(), db);
- }
- // Whenever new state is accessed, add it to the prestate
- switch (log.op.toString()) {
- case "EXTCODECOPY": case "EXTCODESIZE": case "EXTCODEHASH": case "BALANCE":
- this.lookupAccount(toAddress(log.stack.peek(0).toString(16)), db);
- break;
- case "CREATE":
- var from = log.contract.getAddress();
- this.lookupAccount(toContract(from, db.getNonce(from)), db);
- break;
- case "CREATE2":
- var from = log.contract.getAddress();
- // stack: salt, size, offset, endowment
- var offset = log.stack.peek(1).valueOf()
- var size = log.stack.peek(2).valueOf()
- var end = offset + size
- this.lookupAccount(toContract2(from, log.stack.peek(3).toString(16), log.memory.slice(offset, end)), db);
- break;
- case "CALL": case "CALLCODE": case "DELEGATECALL": case "STATICCALL":
- this.lookupAccount(toAddress(log.stack.peek(1).toString(16)), db);
- break;
- case 'SSTORE':case 'SLOAD':
- this.lookupStorage(log.contract.getAddress(), toWord(log.stack.peek(0).toString(16)), db);
- break;
- }
- },
-
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) {}
-}
diff --git a/eth/tracers/js/internal/tracers/tracers.go b/eth/tracers/js/internal/tracers/tracers.go
deleted file mode 100644
index 6547f1b088..0000000000
--- a/eth/tracers/js/internal/tracers/tracers.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2017 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 tracers contains the actual JavaScript tracer assets.
-package tracers
-
-import (
- "embed"
- "io/fs"
- "strings"
- "unicode"
-)
-
-//go:embed *.js
-var files embed.FS
-
-// Load reads the built-in JS tracer files embedded in the binary and
-// returns a mapping of tracer name to source.
-func Load() (map[string]string, error) {
- var assetTracers = make(map[string]string)
- err := fs.WalkDir(files, ".", func(path string, d fs.DirEntry, err error) error {
- if err != nil {
- return err
- }
- if d.IsDir() {
- return nil
- }
- b, err := fs.ReadFile(files, path)
- if err != nil {
- return err
- }
- name := camel(strings.TrimSuffix(path, ".js"))
- assetTracers[name] = string(b)
- return nil
- })
- return assetTracers, err
-}
-
-// camel converts a snake cased input string into a camel cased output.
-func camel(str string) string {
- pieces := strings.Split(str, "_")
- for i := 1; i < len(pieces); i++ {
- pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:]
- }
- return strings.Join(pieces, "")
-}
diff --git a/eth/tracers/js/internal/tracers/trigram_tracer.js b/eth/tracers/js/internal/tracers/trigram_tracer.js
deleted file mode 100644
index 8756490dfc..0000000000
--- a/eth/tracers/js/internal/tracers/trigram_tracer.js
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 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 .
-
-{
- // hist is the map of trigram counters
- hist: {},
- // lastOp is last operation
- lastOps: ['',''],
- lastDepth: 0,
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) {
- var depth = log.getDepth();
- if (depth != this.lastDepth){
- this.lastOps = ['',''];
- this.lastDepth = depth;
- return;
- }
- var op = log.op.toString();
- var key = this.lastOps[0]+'-'+this.lastOps[1]+'-'+op;
- if (this.hist[key]){
- this.hist[key]++;
- }
- else {
- this.hist[key] = 1;
- }
- this.lastOps[0] = this.lastOps[1];
- this.lastOps[1] = op;
- },
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) {},
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function(ctx) {
- return this.hist;
- },
-}
diff --git a/eth/tracers/js/internal/tracers/unigram_tracer.js b/eth/tracers/js/internal/tracers/unigram_tracer.js
deleted file mode 100644
index 51107d8f3d..0000000000
--- a/eth/tracers/js/internal/tracers/unigram_tracer.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 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 .
-
-{
- // hist is the map of opcodes to counters
- hist: {},
- // nops counts number of ops
- nops: 0,
- // step is invoked for every opcode that the VM executes.
- step: function(log, db) {
- var op = log.op.toString();
- if (this.hist[op]){
- this.hist[op]++;
- }
- else {
- this.hist[op] = 1;
- }
- this.nops++;
- },
- // fault is invoked when the actual execution of an opcode fails.
- fault: function(log, db) {},
-
- // result is invoked when all the opcodes have been iterated over and returns
- // the final result of the tracing.
- result: function(ctx) {
- return this.hist;
- },
-}
diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go
deleted file mode 100644
index bf6427faf6..0000000000
--- a/eth/tracers/js/tracer_test.go
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2021 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 js
-
-import (
- "encoding/json"
- "errors"
- "math/big"
- "strings"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/tracers"
- "github.com/ethereum/go-ethereum/params"
-)
-
-type account struct{}
-
-func (account) SubBalance(amount *big.Int) {}
-func (account) AddBalance(amount *big.Int) {}
-func (account) SetAddress(common.Address) {}
-func (account) Value() *big.Int { return nil }
-func (account) SetBalance(*big.Int) {}
-func (account) SetNonce(uint64) {}
-func (account) Balance() *big.Int { return nil }
-func (account) Address() common.Address { return common.Address{} }
-func (account) SetCode(common.Hash, []byte) {}
-func (account) ForEachStorage(cb func(key, value common.Hash) bool) {}
-
-type dummyStatedb struct {
- state.StateDB
-}
-
-func (*dummyStatedb) GetRefund() uint64 { return 1337 }
-func (*dummyStatedb) GetBalance(addr common.Address) *big.Int { return new(big.Int) }
-
-type vmContext struct {
- blockCtx vm.BlockContext
- txCtx vm.TxContext
-}
-
-func testCtx() *vmContext {
- return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}}
-}
-
-func runTrace(tracer tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) {
- var (
- env = vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, chaincfg, vm.Config{Tracer: tracer})
- gasLimit uint64 = 31000
- startGas uint64 = 10000
- value = big.NewInt(0)
- contract = vm.NewContract(account{}, account{}, value, startGas)
- )
- contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0}
- if contractCode != nil {
- contract.Code = contractCode
- }
-
- tracer.CaptureTxStart(gasLimit)
- tracer.CaptureStart(env, contract.Caller(), contract.Address(), false, []byte{}, startGas, value)
- ret, err := env.Interpreter().Run(contract, []byte{}, false)
- tracer.CaptureEnd(ret, startGas-contract.Gas, err)
- // Rest gas assumes no refund
- tracer.CaptureTxEnd(contract.Gas)
- if err != nil {
- return nil, err
- }
- return tracer.GetResult()
-}
-
-func TestTracer(t *testing.T) {
- execTracer := func(code string, contract []byte) ([]byte, string) {
- t.Helper()
- tracer, err := newJsTracer(code, nil, nil)
- if err != nil {
- t.Fatal(err)
- }
- ret, err := runTrace(tracer, testCtx(), params.TestChainConfig, contract)
- if err != nil {
- return nil, err.Error() // Stringify to allow comparison without nil checks
- }
- return ret, ""
- }
- for i, tt := range []struct {
- code string
- want string
- fail string
- contract []byte
- }{
- { // tests that we don't panic on bad arguments to memory access
- code: "{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}",
- want: ``,
- fail: "tracer accessed out of bound memory: offset -1, end -2 at step (:1:53(13)) in server-side tracer function 'step'",
- }, { // tests that we don't panic on bad arguments to stack peeks
- code: "{depths: [], step: function(log) { this.depths.push(log.stack.peek(-1)); }, fault: function() {}, result: function() { return this.depths; }}",
- want: ``,
- fail: "tracer accessed out of bound stack: size 0, index -1 at step (:1:53(11)) in server-side tracer function 'step'",
- }, { // tests that we don't panic on bad arguments to memory getUint
- code: "{ depths: [], step: function(log, db) { this.depths.push(log.memory.getUint(-64));}, fault: function() {}, result: function() { return this.depths; }}",
- want: ``,
- fail: "tracer accessed out of bound memory: available 0, offset -64, size 32 at step (:1:58(11)) in server-side tracer function 'step'",
- }, { // tests some general counting
- code: "{count: 0, step: function() { this.count += 1; }, fault: function() {}, result: function() { return this.count; }}",
- want: `3`,
- }, { // tests that depth is reported correctly
- code: "{depths: [], step: function(log) { this.depths.push(log.stack.length()); }, fault: function() {}, result: function() { return this.depths; }}",
- want: `[0,1,2]`,
- }, { // tests memory length
- code: "{lengths: [], step: function(log) { this.lengths.push(log.memory.length()); }, fault: function() {}, result: function() { return this.lengths; }}",
- want: `[0,0,0]`,
- }, { // tests to-string of opcodes
- code: "{opcodes: [], step: function(log) { this.opcodes.push(log.op.toString()); }, fault: function() {}, result: function() { return this.opcodes; }}",
- want: `["PUSH1","PUSH1","STOP"]`,
- }, { // tests gasUsed
- code: "{depths: [], step: function() {}, fault: function() {}, result: function(ctx) { return ctx.gasPrice+'.'+ctx.gasUsed; }}",
- want: `"100000.21006"`,
- }, {
- code: "{res: null, step: function(log) {}, fault: function() {}, result: function() { return toWord('0xffaa') }}",
- want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":255,"31":170}`,
- }, { // test feeding a buffer back into go
- code: "{res: null, step: function(log) { var address = log.contract.getAddress(); this.res = toAddress(address); }, fault: function() {}, result: function() { return this.res }}",
- want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0}`,
- }, {
- code: "{res: null, step: function(log) { var address = '0x0000000000000000000000000000000000000000'; this.res = toAddress(address); }, fault: function() {}, result: function() { return this.res }}",
- want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0}`,
- }, {
- code: "{res: null, step: function(log) { var address = Array.prototype.slice.call(log.contract.getAddress()); this.res = toAddress(address); }, fault: function() {}, result: function() { return this.res }}",
- want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0}`,
- }, {
- code: "{res: [], step: function(log) { var op = log.op.toString(); if (op === 'MSTORE8' || op === 'STOP') { this.res.push(log.memory.slice(0, 2)) } }, fault: function() {}, result: function() { return this.res }}",
- want: `[{"0":0,"1":0},{"0":255,"1":0}]`,
- contract: []byte{byte(vm.PUSH1), byte(0xff), byte(vm.PUSH1), byte(0x00), byte(vm.MSTORE8), byte(vm.STOP)},
- }, {
- code: "{res: [], step: function(log) { if (log.op.toString() === 'STOP') { this.res.push(log.memory.slice(5, 1025 * 1024)) } }, fault: function() {}, result: function() { return this.res }}",
- want: "",
- fail: "reached limit for padding memory slice: 1049568 at step (:1:83(20)) in server-side tracer function 'step'",
- contract: []byte{byte(vm.PUSH1), byte(0xff), byte(vm.PUSH1), byte(0x00), byte(vm.MSTORE8), byte(vm.STOP)},
- },
- } {
- if have, err := execTracer(tt.code, tt.contract); tt.want != string(have) || tt.fail != err {
- t.Errorf("testcase %d: expected return value to be \n'%s'\n\tgot\n'%s'\nerror to be\n'%s'\n\tgot\n'%s'\n\tcode: %v", i, tt.want, string(have), tt.fail, err, tt.code)
- }
- }
-}
-
-func TestHalt(t *testing.T) {
- timeout := errors.New("stahp")
- tracer, err := newJsTracer("{step: function() { while(1); }, result: function() { return null; }, fault: function(){}}", nil, nil)
- if err != nil {
- t.Fatal(err)
- }
- go func() {
- time.Sleep(1 * time.Second)
- tracer.Stop(timeout)
- }()
- if _, err = runTrace(tracer, testCtx(), params.TestChainConfig, nil); !strings.Contains(err.Error(), "stahp") {
- t.Errorf("Expected timeout error, got %v", err)
- }
-}
-
-func TestHaltBetweenSteps(t *testing.T) {
- tracer, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }}", nil, nil)
- if err != nil {
- t.Fatal(err)
- }
- env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer})
- scope := &vm.ScopeContext{
- Contract: vm.NewContract(&account{}, &account{}, big.NewInt(0), 0),
- }
- tracer.CaptureStart(env, common.Address{}, common.Address{}, false, []byte{}, 0, big.NewInt(0))
- tracer.CaptureState(0, 0, 0, 0, scope, nil, 0, nil)
- timeout := errors.New("stahp")
- tracer.Stop(timeout)
- tracer.CaptureState(0, 0, 0, 0, scope, nil, 0, nil)
-
- if _, err := tracer.GetResult(); !strings.Contains(err.Error(), timeout.Error()) {
- t.Errorf("Expected timeout error, got %v", err)
- }
-}
-
-// testNoStepExec tests a regular value transfer (no exec), and accessing the statedb
-// in 'result'
-func TestNoStepExec(t *testing.T) {
- execTracer := func(code string) []byte {
- t.Helper()
- tracer, err := newJsTracer(code, nil, nil)
- if err != nil {
- t.Fatal(err)
- }
- env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer})
- tracer.CaptureStart(env, common.Address{}, common.Address{}, false, []byte{}, 1000, big.NewInt(0))
- tracer.CaptureEnd(nil, 0, nil)
- ret, err := tracer.GetResult()
- if err != nil {
- t.Fatal(err)
- }
- return ret
- }
- for i, tt := range []struct {
- code string
- want string
- }{
- { // tests that we don't panic on accessing the db methods
- code: "{depths: [], step: function() {}, fault: function() {}, result: function(ctx, db){ return db.getBalance(ctx.to)} }",
- want: `"0"`,
- },
- } {
- if have := execTracer(tt.code); tt.want != string(have) {
- t.Errorf("testcase %d: expected return value to be %s got %s\n\tcode: %v", i, tt.want, string(have), tt.code)
- }
- }
-}
-
-func TestIsPrecompile(t *testing.T) {
- chaincfg := ¶ms.ChainConfig{ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), DAOForkBlock: nil, DAOForkSupport: false, EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(100), ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(200), MuirGlacierBlock: big.NewInt(0), BerlinBlock: big.NewInt(300), LondonBlock: big.NewInt(0), TerminalTotalDifficulty: nil, Ethash: new(params.EthashConfig), Clique: nil}
- chaincfg.ByzantiumBlock = big.NewInt(100)
- chaincfg.IstanbulBlock = big.NewInt(200)
- chaincfg.BerlinBlock = big.NewInt(300)
- txCtx := vm.TxContext{GasPrice: big.NewInt(100000)}
- tracer, err := newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil)
- if err != nil {
- t.Fatal(err)
- }
-
- blockCtx := vm.BlockContext{BlockNumber: big.NewInt(150)}
- res, err := runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg, nil)
- if err != nil {
- t.Error(err)
- }
- if string(res) != "false" {
- t.Errorf("tracer should not consider blake2f as precompile in byzantium")
- }
-
- tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil)
- blockCtx = vm.BlockContext{BlockNumber: big.NewInt(250)}
- res, err = runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg, nil)
- if err != nil {
- t.Error(err)
- }
- if string(res) != "true" {
- t.Errorf("tracer should consider blake2f as precompile in istanbul")
- }
-}
-
-func TestEnterExit(t *testing.T) {
- // test that either both or none of enter() and exit() are defined
- if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}", new(tracers.Context), nil); err == nil {
- t.Fatal("tracer creation should've failed without exit() definition")
- }
- if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}", new(tracers.Context), nil); err != nil {
- t.Fatal(err)
- }
- // test that the enter and exit method are correctly invoked and the values passed
- tracer, err := newJsTracer("{enters: 0, exits: 0, enterGas: 0, gasUsed: 0, step: function() {}, fault: function() {}, result: function() { return {enters: this.enters, exits: this.exits, enterGas: this.enterGas, gasUsed: this.gasUsed} }, enter: function(frame) { this.enters++; this.enterGas = frame.getGas(); }, exit: function(res) { this.exits++; this.gasUsed = res.getGasUsed(); }}", new(tracers.Context), nil)
- if err != nil {
- t.Fatal(err)
- }
- scope := &vm.ScopeContext{
- Contract: vm.NewContract(&account{}, &account{}, big.NewInt(0), 0),
- }
- tracer.CaptureEnter(vm.CALL, scope.Contract.Caller(), scope.Contract.Address(), []byte{}, 1000, new(big.Int))
- tracer.CaptureExit([]byte{}, 400, nil)
-
- have, err := tracer.GetResult()
- if err != nil {
- t.Fatal(err)
- }
- want := `{"enters":1,"exits":1,"enterGas":1000,"gasUsed":400}`
- if string(have) != want {
- t.Errorf("Number of invocations of enter() and exit() is wrong. Have %s, want %s\n", have, want)
- }
-}
-
-func TestSetup(t *testing.T) {
- // Test empty config
- _, err := newJsTracer(`{setup: function(cfg) { if (cfg !== "{}") { throw("invalid empty config") } }, fault: function() {}, result: function() {}}`, new(tracers.Context), nil)
- if err != nil {
- t.Error(err)
- }
-
- cfg, err := json.Marshal(map[string]string{"foo": "bar"})
- if err != nil {
- t.Fatal(err)
- }
- // Test no setup func
- _, err = newJsTracer(`{fault: function() {}, result: function() {}}`, new(tracers.Context), cfg)
- if err != nil {
- t.Fatal(err)
- }
- // Test config value
- tracer, err := newJsTracer("{config: null, setup: function(cfg) { this.config = JSON.parse(cfg) }, step: function() {}, fault: function() {}, result: function() { return this.config.foo }}", new(tracers.Context), cfg)
- if err != nil {
- t.Fatal(err)
- }
- have, err := tracer.GetResult()
- if err != nil {
- t.Fatal(err)
- }
- if string(have) != `"bar"` {
- t.Errorf("tracer returned wrong result. have: %s, want: \"bar\"\n", string(have))
- }
-}
diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go
deleted file mode 100644
index 766ee4e4b9..0000000000
--- a/eth/tracers/logger/access_list_tracer.go
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2021 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 logger
-
-import (
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
-)
-
-// accessList is an accumulator for the set of accounts and storage slots an EVM
-// contract execution touches.
-type accessList map[common.Address]accessListSlots
-
-// accessListSlots is an accumulator for the set of storage slots within a single
-// contract that an EVM contract execution touches.
-type accessListSlots map[common.Hash]struct{}
-
-// newAccessList creates a new accessList.
-func newAccessList() accessList {
- return make(map[common.Address]accessListSlots)
-}
-
-// addAddress adds an address to the accesslist.
-func (al accessList) addAddress(address common.Address) {
- // Set address if not previously present
- if _, present := al[address]; !present {
- al[address] = make(map[common.Hash]struct{})
- }
-}
-
-// addSlot adds a storage slot to the accesslist.
-func (al accessList) addSlot(address common.Address, slot common.Hash) {
- // Set address if not previously present
- al.addAddress(address)
-
- // Set the slot on the surely existent storage set
- al[address][slot] = struct{}{}
-}
-
-// equal checks if the content of the current access list is the same as the
-// content of the other one.
-func (al accessList) equal(other accessList) bool {
- // Cross reference the accounts first
- if len(al) != len(other) {
- return false
- }
- // Given that len(al) == len(other), we only need to check that
- // all the items from al are in other.
- for addr := range al {
- if _, ok := other[addr]; !ok {
- return false
- }
- }
-
- // Accounts match, cross reference the storage slots too
- for addr, slots := range al {
- otherslots := other[addr]
-
- if len(slots) != len(otherslots) {
- return false
- }
- // Given that len(slots) == len(otherslots), we only need to check that
- // all the items from slots are in otherslots.
- for hash := range slots {
- if _, ok := otherslots[hash]; !ok {
- return false
- }
- }
- }
- return true
-}
-
-// accesslist converts the accesslist to a types.AccessList.
-func (al accessList) accessList() types.AccessList {
- acl := make(types.AccessList, 0, len(al))
- for addr, slots := range al {
- tuple := types.AccessTuple{Address: addr, StorageKeys: []common.Hash{}}
- for slot := range slots {
- tuple.StorageKeys = append(tuple.StorageKeys, slot)
- }
- acl = append(acl, tuple)
- }
- return acl
-}
-
-// AccessListTracer is a tracer that accumulates touched accounts and storage
-// slots into an internal set.
-type AccessListTracer struct {
- excl map[common.Address]struct{} // Set of account to exclude from the list
- list accessList // Set of accounts and storage slots touched
-}
-
-// NewAccessListTracer creates a new tracer that can generate AccessLists.
-// An optional AccessList can be specified to occupy slots and addresses in
-// the resulting accesslist.
-func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompiles []common.Address) *AccessListTracer {
- excl := map[common.Address]struct{}{
- from: {}, to: {},
- }
- for _, addr := range precompiles {
- excl[addr] = struct{}{}
- }
- list := newAccessList()
- for _, al := range acl {
- if _, ok := excl[al.Address]; !ok {
- list.addAddress(al.Address)
- }
- for _, slot := range al.StorageKeys {
- list.addSlot(al.Address, slot)
- }
- }
- return &AccessListTracer{
- excl: excl,
- list: list,
- }
-}
-
-func (a *AccessListTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
-}
-
-// CaptureState captures all opcodes that touch storage or addresses and adds them to the accesslist.
-func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- stack := scope.Stack
- stackData := stack.Data()
- stackLen := len(stackData)
- if (op == vm.SLOAD || op == vm.SSTORE) && stackLen >= 1 {
- slot := common.Hash(stackData[stackLen-1].Bytes32())
- a.list.addSlot(scope.Contract.Address(), slot)
- }
- if (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT) && stackLen >= 1 {
- addr := common.Address(stackData[stackLen-1].Bytes20())
- if _, ok := a.excl[addr]; !ok {
- a.list.addAddress(addr)
- }
- }
- if (op == vm.DELEGATECALL || op == vm.CALL || op == vm.STATICCALL || op == vm.CALLCODE) && stackLen >= 5 {
- addr := common.Address(stackData[stackLen-2].Bytes20())
- if _, ok := a.excl[addr]; !ok {
- a.list.addAddress(addr)
- }
- }
-}
-
-func (*AccessListTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
-}
-
-func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {}
-
-func (*AccessListTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
-}
-
-func (*AccessListTracer) CaptureExit(output []byte, gasUsed uint64, err error) {}
-
-func (*AccessListTracer) CaptureTxStart(gasLimit uint64) {}
-
-func (*AccessListTracer) CaptureTxEnd(restGas uint64) {}
-
-// AccessList returns the current accesslist maintained by the tracer.
-func (a *AccessListTracer) AccessList() types.AccessList {
- return a.list.accessList()
-}
-
-// Equal returns if the content of two access list traces are equal.
-func (a *AccessListTracer) Equal(other *AccessListTracer) bool {
- return a.list.equal(other.list)
-}
diff --git a/eth/tracers/logger/gen_structlog.go b/eth/tracers/logger/gen_structlog.go
deleted file mode 100644
index b406cb3445..0000000000
--- a/eth/tracers/logger/gen_structlog.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package logger
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/holiman/uint256"
-)
-
-var _ = (*structLogMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (s StructLog) MarshalJSON() ([]byte, error) {
- type StructLog struct {
- Pc uint64 `json:"pc"`
- Op vm.OpCode `json:"op"`
- Gas math.HexOrDecimal64 `json:"gas"`
- GasCost math.HexOrDecimal64 `json:"gasCost"`
- Memory hexutil.Bytes `json:"memory,omitempty"`
- MemorySize int `json:"memSize"`
- Stack []hexutil.U256 `json:"stack"`
- ReturnData hexutil.Bytes `json:"returnData,omitempty"`
- Storage map[common.Hash]common.Hash `json:"-"`
- Depth int `json:"depth"`
- RefundCounter uint64 `json:"refund"`
- Err error `json:"-"`
- OpName string `json:"opName"`
- ErrorString string `json:"error,omitempty"`
- }
- var enc StructLog
- enc.Pc = s.Pc
- enc.Op = s.Op
- enc.Gas = math.HexOrDecimal64(s.Gas)
- enc.GasCost = math.HexOrDecimal64(s.GasCost)
- enc.Memory = s.Memory
- enc.MemorySize = s.MemorySize
- if s.Stack != nil {
- enc.Stack = make([]hexutil.U256, len(s.Stack))
- for k, v := range s.Stack {
- enc.Stack[k] = hexutil.U256(v)
- }
- }
- enc.ReturnData = s.ReturnData
- enc.Storage = s.Storage
- enc.Depth = s.Depth
- enc.RefundCounter = s.RefundCounter
- enc.Err = s.Err
- enc.OpName = s.OpName()
- enc.ErrorString = s.ErrorString()
- return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (s *StructLog) UnmarshalJSON(input []byte) error {
- type StructLog struct {
- Pc *uint64 `json:"pc"`
- Op *vm.OpCode `json:"op"`
- Gas *math.HexOrDecimal64 `json:"gas"`
- GasCost *math.HexOrDecimal64 `json:"gasCost"`
- Memory *hexutil.Bytes `json:"memory,omitempty"`
- MemorySize *int `json:"memSize"`
- Stack []hexutil.U256 `json:"stack"`
- ReturnData *hexutil.Bytes `json:"returnData,omitempty"`
- Storage map[common.Hash]common.Hash `json:"-"`
- Depth *int `json:"depth"`
- RefundCounter *uint64 `json:"refund"`
- Err error `json:"-"`
- }
- var dec StructLog
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Pc != nil {
- s.Pc = *dec.Pc
- }
- if dec.Op != nil {
- s.Op = *dec.Op
- }
- if dec.Gas != nil {
- s.Gas = uint64(*dec.Gas)
- }
- if dec.GasCost != nil {
- s.GasCost = uint64(*dec.GasCost)
- }
- if dec.Memory != nil {
- s.Memory = *dec.Memory
- }
- if dec.MemorySize != nil {
- s.MemorySize = *dec.MemorySize
- }
- if dec.Stack != nil {
- s.Stack = make([]uint256.Int, len(dec.Stack))
- for k, v := range dec.Stack {
- s.Stack[k] = uint256.Int(v)
- }
- }
- if dec.ReturnData != nil {
- s.ReturnData = *dec.ReturnData
- }
- if dec.Storage != nil {
- s.Storage = dec.Storage
- }
- if dec.Depth != nil {
- s.Depth = *dec.Depth
- }
- if dec.RefundCounter != nil {
- s.RefundCounter = *dec.RefundCounter
- }
- if dec.Err != nil {
- s.Err = dec.Err
- }
- return nil
-}
diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go
deleted file mode 100644
index 2b36f9f492..0000000000
--- a/eth/tracers/logger/logger.go
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright 2021 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 logger
-
-import (
- "encoding/hex"
- "encoding/json"
- "fmt"
- "io"
- "math/big"
- "strings"
- "sync/atomic"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/params"
- "github.com/holiman/uint256"
-)
-
-// Storage represents a contract's storage.
-type Storage map[common.Hash]common.Hash
-
-// Copy duplicates the current storage.
-func (s Storage) Copy() Storage {
- cpy := make(Storage, len(s))
- for key, value := range s {
- cpy[key] = value
- }
- return cpy
-}
-
-// Config are the configuration options for structured logger the EVM
-type Config struct {
- EnableMemory bool // enable memory capture
- DisableStack bool // disable stack capture
- DisableStorage bool // disable storage capture
- EnableReturnData bool // enable return data capture
- Debug bool // print output during capture end
- Limit int // maximum length of output, but zero means unlimited
- // Chain overrides, can be used to execute a trace using future fork rules
- Overrides *params.ChainConfig `json:"overrides,omitempty"`
-}
-
-//go:generate go run github.com/fjl/gencodec -type StructLog -field-override structLogMarshaling -out gen_structlog.go
-
-// StructLog is emitted to the EVM each cycle and lists information about the current internal state
-// prior to the execution of the statement.
-type StructLog struct {
- Pc uint64 `json:"pc"`
- Op vm.OpCode `json:"op"`
- Gas uint64 `json:"gas"`
- GasCost uint64 `json:"gasCost"`
- Memory []byte `json:"memory,omitempty"`
- MemorySize int `json:"memSize"`
- Stack []uint256.Int `json:"stack"`
- ReturnData []byte `json:"returnData,omitempty"`
- Storage map[common.Hash]common.Hash `json:"-"`
- Depth int `json:"depth"`
- RefundCounter uint64 `json:"refund"`
- Err error `json:"-"`
-}
-
-// overrides for gencodec
-type structLogMarshaling struct {
- Gas math.HexOrDecimal64
- GasCost math.HexOrDecimal64
- Memory hexutil.Bytes
- ReturnData hexutil.Bytes
- Stack []hexutil.U256
- OpName string `json:"opName"` // adds call to OpName() in MarshalJSON
- ErrorString string `json:"error,omitempty"` // adds call to ErrorString() in MarshalJSON
-}
-
-// OpName formats the operand name in a human-readable format.
-func (s *StructLog) OpName() string {
- return s.Op.String()
-}
-
-// ErrorString formats the log's error as a string.
-func (s *StructLog) ErrorString() string {
- if s.Err != nil {
- return s.Err.Error()
- }
- return ""
-}
-
-// StructLogger is an EVM state logger and implements EVMLogger.
-//
-// StructLogger can capture state based on the given Log configuration and also keeps
-// a track record of modified storage which is used in reporting snapshots of the
-// contract their storage.
-type StructLogger struct {
- cfg Config
- env *vm.EVM
-
- storage map[common.Address]Storage
- logs []StructLog
- output []byte
- err error
- gasLimit uint64
- usedGas uint64
-
- interrupt atomic.Bool // Atomic flag to signal execution interruption
- reason error // Textual reason for the interruption
-}
-
-// NewStructLogger returns a new logger
-func NewStructLogger(cfg *Config) *StructLogger {
- logger := &StructLogger{
- storage: make(map[common.Address]Storage),
- }
- if cfg != nil {
- logger.cfg = *cfg
- }
- return logger
-}
-
-// Reset clears the data held by the logger.
-func (l *StructLogger) Reset() {
- l.storage = make(map[common.Address]Storage)
- l.output = make([]byte, 0)
- l.logs = l.logs[:0]
- l.err = nil
-}
-
-// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
-func (l *StructLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- l.env = env
-}
-
-// CaptureState logs a new structured log message and pushes it out to the environment
-//
-// CaptureState also tracks SLOAD/SSTORE ops to track storage change.
-func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- // If tracing was interrupted, set the error and stop
- if l.interrupt.Load() {
- return
- }
- // check if already accumulated the specified number of logs
- if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) {
- return
- }
-
- memory := scope.Memory
- stack := scope.Stack
- contract := scope.Contract
- // Copy a snapshot of the current memory state to a new buffer
- var mem []byte
- if l.cfg.EnableMemory {
- mem = make([]byte, len(memory.Data()))
- copy(mem, memory.Data())
- }
- // Copy a snapshot of the current stack state to a new buffer
- var stck []uint256.Int
- if !l.cfg.DisableStack {
- stck = make([]uint256.Int, len(stack.Data()))
- for i, item := range stack.Data() {
- stck[i] = item
- }
- }
- stackData := stack.Data()
- stackLen := len(stackData)
- // Copy a snapshot of the current storage to a new container
- var storage Storage
- if !l.cfg.DisableStorage && (op == vm.SLOAD || op == vm.SSTORE) {
- // initialise new changed values storage container for this contract
- // if not present.
- if l.storage[contract.Address()] == nil {
- l.storage[contract.Address()] = make(Storage)
- }
- // capture SLOAD opcodes and record the read entry in the local storage
- if op == vm.SLOAD && stackLen >= 1 {
- var (
- address = common.Hash(stackData[stackLen-1].Bytes32())
- value = l.env.StateDB.GetState(contract.Address(), address)
- )
- l.storage[contract.Address()][address] = value
- storage = l.storage[contract.Address()].Copy()
- } else if op == vm.SSTORE && stackLen >= 2 {
- // capture SSTORE opcodes and record the written entry in the local storage.
- var (
- value = common.Hash(stackData[stackLen-2].Bytes32())
- address = common.Hash(stackData[stackLen-1].Bytes32())
- )
- l.storage[contract.Address()][address] = value
- storage = l.storage[contract.Address()].Copy()
- }
- }
- var rdata []byte
- if l.cfg.EnableReturnData {
- rdata = make([]byte, len(rData))
- copy(rdata, rData)
- }
- // create a new snapshot of the EVM.
- log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err}
- l.logs = append(l.logs, log)
-}
-
-// CaptureFault implements the EVMLogger interface to trace an execution fault
-// while running an opcode.
-func (l *StructLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
-}
-
-// CaptureEnd is called after the call finishes to finalize the tracing.
-func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, err error) {
- l.output = output
- l.err = err
- if l.cfg.Debug {
- fmt.Printf("%#x\n", output)
- if err != nil {
- fmt.Printf(" error: %v\n", err)
- }
- }
-}
-
-func (l *StructLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
-}
-
-func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) {
-}
-
-func (l *StructLogger) GetResult() (json.RawMessage, error) {
- // Tracing aborted
- if l.reason != nil {
- return nil, l.reason
- }
- failed := l.err != nil
- returnData := common.CopyBytes(l.output)
- // Return data when successful and revert reason when reverted, otherwise empty.
- returnVal := fmt.Sprintf("%x", returnData)
- if failed && l.err != vm.ErrExecutionReverted {
- returnVal = ""
- }
- return json.Marshal(&ExecutionResult{
- Gas: l.usedGas,
- Failed: failed,
- ReturnValue: returnVal,
- StructLogs: formatLogs(l.StructLogs()),
- })
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (l *StructLogger) Stop(err error) {
- l.reason = err
- l.interrupt.Store(true)
-}
-
-func (l *StructLogger) CaptureTxStart(gasLimit uint64) {
- l.gasLimit = gasLimit
-}
-
-func (l *StructLogger) CaptureTxEnd(restGas uint64) {
- l.usedGas = l.gasLimit - restGas
-}
-
-// StructLogs returns the captured log entries.
-func (l *StructLogger) StructLogs() []StructLog { return l.logs }
-
-// Error returns the VM error captured by the trace.
-func (l *StructLogger) Error() error { return l.err }
-
-// Output returns the VM return value captured by the trace.
-func (l *StructLogger) Output() []byte { return l.output }
-
-// WriteTrace writes a formatted trace to the given writer
-func WriteTrace(writer io.Writer, logs []StructLog) {
- for _, log := range logs {
- fmt.Fprintf(writer, "%-16spc=%08d gas=%v cost=%v", log.Op, log.Pc, log.Gas, log.GasCost)
- if log.Err != nil {
- fmt.Fprintf(writer, " ERROR: %v", log.Err)
- }
- fmt.Fprintln(writer)
-
- if len(log.Stack) > 0 {
- fmt.Fprintln(writer, "Stack:")
- for i := len(log.Stack) - 1; i >= 0; i-- {
- fmt.Fprintf(writer, "%08d %s\n", len(log.Stack)-i-1, log.Stack[i].Hex())
- }
- }
- if len(log.Memory) > 0 {
- fmt.Fprintln(writer, "Memory:")
- fmt.Fprint(writer, hex.Dump(log.Memory))
- }
- if len(log.Storage) > 0 {
- fmt.Fprintln(writer, "Storage:")
- for h, item := range log.Storage {
- fmt.Fprintf(writer, "%x: %x\n", h, item)
- }
- }
- if len(log.ReturnData) > 0 {
- fmt.Fprintln(writer, "ReturnData:")
- fmt.Fprint(writer, hex.Dump(log.ReturnData))
- }
- fmt.Fprintln(writer)
- }
-}
-
-// WriteLogs writes vm logs in a readable format to the given writer
-func WriteLogs(writer io.Writer, logs []*types.Log) {
- for _, log := range logs {
- fmt.Fprintf(writer, "LOG%d: %x bn=%d txi=%x\n", len(log.Topics), log.Address, log.BlockNumber, log.TxIndex)
-
- for i, topic := range log.Topics {
- fmt.Fprintf(writer, "%08d %x\n", i, topic)
- }
-
- fmt.Fprint(writer, hex.Dump(log.Data))
- fmt.Fprintln(writer)
- }
-}
-
-type mdLogger struct {
- out io.Writer
- cfg *Config
- env *vm.EVM
-}
-
-// NewMarkdownLogger creates a logger which outputs information in a format adapted
-// for human readability, and is also a valid markdown table
-func NewMarkdownLogger(cfg *Config, writer io.Writer) *mdLogger {
- l := &mdLogger{out: writer, cfg: cfg}
- if l.cfg == nil {
- l.cfg = &Config{}
- }
- return l
-}
-
-func (t *mdLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- t.env = env
- if !create {
- fmt.Fprintf(t.out, "From: `%v`\nTo: `%v`\nData: `%#x`\nGas: `%d`\nValue `%v` wei\n",
- from.String(), to.String(),
- input, gas, value)
- } else {
- fmt.Fprintf(t.out, "From: `%v`\nCreate at: `%v`\nData: `%#x`\nGas: `%d`\nValue `%v` wei\n",
- from.String(), to.String(),
- input, gas, value)
- }
-
- fmt.Fprintf(t.out, `
-| Pc | Op | Cost | Stack | RStack | Refund |
-|-------|-------------|------|-----------|-----------|---------|
-`)
-}
-
-// CaptureState also tracks SLOAD/SSTORE ops to track storage change.
-func (t *mdLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- stack := scope.Stack
- fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost)
-
- if !t.cfg.DisableStack {
- // format stack
- var a []string
- for _, elem := range stack.Data() {
- a = append(a, elem.Hex())
- }
- b := fmt.Sprintf("[%v]", strings.Join(a, ","))
- fmt.Fprintf(t.out, "%10v |", b)
- }
- fmt.Fprintf(t.out, "%10v |", t.env.StateDB.GetRefund())
- fmt.Fprintln(t.out, "")
- if err != nil {
- fmt.Fprintf(t.out, "Error: %v\n", err)
- }
-}
-
-func (t *mdLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
- fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err)
-}
-
-func (t *mdLogger) CaptureEnd(output []byte, gasUsed uint64, err error) {
- fmt.Fprintf(t.out, "\nOutput: `%#x`\nConsumed gas: `%d`\nError: `%v`\n",
- output, gasUsed, err)
-}
-
-func (t *mdLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
-}
-
-func (t *mdLogger) CaptureExit(output []byte, gasUsed uint64, err error) {}
-
-func (*mdLogger) CaptureTxStart(gasLimit uint64) {}
-
-func (*mdLogger) CaptureTxEnd(restGas uint64) {}
-
-// ExecutionResult groups all structured logs emitted by the EVM
-// while replaying a transaction in debug mode as well as transaction
-// execution status, the amount of gas used and the return value
-type ExecutionResult struct {
- Gas uint64 `json:"gas"`
- Failed bool `json:"failed"`
- ReturnValue string `json:"returnValue"`
- StructLogs []StructLogRes `json:"structLogs"`
-}
-
-// StructLogRes stores a structured log emitted by the EVM while replaying a
-// transaction in debug mode
-type StructLogRes struct {
- Pc uint64 `json:"pc"`
- Op string `json:"op"`
- Gas uint64 `json:"gas"`
- GasCost uint64 `json:"gasCost"`
- Depth int `json:"depth"`
- Error string `json:"error,omitempty"`
- Stack *[]string `json:"stack,omitempty"`
- ReturnData string `json:"returnData,omitempty"`
- Memory *[]string `json:"memory,omitempty"`
- Storage *map[string]string `json:"storage,omitempty"`
- RefundCounter uint64 `json:"refund,omitempty"`
-}
-
-// formatLogs formats EVM returned structured logs for json output
-func formatLogs(logs []StructLog) []StructLogRes {
- formatted := make([]StructLogRes, len(logs))
- for index, trace := range logs {
- formatted[index] = StructLogRes{
- Pc: trace.Pc,
- Op: trace.Op.String(),
- Gas: trace.Gas,
- GasCost: trace.GasCost,
- Depth: trace.Depth,
- Error: trace.ErrorString(),
- RefundCounter: trace.RefundCounter,
- }
- if trace.Stack != nil {
- stack := make([]string, len(trace.Stack))
- for i, stackValue := range trace.Stack {
- stack[i] = stackValue.Hex()
- }
- formatted[index].Stack = &stack
- }
- if trace.ReturnData != nil && len(trace.ReturnData) > 0 {
- formatted[index].ReturnData = hexutil.Bytes(trace.ReturnData).String()
- }
- if trace.Memory != nil {
- memory := make([]string, 0, (len(trace.Memory)+31)/32)
- for i := 0; i+32 <= len(trace.Memory); i += 32 {
- memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32]))
- }
- formatted[index].Memory = &memory
- }
- if trace.Storage != nil {
- storage := make(map[string]string)
- for i, storageValue := range trace.Storage {
- storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue)
- }
- formatted[index].Storage = &storage
- }
- }
- return formatted
-}
diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go
deleted file mode 100644
index a2cb4cd9fc..0000000000
--- a/eth/tracers/logger/logger_json.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2021 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 logger
-
-import (
- "encoding/json"
- "io"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/vm"
-)
-
-type JSONLogger struct {
- encoder *json.Encoder
- cfg *Config
- env *vm.EVM
-}
-
-// NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects
-// into the provided stream.
-func NewJSONLogger(cfg *Config, writer io.Writer) *JSONLogger {
- l := &JSONLogger{encoder: json.NewEncoder(writer), cfg: cfg}
- if l.cfg == nil {
- l.cfg = &Config{}
- }
- return l
-}
-
-func (l *JSONLogger) CaptureStart(env *vm.EVM, from, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- l.env = env
-}
-
-func (l *JSONLogger) CaptureFault(pc uint64, op vm.OpCode, gas uint64, cost uint64, scope *vm.ScopeContext, depth int, err error) {
- // TODO: Add rData to this interface as well
- l.CaptureState(pc, op, gas, cost, scope, nil, depth, err)
-}
-
-// CaptureState outputs state information on the logger.
-func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- memory := scope.Memory
- stack := scope.Stack
-
- log := StructLog{
- Pc: pc,
- Op: op,
- Gas: gas,
- GasCost: cost,
- MemorySize: memory.Len(),
- Depth: depth,
- RefundCounter: l.env.StateDB.GetRefund(),
- Err: err,
- }
- if l.cfg.EnableMemory {
- log.Memory = memory.Data()
- }
- if !l.cfg.DisableStack {
- log.Stack = stack.Data()
- }
- if l.cfg.EnableReturnData {
- log.ReturnData = rData
- }
- l.encoder.Encode(log)
-}
-
-// CaptureEnd is triggered at end of execution.
-func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, err error) {
- type endLog struct {
- Output string `json:"output"`
- GasUsed math.HexOrDecimal64 `json:"gasUsed"`
- Err string `json:"error,omitempty"`
- }
- var errMsg string
- if err != nil {
- errMsg = err.Error()
- }
- l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), errMsg})
-}
-
-func (l *JSONLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
-}
-
-func (l *JSONLogger) CaptureExit(output []byte, gasUsed uint64, err error) {}
-
-func (l *JSONLogger) CaptureTxStart(gasLimit uint64) {}
-
-func (l *JSONLogger) CaptureTxEnd(restGas uint64) {}
diff --git a/eth/tracers/logger/logger_test.go b/eth/tracers/logger/logger_test.go
deleted file mode 100644
index 3192a15cba..0000000000
--- a/eth/tracers/logger/logger_test.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2021 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 logger
-
-import (
- "encoding/json"
- "errors"
- "math/big"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/params"
-)
-
-type dummyContractRef struct {
- calledForEach bool
-}
-
-func (dummyContractRef) Address() common.Address { return common.Address{} }
-func (dummyContractRef) Value() *big.Int { return new(big.Int) }
-func (dummyContractRef) SetCode(common.Hash, []byte) {}
-func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) {
- d.calledForEach = true
-}
-func (d *dummyContractRef) SubBalance(amount *big.Int) {}
-func (d *dummyContractRef) AddBalance(amount *big.Int) {}
-func (d *dummyContractRef) SetBalance(*big.Int) {}
-func (d *dummyContractRef) SetNonce(uint64) {}
-func (d *dummyContractRef) Balance() *big.Int { return new(big.Int) }
-
-type dummyStatedb struct {
- state.StateDB
-}
-
-func (*dummyStatedb) GetRefund() uint64 { return 1337 }
-func (*dummyStatedb) GetState(_ common.Address, _ common.Hash) common.Hash { return common.Hash{} }
-func (*dummyStatedb) SetState(_ common.Address, _ common.Hash, _ common.Hash) {}
-
-func TestStoreCapture(t *testing.T) {
- var (
- logger = NewStructLogger(nil)
- env = vm.NewEVM(vm.BlockContext{}, vm.TxContext{}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: logger})
- contract = vm.NewContract(&dummyContractRef{}, &dummyContractRef{}, new(big.Int), 100000)
- )
- contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)}
- var index common.Hash
- logger.CaptureStart(env, common.Address{}, contract.Address(), false, nil, 0, nil)
- _, err := env.Interpreter().Run(contract, []byte{}, false)
- if err != nil {
- t.Fatal(err)
- }
- if len(logger.storage[contract.Address()]) == 0 {
- t.Fatalf("expected exactly 1 changed value on address %x, got %d", contract.Address(),
- len(logger.storage[contract.Address()]))
- }
- exp := common.BigToHash(big.NewInt(1))
- if logger.storage[contract.Address()][index] != exp {
- t.Errorf("expected %x, got %x", exp, logger.storage[contract.Address()][index])
- }
-}
-
-// Tests that blank fields don't appear in logs when JSON marshalled, to reduce
-// logs bloat and confusion. See https://github.com/ethereum/go-ethereum/issues/24487
-func TestStructLogMarshalingOmitEmpty(t *testing.T) {
- tests := []struct {
- name string
- log *StructLog
- want string
- }{
- {"empty err and no fields", &StructLog{},
- `{"pc":0,"op":0,"gas":"0x0","gasCost":"0x0","memSize":0,"stack":null,"depth":0,"refund":0,"opName":"STOP"}`},
- {"with err", &StructLog{Err: errors.New("this failed")},
- `{"pc":0,"op":0,"gas":"0x0","gasCost":"0x0","memSize":0,"stack":null,"depth":0,"refund":0,"opName":"STOP","error":"this failed"}`},
- {"with mem", &StructLog{Memory: make([]byte, 2), MemorySize: 2},
- `{"pc":0,"op":0,"gas":"0x0","gasCost":"0x0","memory":"0x0000","memSize":2,"stack":null,"depth":0,"refund":0,"opName":"STOP"}`},
- {"with 0-size mem", &StructLog{Memory: make([]byte, 0)},
- `{"pc":0,"op":0,"gas":"0x0","gasCost":"0x0","memSize":0,"stack":null,"depth":0,"refund":0,"opName":"STOP"}`},
- }
-
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- blob, err := json.Marshal(tt.log)
- if err != nil {
- t.Fatal(err)
- }
- if have, want := string(blob), tt.want; have != want {
- t.Fatalf("mismatched results\n\thave: %v\n\twant: %v", have, want)
- }
- })
- }
-}
diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go
deleted file mode 100644
index 5a2c4f9111..0000000000
--- a/eth/tracers/native/4byte.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2021 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 native
-
-import (
- "encoding/json"
- "math/big"
- "strconv"
- "sync/atomic"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/tracers"
-)
-
-func init() {
- tracers.DefaultDirectory.Register("4byteTracer", newFourByteTracer, false)
-}
-
-// fourByteTracer searches for 4byte-identifiers, and collects them for post-processing.
-// It collects the methods identifiers along with the size of the supplied data, so
-// a reversed signature can be matched against the size of the data.
-//
-// Example:
-//
-// > debug.traceTransaction( "0x214e597e35da083692f5386141e69f47e973b2c56e7a8073b1ea08fd7571e9de", {tracer: "4byteTracer"})
-// {
-// 0x27dc297e-128: 1,
-// 0x38cc4831-0: 2,
-// 0x524f3889-96: 1,
-// 0xadf59f99-288: 1,
-// 0xc281d19e-0: 1
-// }
-type fourByteTracer struct {
- noopTracer
- ids map[string]int // ids aggregates the 4byte ids found
- interrupt atomic.Bool // Atomic flag to signal execution interruption
- reason error // Textual reason for the interruption
- activePrecompiles []common.Address // Updated on CaptureStart based on given rules
-}
-
-// newFourByteTracer returns a native go tracer which collects
-// 4 byte-identifiers of a tx, and implements vm.EVMLogger.
-func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, error) {
- t := &fourByteTracer{
- ids: make(map[string]int),
- }
- return t, nil
-}
-
-// isPrecompiled returns whether the addr is a precompile. Logic borrowed from newJsTracer in eth/tracers/js/tracer.go
-func (t *fourByteTracer) isPrecompiled(addr common.Address) bool {
- for _, p := range t.activePrecompiles {
- if p == addr {
- return true
- }
- }
- return false
-}
-
-// store saves the given identifier and datasize.
-func (t *fourByteTracer) store(id []byte, size int) {
- key := bytesToHex(id) + "-" + strconv.Itoa(size)
- t.ids[key] += 1
-}
-
-// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
-func (t *fourByteTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- // Update list of precompiles based on current block
- rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time)
- t.activePrecompiles = vm.ActivePrecompiles(rules)
-
- // Save the outer calldata also
- if len(input) >= 4 {
- t.store(input[0:4], len(input)-4)
- }
-}
-
-// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
-func (t *fourByteTracer) CaptureEnter(op vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
- // Skip if tracing was interrupted
- if t.interrupt.Load() {
- return
- }
- if len(input) < 4 {
- return
- }
- // primarily we want to avoid CREATE/CREATE2/SELFDESTRUCT
- if op != vm.DELEGATECALL && op != vm.STATICCALL &&
- op != vm.CALL && op != vm.CALLCODE {
- return
- }
- // Skip any pre-compile invocations, those are just fancy opcodes
- if t.isPrecompiled(to) {
- return
- }
- t.store(input[0:4], len(input)-4)
-}
-
-// GetResult returns the json-encoded nested list of call traces, and any
-// error arising from the encoding or forceful termination (via `Stop`).
-func (t *fourByteTracer) GetResult() (json.RawMessage, error) {
- res, err := json.Marshal(t.ids)
- if err != nil {
- return nil, err
- }
- return res, t.reason
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (t *fourByteTracer) Stop(err error) {
- t.reason = err
- t.interrupt.Store(true)
-}
-
-func bytesToHex(s []byte) string {
- return "0x" + common.Bytes2Hex(s)
-}
diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go
deleted file mode 100644
index f85cf6206a..0000000000
--- a/eth/tracers/native/call.go
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2021 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 native
-
-import (
- "encoding/json"
- "errors"
- "math/big"
- "sync/atomic"
-
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/tracers"
- "github.com/ethereum/go-ethereum/log"
-)
-
-//go:generate go run github.com/fjl/gencodec -type callFrame -field-override callFrameMarshaling -out gen_callframe_json.go
-
-func init() {
- tracers.DefaultDirectory.Register("callTracer", newCallTracer, false)
-}
-
-type callLog struct {
- Address common.Address `json:"address"`
- Topics []common.Hash `json:"topics"`
- Data hexutil.Bytes `json:"data"`
- // Position of the log relative to subcalls within the same trace
- // See https://github.com/ethereum/go-ethereum/pull/28389 for details
- Position hexutil.Uint `json:"position"`
-}
-
-type callFrame struct {
- Type vm.OpCode `json:"-"`
- From common.Address `json:"from"`
- Gas uint64 `json:"gas"`
- GasUsed uint64 `json:"gasUsed"`
- To *common.Address `json:"to,omitempty" rlp:"optional"`
- Input []byte `json:"input" rlp:"optional"`
- Output []byte `json:"output,omitempty" rlp:"optional"`
- Error string `json:"error,omitempty" rlp:"optional"`
- RevertReason string `json:"revertReason,omitempty"`
- Calls []callFrame `json:"calls,omitempty" rlp:"optional"`
- Logs []callLog `json:"logs,omitempty" rlp:"optional"`
- // Placed at end on purpose. The RLP will be decoded to 0 instead of
- // nil if there are non-empty elements after in the struct.
- Value *big.Int `json:"value,omitempty" rlp:"optional"`
-}
-
-func (f callFrame) TypeString() string {
- return f.Type.String()
-}
-
-func (f callFrame) failed() bool {
- return len(f.Error) > 0
-}
-
-func (f *callFrame) processOutput(output []byte, err error) {
- output = common.CopyBytes(output)
- if err == nil {
- f.Output = output
- return
- }
- f.Error = err.Error()
- if f.Type == vm.CREATE || f.Type == vm.CREATE2 {
- f.To = nil
- }
- if !errors.Is(err, vm.ErrExecutionReverted) || len(output) == 0 {
- return
- }
- f.Output = output
- if len(output) < 4 {
- return
- }
- if unpacked, err := abi.UnpackRevert(output); err == nil {
- f.RevertReason = unpacked
- }
-}
-
-type callFrameMarshaling struct {
- TypeString string `json:"type"`
- Gas hexutil.Uint64
- GasUsed hexutil.Uint64
- Value *hexutil.Big
- Input hexutil.Bytes
- Output hexutil.Bytes
-}
-
-type callTracer struct {
- noopTracer
- callstack []callFrame
- config callTracerConfig
- gasLimit uint64
- interrupt atomic.Bool // Atomic flag to signal execution interruption
- reason error // Textual reason for the interruption
-}
-
-type callTracerConfig struct {
- OnlyTopCall bool `json:"onlyTopCall"` // If true, call tracer won't collect any subcalls
- WithLog bool `json:"withLog"` // If true, call tracer will collect event logs
-}
-
-// newCallTracer returns a native go tracer which tracks
-// call frames of a tx, and implements vm.EVMLogger.
-func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
- var config callTracerConfig
- if cfg != nil {
- if err := json.Unmarshal(cfg, &config); err != nil {
- return nil, err
- }
- }
- // First callframe contains tx context info
- // and is populated on start and end.
- return &callTracer{callstack: make([]callFrame, 1), config: config}, nil
-}
-
-// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
-func (t *callTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- toCopy := to
- t.callstack[0] = callFrame{
- Type: vm.CALL,
- From: from,
- To: &toCopy,
- Input: common.CopyBytes(input),
- Gas: t.gasLimit,
- Value: value,
- }
- if create {
- t.callstack[0].Type = vm.CREATE
- }
-}
-
-// CaptureEnd is called after the call finishes to finalize the tracing.
-func (t *callTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
- t.callstack[0].processOutput(output, err)
-}
-
-// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
-func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- // skip if the previous op caused an error
- if err != nil {
- return
- }
- // Only logs need to be captured via opcode processing
- if !t.config.WithLog {
- return
- }
- // Avoid processing nested calls when only caring about top call
- if t.config.OnlyTopCall && depth > 0 {
- return
- }
- // Skip if tracing was interrupted
- if t.interrupt.Load() {
- return
- }
- switch op {
- case vm.LOG0, vm.LOG1, vm.LOG2, vm.LOG3, vm.LOG4:
- size := int(op - vm.LOG0)
-
- stack := scope.Stack
- stackData := stack.Data()
-
- // Don't modify the stack
- mStart := stackData[len(stackData)-1]
- mSize := stackData[len(stackData)-2]
- topics := make([]common.Hash, size)
- for i := 0; i < size; i++ {
- topic := stackData[len(stackData)-2-(i+1)]
- topics[i] = common.Hash(topic.Bytes32())
- }
-
- data, err := tracers.GetMemoryCopyPadded(scope.Memory, int64(mStart.Uint64()), int64(mSize.Uint64()))
- if err != nil {
- // mSize was unrealistically large
- log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "callTracer", "offset", mStart, "size", mSize)
- return
- }
-
- log := callLog{
- Address: scope.Contract.Address(),
- Topics: topics,
- Data: hexutil.Bytes(data),
- Position: hexutil.Uint(len(t.callstack[len(t.callstack)-1].Calls)),
- }
- t.callstack[len(t.callstack)-1].Logs = append(t.callstack[len(t.callstack)-1].Logs, log)
- }
-}
-
-// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
-func (t *callTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
- if t.config.OnlyTopCall {
- return
- }
- // Skip if tracing was interrupted
- if t.interrupt.Load() {
- return
- }
-
- toCopy := to
- call := callFrame{
- Type: typ,
- From: from,
- To: &toCopy,
- Input: common.CopyBytes(input),
- Gas: gas,
- Value: value,
- }
- t.callstack = append(t.callstack, call)
-}
-
-// CaptureExit is called when EVM exits a scope, even if the scope didn't
-// execute any code.
-func (t *callTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
- if t.config.OnlyTopCall {
- return
- }
- size := len(t.callstack)
- if size <= 1 {
- return
- }
- // pop call
- call := t.callstack[size-1]
- t.callstack = t.callstack[:size-1]
- size -= 1
-
- call.GasUsed = gasUsed
- call.processOutput(output, err)
- t.callstack[size-1].Calls = append(t.callstack[size-1].Calls, call)
-}
-
-func (t *callTracer) CaptureTxStart(gasLimit uint64) {
- t.gasLimit = gasLimit
-}
-
-func (t *callTracer) CaptureTxEnd(restGas uint64) {
- t.callstack[0].GasUsed = t.gasLimit - restGas
- if t.config.WithLog {
- // Logs are not emitted when the call fails
- clearFailedLogs(&t.callstack[0], false)
- }
-}
-
-// GetResult returns the json-encoded nested list of call traces, and any
-// error arising from the encoding or forceful termination (via `Stop`).
-func (t *callTracer) GetResult() (json.RawMessage, error) {
- if len(t.callstack) != 1 {
- return nil, errors.New("incorrect number of top-level calls")
- }
-
- res, err := json.Marshal(t.callstack[0])
- if err != nil {
- return nil, err
- }
- return json.RawMessage(res), t.reason
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (t *callTracer) Stop(err error) {
- t.reason = err
- t.interrupt.Store(true)
-}
-
-// clearFailedLogs clears the logs of a callframe and all its children
-// in case of execution failure.
-func clearFailedLogs(cf *callFrame, parentFailed bool) {
- failed := cf.failed() || parentFailed
- // Clear own logs
- if failed {
- cf.Logs = nil
- }
- for i := range cf.Calls {
- clearFailedLogs(&cf.Calls[i], failed)
- }
-}
diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go
deleted file mode 100644
index 266ab99001..0000000000
--- a/eth/tracers/native/call_flat.go
+++ /dev/null
@@ -1,381 +0,0 @@
-// 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 native
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
- "strings"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/tracers"
-)
-
-//go:generate go run github.com/fjl/gencodec -type flatCallAction -field-override flatCallActionMarshaling -out gen_flatcallaction_json.go
-//go:generate go run github.com/fjl/gencodec -type flatCallResult -field-override flatCallResultMarshaling -out gen_flatcallresult_json.go
-
-func init() {
- tracers.DefaultDirectory.Register("flatCallTracer", newFlatCallTracer, false)
-}
-
-var parityErrorMapping = map[string]string{
- "contract creation code storage out of gas": "Out of gas",
- "out of gas": "Out of gas",
- "gas uint64 overflow": "Out of gas",
- "max code size exceeded": "Out of gas",
- "invalid jump destination": "Bad jump destination",
- "execution reverted": "Reverted",
- "return data out of bounds": "Out of bounds",
- "stack limit reached 1024 (1023)": "Out of stack",
- "precompiled failed": "Built-in failed",
- "invalid input length": "Built-in failed",
-}
-
-var parityErrorMappingStartingWith = map[string]string{
- "invalid opcode:": "Bad instruction",
- "stack underflow": "Stack underflow",
-}
-
-// flatCallFrame is a standalone callframe.
-type flatCallFrame struct {
- Action flatCallAction `json:"action"`
- BlockHash *common.Hash `json:"blockHash"`
- BlockNumber uint64 `json:"blockNumber"`
- Error string `json:"error,omitempty"`
- Result *flatCallResult `json:"result,omitempty"`
- Subtraces int `json:"subtraces"`
- TraceAddress []int `json:"traceAddress"`
- TransactionHash *common.Hash `json:"transactionHash"`
- TransactionPosition uint64 `json:"transactionPosition"`
- Type string `json:"type"`
-}
-
-type flatCallAction struct {
- Author *common.Address `json:"author,omitempty"`
- RewardType string `json:"rewardType,omitempty"`
- SelfDestructed *common.Address `json:"address,omitempty"`
- Balance *big.Int `json:"balance,omitempty"`
- CallType string `json:"callType,omitempty"`
- CreationMethod string `json:"creationMethod,omitempty"`
- From *common.Address `json:"from,omitempty"`
- Gas *uint64 `json:"gas,omitempty"`
- Init *[]byte `json:"init,omitempty"`
- Input *[]byte `json:"input,omitempty"`
- RefundAddress *common.Address `json:"refundAddress,omitempty"`
- To *common.Address `json:"to,omitempty"`
- Value *big.Int `json:"value,omitempty"`
-}
-
-type flatCallActionMarshaling struct {
- Balance *hexutil.Big
- Gas *hexutil.Uint64
- Init *hexutil.Bytes
- Input *hexutil.Bytes
- Value *hexutil.Big
-}
-
-type flatCallResult struct {
- Address *common.Address `json:"address,omitempty"`
- Code *[]byte `json:"code,omitempty"`
- GasUsed *uint64 `json:"gasUsed,omitempty"`
- Output *[]byte `json:"output,omitempty"`
-}
-
-type flatCallResultMarshaling struct {
- Code *hexutil.Bytes
- GasUsed *hexutil.Uint64
- Output *hexutil.Bytes
-}
-
-// flatCallTracer reports call frame information of a tx in a flat format, i.e.
-// as opposed to the nested format of `callTracer`.
-type flatCallTracer struct {
- tracer *callTracer
- config flatCallTracerConfig
- ctx *tracers.Context // Holds tracer context data
- reason error // Textual reason for the interruption
- activePrecompiles []common.Address // Updated on CaptureStart based on given rules
-}
-
-type flatCallTracerConfig struct {
- ConvertParityErrors bool `json:"convertParityErrors"` // If true, call tracer converts errors to parity format
- IncludePrecompiles bool `json:"includePrecompiles"` // If true, call tracer includes calls to precompiled contracts
-}
-
-// newFlatCallTracer returns a new flatCallTracer.
-func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
- var config flatCallTracerConfig
- if cfg != nil {
- if err := json.Unmarshal(cfg, &config); err != nil {
- return nil, err
- }
- }
-
- // Create inner call tracer with default configuration, don't forward
- // the OnlyTopCall or WithLog to inner for now
- tracer, err := tracers.DefaultDirectory.New("callTracer", ctx, nil)
- if err != nil {
- return nil, err
- }
- t, ok := tracer.(*callTracer)
- if !ok {
- return nil, errors.New("internal error: embedded tracer has wrong type")
- }
-
- return &flatCallTracer{tracer: t, ctx: ctx, config: config}, nil
-}
-
-// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
-func (t *flatCallTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- t.tracer.CaptureStart(env, from, to, create, input, gas, value)
- // Update list of precompiles based on current block
- rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Random != nil, env.Context.Time)
- t.activePrecompiles = vm.ActivePrecompiles(rules)
-}
-
-// CaptureEnd is called after the call finishes to finalize the tracing.
-func (t *flatCallTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
- t.tracer.CaptureEnd(output, gasUsed, err)
-}
-
-// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
-func (t *flatCallTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- t.tracer.CaptureState(pc, op, gas, cost, scope, rData, depth, err)
-}
-
-// CaptureFault implements the EVMLogger interface to trace an execution fault.
-func (t *flatCallTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
- t.tracer.CaptureFault(pc, op, gas, cost, scope, depth, err)
-}
-
-// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
-func (t *flatCallTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
- t.tracer.CaptureEnter(typ, from, to, input, gas, value)
-
- // Child calls must have a value, even if it's zero.
- // Practically speaking, only STATICCALL has nil value. Set it to zero.
- if t.tracer.callstack[len(t.tracer.callstack)-1].Value == nil && value == nil {
- t.tracer.callstack[len(t.tracer.callstack)-1].Value = big.NewInt(0)
- }
-}
-
-// CaptureExit is called when EVM exits a scope, even if the scope didn't
-// execute any code.
-func (t *flatCallTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
- t.tracer.CaptureExit(output, gasUsed, err)
-
- // Parity traces don't include CALL/STATICCALLs to precompiles.
- // By default we remove them from the callstack.
- if t.config.IncludePrecompiles {
- return
- }
- var (
- // call has been nested in parent
- parent = t.tracer.callstack[len(t.tracer.callstack)-1]
- call = parent.Calls[len(parent.Calls)-1]
- typ = call.Type
- to = call.To
- )
- if typ == vm.CALL || typ == vm.STATICCALL {
- if t.isPrecompiled(*to) {
- t.tracer.callstack[len(t.tracer.callstack)-1].Calls = parent.Calls[:len(parent.Calls)-1]
- }
- }
-}
-
-func (t *flatCallTracer) CaptureTxStart(gasLimit uint64) {
- t.tracer.CaptureTxStart(gasLimit)
-}
-
-func (t *flatCallTracer) CaptureTxEnd(restGas uint64) {
- t.tracer.CaptureTxEnd(restGas)
-}
-
-// GetResult returns an empty json object.
-func (t *flatCallTracer) GetResult() (json.RawMessage, error) {
- if len(t.tracer.callstack) < 1 {
- return nil, errors.New("invalid number of calls")
- }
-
- flat, err := flatFromNested(&t.tracer.callstack[0], []int{}, t.config.ConvertParityErrors, t.ctx)
- if err != nil {
- return nil, err
- }
-
- res, err := json.Marshal(flat)
- if err != nil {
- return nil, err
- }
- return res, t.reason
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (t *flatCallTracer) Stop(err error) {
- t.tracer.Stop(err)
-}
-
-// isPrecompiled returns whether the addr is a precompile.
-func (t *flatCallTracer) isPrecompiled(addr common.Address) bool {
- for _, p := range t.activePrecompiles {
- if p == addr {
- return true
- }
- }
- return false
-}
-
-func flatFromNested(input *callFrame, traceAddress []int, convertErrs bool, ctx *tracers.Context) (output []flatCallFrame, err error) {
- var frame *flatCallFrame
- switch input.Type {
- case vm.CREATE, vm.CREATE2:
- frame = newFlatCreate(input)
- case vm.SELFDESTRUCT:
- frame = newFlatSelfdestruct(input)
- case vm.CALL, vm.STATICCALL, vm.CALLCODE, vm.DELEGATECALL:
- frame = newFlatCall(input)
- default:
- return nil, fmt.Errorf("unrecognized call frame type: %s", input.Type)
- }
-
- frame.TraceAddress = traceAddress
- frame.Error = input.Error
- frame.Subtraces = len(input.Calls)
- fillCallFrameFromContext(frame, ctx)
- if convertErrs {
- convertErrorToParity(frame)
- }
-
- // Revert output contains useful information (revert reason).
- // Otherwise discard result.
- if input.Error != "" && input.Error != vm.ErrExecutionReverted.Error() {
- frame.Result = nil
- }
-
- output = append(output, *frame)
- if len(input.Calls) > 0 {
- for i, childCall := range input.Calls {
- childAddr := childTraceAddress(traceAddress, i)
- childCallCopy := childCall
- flat, err := flatFromNested(&childCallCopy, childAddr, convertErrs, ctx)
- if err != nil {
- return nil, err
- }
- output = append(output, flat...)
- }
- }
-
- return output, nil
-}
-
-func newFlatCreate(input *callFrame) *flatCallFrame {
- var (
- actionInit = input.Input[:]
- resultCode = input.Output[:]
- )
-
- return &flatCallFrame{
- Type: strings.ToLower(vm.CREATE.String()),
- Action: flatCallAction{
- From: &input.From,
- Gas: &input.Gas,
- Value: input.Value,
- Init: &actionInit,
- },
- Result: &flatCallResult{
- GasUsed: &input.GasUsed,
- Address: input.To,
- Code: &resultCode,
- },
- }
-}
-
-func newFlatCall(input *callFrame) *flatCallFrame {
- var (
- actionInput = input.Input[:]
- resultOutput = input.Output[:]
- )
-
- return &flatCallFrame{
- Type: strings.ToLower(vm.CALL.String()),
- Action: flatCallAction{
- From: &input.From,
- To: input.To,
- Gas: &input.Gas,
- Value: input.Value,
- CallType: strings.ToLower(input.Type.String()),
- Input: &actionInput,
- },
- Result: &flatCallResult{
- GasUsed: &input.GasUsed,
- Output: &resultOutput,
- },
- }
-}
-
-func newFlatSelfdestruct(input *callFrame) *flatCallFrame {
- return &flatCallFrame{
- Type: "suicide",
- Action: flatCallAction{
- SelfDestructed: &input.From,
- Balance: input.Value,
- RefundAddress: input.To,
- },
- }
-}
-
-func fillCallFrameFromContext(callFrame *flatCallFrame, ctx *tracers.Context) {
- if ctx == nil {
- return
- }
- if ctx.BlockHash != (common.Hash{}) {
- callFrame.BlockHash = &ctx.BlockHash
- }
- if ctx.BlockNumber != nil {
- callFrame.BlockNumber = ctx.BlockNumber.Uint64()
- }
- if ctx.TxHash != (common.Hash{}) {
- callFrame.TransactionHash = &ctx.TxHash
- }
- callFrame.TransactionPosition = uint64(ctx.TxIndex)
-}
-
-func convertErrorToParity(call *flatCallFrame) {
- if call.Error == "" {
- return
- }
-
- if parityError, ok := parityErrorMapping[call.Error]; ok {
- call.Error = parityError
- } else {
- for gethError, parityError := range parityErrorMappingStartingWith {
- if strings.HasPrefix(call.Error, gethError) {
- call.Error = parityError
- }
- }
- }
-}
-
-func childTraceAddress(a []int, i int) []int {
- child := make([]int, 0, len(a)+1)
- child = append(child, a...)
- child = append(child, i)
- return child
-}
diff --git a/eth/tracers/native/gen_account_json.go b/eth/tracers/native/gen_account_json.go
deleted file mode 100644
index 4c39cbc38c..0000000000
--- a/eth/tracers/native/gen_account_json.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package native
-
-import (
- "encoding/json"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*accountMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (a account) MarshalJSON() ([]byte, error) {
- type account struct {
- Balance *hexutil.Big `json:"balance,omitempty"`
- Code hexutil.Bytes `json:"code,omitempty"`
- Nonce uint64 `json:"nonce,omitempty"`
- Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
- }
- var enc account
- enc.Balance = (*hexutil.Big)(a.Balance)
- enc.Code = a.Code
- enc.Nonce = a.Nonce
- enc.Storage = a.Storage
- return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (a *account) UnmarshalJSON(input []byte) error {
- type account struct {
- Balance *hexutil.Big `json:"balance,omitempty"`
- Code *hexutil.Bytes `json:"code,omitempty"`
- Nonce *uint64 `json:"nonce,omitempty"`
- Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
- }
- var dec account
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Balance != nil {
- a.Balance = (*big.Int)(dec.Balance)
- }
- if dec.Code != nil {
- a.Code = *dec.Code
- }
- if dec.Nonce != nil {
- a.Nonce = *dec.Nonce
- }
- if dec.Storage != nil {
- a.Storage = dec.Storage
- }
- return nil
-}
diff --git a/eth/tracers/native/gen_callframe_json.go b/eth/tracers/native/gen_callframe_json.go
deleted file mode 100644
index c44f38390d..0000000000
--- a/eth/tracers/native/gen_callframe_json.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package native
-
-import (
- "encoding/json"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/vm"
-)
-
-var _ = (*callFrameMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (c callFrame) MarshalJSON() ([]byte, error) {
- type callFrame0 struct {
- Type vm.OpCode `json:"-"`
- From common.Address `json:"from"`
- Gas hexutil.Uint64 `json:"gas"`
- GasUsed hexutil.Uint64 `json:"gasUsed"`
- To *common.Address `json:"to,omitempty" rlp:"optional"`
- Input hexutil.Bytes `json:"input" rlp:"optional"`
- Output hexutil.Bytes `json:"output,omitempty" rlp:"optional"`
- Error string `json:"error,omitempty" rlp:"optional"`
- RevertReason string `json:"revertReason,omitempty"`
- Calls []callFrame `json:"calls,omitempty" rlp:"optional"`
- Logs []callLog `json:"logs,omitempty" rlp:"optional"`
- Value *hexutil.Big `json:"value,omitempty" rlp:"optional"`
- TypeString string `json:"type"`
- }
- var enc callFrame0
- enc.Type = c.Type
- enc.From = c.From
- enc.Gas = hexutil.Uint64(c.Gas)
- enc.GasUsed = hexutil.Uint64(c.GasUsed)
- enc.To = c.To
- enc.Input = c.Input
- enc.Output = c.Output
- enc.Error = c.Error
- enc.RevertReason = c.RevertReason
- enc.Calls = c.Calls
- enc.Logs = c.Logs
- enc.Value = (*hexutil.Big)(c.Value)
- enc.TypeString = c.TypeString()
- return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (c *callFrame) UnmarshalJSON(input []byte) error {
- type callFrame0 struct {
- Type *vm.OpCode `json:"-"`
- From *common.Address `json:"from"`
- Gas *hexutil.Uint64 `json:"gas"`
- GasUsed *hexutil.Uint64 `json:"gasUsed"`
- To *common.Address `json:"to,omitempty" rlp:"optional"`
- Input *hexutil.Bytes `json:"input" rlp:"optional"`
- Output *hexutil.Bytes `json:"output,omitempty" rlp:"optional"`
- Error *string `json:"error,omitempty" rlp:"optional"`
- RevertReason *string `json:"revertReason,omitempty"`
- Calls []callFrame `json:"calls,omitempty" rlp:"optional"`
- Logs []callLog `json:"logs,omitempty" rlp:"optional"`
- Value *hexutil.Big `json:"value,omitempty" rlp:"optional"`
- }
- var dec callFrame0
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Type != nil {
- c.Type = *dec.Type
- }
- if dec.From != nil {
- c.From = *dec.From
- }
- if dec.Gas != nil {
- c.Gas = uint64(*dec.Gas)
- }
- if dec.GasUsed != nil {
- c.GasUsed = uint64(*dec.GasUsed)
- }
- if dec.To != nil {
- c.To = dec.To
- }
- if dec.Input != nil {
- c.Input = *dec.Input
- }
- if dec.Output != nil {
- c.Output = *dec.Output
- }
- if dec.Error != nil {
- c.Error = *dec.Error
- }
- if dec.RevertReason != nil {
- c.RevertReason = *dec.RevertReason
- }
- if dec.Calls != nil {
- c.Calls = dec.Calls
- }
- if dec.Logs != nil {
- c.Logs = dec.Logs
- }
- if dec.Value != nil {
- c.Value = (*big.Int)(dec.Value)
- }
- return nil
-}
diff --git a/eth/tracers/native/gen_flatcallaction_json.go b/eth/tracers/native/gen_flatcallaction_json.go
deleted file mode 100644
index c075606983..0000000000
--- a/eth/tracers/native/gen_flatcallaction_json.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package native
-
-import (
- "encoding/json"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*flatCallActionMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (f flatCallAction) MarshalJSON() ([]byte, error) {
- type flatCallAction struct {
- Author *common.Address `json:"author,omitempty"`
- RewardType string `json:"rewardType,omitempty"`
- SelfDestructed *common.Address `json:"address,omitempty"`
- Balance *hexutil.Big `json:"balance,omitempty"`
- CallType string `json:"callType,omitempty"`
- CreationMethod string `json:"creationMethod,omitempty"`
- From *common.Address `json:"from,omitempty"`
- Gas *hexutil.Uint64 `json:"gas,omitempty"`
- Init *hexutil.Bytes `json:"init,omitempty"`
- Input *hexutil.Bytes `json:"input,omitempty"`
- RefundAddress *common.Address `json:"refundAddress,omitempty"`
- To *common.Address `json:"to,omitempty"`
- Value *hexutil.Big `json:"value,omitempty"`
- }
- var enc flatCallAction
- enc.Author = f.Author
- enc.RewardType = f.RewardType
- enc.SelfDestructed = f.SelfDestructed
- enc.Balance = (*hexutil.Big)(f.Balance)
- enc.CallType = f.CallType
- enc.CreationMethod = f.CreationMethod
- enc.From = f.From
- enc.Gas = (*hexutil.Uint64)(f.Gas)
- enc.Init = (*hexutil.Bytes)(f.Init)
- enc.Input = (*hexutil.Bytes)(f.Input)
- enc.RefundAddress = f.RefundAddress
- enc.To = f.To
- enc.Value = (*hexutil.Big)(f.Value)
- return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (f *flatCallAction) UnmarshalJSON(input []byte) error {
- type flatCallAction struct {
- Author *common.Address `json:"author,omitempty"`
- RewardType *string `json:"rewardType,omitempty"`
- SelfDestructed *common.Address `json:"address,omitempty"`
- Balance *hexutil.Big `json:"balance,omitempty"`
- CallType *string `json:"callType,omitempty"`
- CreationMethod *string `json:"creationMethod,omitempty"`
- From *common.Address `json:"from,omitempty"`
- Gas *hexutil.Uint64 `json:"gas,omitempty"`
- Init *hexutil.Bytes `json:"init,omitempty"`
- Input *hexutil.Bytes `json:"input,omitempty"`
- RefundAddress *common.Address `json:"refundAddress,omitempty"`
- To *common.Address `json:"to,omitempty"`
- Value *hexutil.Big `json:"value,omitempty"`
- }
- var dec flatCallAction
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Author != nil {
- f.Author = dec.Author
- }
- if dec.RewardType != nil {
- f.RewardType = *dec.RewardType
- }
- if dec.SelfDestructed != nil {
- f.SelfDestructed = dec.SelfDestructed
- }
- if dec.Balance != nil {
- f.Balance = (*big.Int)(dec.Balance)
- }
- if dec.CallType != nil {
- f.CallType = *dec.CallType
- }
- if dec.CreationMethod != nil {
- f.CreationMethod = *dec.CreationMethod
- }
- if dec.From != nil {
- f.From = dec.From
- }
- if dec.Gas != nil {
- f.Gas = (*uint64)(dec.Gas)
- }
- if dec.Init != nil {
- f.Init = (*[]byte)(dec.Init)
- }
- if dec.Input != nil {
- f.Input = (*[]byte)(dec.Input)
- }
- if dec.RefundAddress != nil {
- f.RefundAddress = dec.RefundAddress
- }
- if dec.To != nil {
- f.To = dec.To
- }
- if dec.Value != nil {
- f.Value = (*big.Int)(dec.Value)
- }
- return nil
-}
diff --git a/eth/tracers/native/gen_flatcallresult_json.go b/eth/tracers/native/gen_flatcallresult_json.go
deleted file mode 100644
index e9fa5e44da..0000000000
--- a/eth/tracers/native/gen_flatcallresult_json.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package native
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*flatCallResultMarshaling)(nil)
-
-// MarshalJSON marshals as JSON.
-func (f flatCallResult) MarshalJSON() ([]byte, error) {
- type flatCallResult struct {
- Address *common.Address `json:"address,omitempty"`
- Code *hexutil.Bytes `json:"code,omitempty"`
- GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"`
- Output *hexutil.Bytes `json:"output,omitempty"`
- }
- var enc flatCallResult
- enc.Address = f.Address
- enc.Code = (*hexutil.Bytes)(f.Code)
- enc.GasUsed = (*hexutil.Uint64)(f.GasUsed)
- enc.Output = (*hexutil.Bytes)(f.Output)
- return json.Marshal(&enc)
-}
-
-// UnmarshalJSON unmarshals from JSON.
-func (f *flatCallResult) UnmarshalJSON(input []byte) error {
- type flatCallResult struct {
- Address *common.Address `json:"address,omitempty"`
- Code *hexutil.Bytes `json:"code,omitempty"`
- GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"`
- Output *hexutil.Bytes `json:"output,omitempty"`
- }
- var dec flatCallResult
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Address != nil {
- f.Address = dec.Address
- }
- if dec.Code != nil {
- f.Code = (*[]byte)(dec.Code)
- }
- if dec.GasUsed != nil {
- f.GasUsed = (*uint64)(dec.GasUsed)
- }
- if dec.Output != nil {
- f.Output = (*[]byte)(dec.Output)
- }
- return nil
-}
diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go
deleted file mode 100644
index db8ddd6438..0000000000
--- a/eth/tracers/native/mux.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// 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 native
-
-import (
- "encoding/json"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/tracers"
-)
-
-func init() {
- tracers.DefaultDirectory.Register("muxTracer", newMuxTracer, false)
-}
-
-// muxTracer is a go implementation of the Tracer interface which
-// runs multiple tracers in one go.
-type muxTracer struct {
- names []string
- tracers []tracers.Tracer
-}
-
-// newMuxTracer returns a new mux tracer.
-func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
- var config map[string]json.RawMessage
- if cfg != nil {
- if err := json.Unmarshal(cfg, &config); err != nil {
- return nil, err
- }
- }
- objects := make([]tracers.Tracer, 0, len(config))
- names := make([]string, 0, len(config))
- for k, v := range config {
- t, err := tracers.DefaultDirectory.New(k, ctx, v)
- if err != nil {
- return nil, err
- }
- objects = append(objects, t)
- names = append(names, k)
- }
-
- return &muxTracer{names: names, tracers: objects}, nil
-}
-
-// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
-func (t *muxTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- for _, t := range t.tracers {
- t.CaptureStart(env, from, to, create, input, gas, value)
- }
-}
-
-// CaptureEnd is called after the call finishes to finalize the tracing.
-func (t *muxTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
- for _, t := range t.tracers {
- t.CaptureEnd(output, gasUsed, err)
- }
-}
-
-// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
-func (t *muxTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- for _, t := range t.tracers {
- t.CaptureState(pc, op, gas, cost, scope, rData, depth, err)
- }
-}
-
-// CaptureFault implements the EVMLogger interface to trace an execution fault.
-func (t *muxTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
- for _, t := range t.tracers {
- t.CaptureFault(pc, op, gas, cost, scope, depth, err)
- }
-}
-
-// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
-func (t *muxTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
- for _, t := range t.tracers {
- t.CaptureEnter(typ, from, to, input, gas, value)
- }
-}
-
-// CaptureExit is called when EVM exits a scope, even if the scope didn't
-// execute any code.
-func (t *muxTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
- for _, t := range t.tracers {
- t.CaptureExit(output, gasUsed, err)
- }
-}
-
-func (t *muxTracer) CaptureTxStart(gasLimit uint64) {
- for _, t := range t.tracers {
- t.CaptureTxStart(gasLimit)
- }
-}
-
-func (t *muxTracer) CaptureTxEnd(restGas uint64) {
- for _, t := range t.tracers {
- t.CaptureTxEnd(restGas)
- }
-}
-
-// GetResult returns an empty json object.
-func (t *muxTracer) GetResult() (json.RawMessage, error) {
- resObject := make(map[string]json.RawMessage)
- for i, tt := range t.tracers {
- r, err := tt.GetResult()
- if err != nil {
- return nil, err
- }
- resObject[t.names[i]] = r
- }
- res, err := json.Marshal(resObject)
- if err != nil {
- return nil, err
- }
- return res, nil
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (t *muxTracer) Stop(err error) {
- for _, t := range t.tracers {
- t.Stop(err)
- }
-}
diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go
deleted file mode 100644
index 3beecd8abf..0000000000
--- a/eth/tracers/native/noop.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2021 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 native
-
-import (
- "encoding/json"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/tracers"
-)
-
-func init() {
- tracers.DefaultDirectory.Register("noopTracer", newNoopTracer, false)
-}
-
-// noopTracer is a go implementation of the Tracer interface which
-// performs no action. It's mostly useful for testing purposes.
-type noopTracer struct{}
-
-// newNoopTracer returns a new noop tracer.
-func newNoopTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, error) {
- return &noopTracer{}, nil
-}
-
-// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
-func (t *noopTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
-}
-
-// CaptureEnd is called after the call finishes to finalize the tracing.
-func (t *noopTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
-}
-
-// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
-func (t *noopTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
-}
-
-// CaptureFault implements the EVMLogger interface to trace an execution fault.
-func (t *noopTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) {
-}
-
-// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
-func (t *noopTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
-}
-
-// CaptureExit is called when EVM exits a scope, even if the scope didn't
-// execute any code.
-func (t *noopTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
-}
-
-func (*noopTracer) CaptureTxStart(gasLimit uint64) {}
-
-func (*noopTracer) CaptureTxEnd(restGas uint64) {}
-
-// GetResult returns an empty json object.
-func (t *noopTracer) GetResult() (json.RawMessage, error) {
- return json.RawMessage(`{}`), nil
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (t *noopTracer) Stop(err error) {
-}
diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go
deleted file mode 100644
index 82451c40a6..0000000000
--- a/eth/tracers/native/prestate.go
+++ /dev/null
@@ -1,297 +0,0 @@
-// 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 native
-
-import (
- "bytes"
- "encoding/json"
- "math/big"
- "sync/atomic"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/eth/tracers"
- "github.com/ethereum/go-ethereum/log"
-)
-
-//go:generate go run github.com/fjl/gencodec -type account -field-override accountMarshaling -out gen_account_json.go
-
-func init() {
- tracers.DefaultDirectory.Register("prestateTracer", newPrestateTracer, false)
-}
-
-type state = map[common.Address]*account
-
-type account struct {
- Balance *big.Int `json:"balance,omitempty"`
- Code []byte `json:"code,omitempty"`
- Nonce uint64 `json:"nonce,omitempty"`
- Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
-}
-
-func (a *account) exists() bool {
- return a.Nonce > 0 || len(a.Code) > 0 || len(a.Storage) > 0 || (a.Balance != nil && a.Balance.Sign() != 0)
-}
-
-type accountMarshaling struct {
- Balance *hexutil.Big
- Code hexutil.Bytes
-}
-
-type prestateTracer struct {
- noopTracer
- env *vm.EVM
- pre state
- post state
- create bool
- to common.Address
- gasLimit uint64 // Amount of gas bought for the whole tx
- config prestateTracerConfig
- interrupt atomic.Bool // Atomic flag to signal execution interruption
- reason error // Textual reason for the interruption
- created map[common.Address]bool
- deleted map[common.Address]bool
-}
-
-type prestateTracerConfig struct {
- DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications
-}
-
-func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
- var config prestateTracerConfig
- if cfg != nil {
- if err := json.Unmarshal(cfg, &config); err != nil {
- return nil, err
- }
- }
- return &prestateTracer{
- pre: state{},
- post: state{},
- config: config,
- created: make(map[common.Address]bool),
- deleted: make(map[common.Address]bool),
- }, nil
-}
-
-// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
-func (t *prestateTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
- t.env = env
- t.create = create
- t.to = to
-
- t.lookupAccount(from)
- t.lookupAccount(to)
- t.lookupAccount(env.Context.Coinbase)
-
- // The recipient balance includes the value transferred.
- toBal := new(big.Int).Sub(t.pre[to].Balance, value)
- t.pre[to].Balance = toBal
-
- // The sender balance is after reducing: value and gasLimit.
- // We need to re-add them to get the pre-tx balance.
- fromBal := new(big.Int).Set(t.pre[from].Balance)
- gasPrice := env.TxContext.GasPrice
- consumedGas := new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(t.gasLimit))
- fromBal.Add(fromBal, new(big.Int).Add(value, consumedGas))
- t.pre[from].Balance = fromBal
- t.pre[from].Nonce--
-
- if create && t.config.DiffMode {
- t.created[to] = true
- }
-}
-
-// CaptureEnd is called after the call finishes to finalize the tracing.
-func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {
- if t.config.DiffMode {
- return
- }
-
- if t.create {
- // Keep existing account prior to contract creation at that address
- if s := t.pre[t.to]; s != nil && !s.exists() {
- // Exclude newly created contract.
- delete(t.pre, t.to)
- }
- }
-}
-
-// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
-func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
- if err != nil {
- return
- }
- // Skip if tracing was interrupted
- if t.interrupt.Load() {
- return
- }
- stack := scope.Stack
- stackData := stack.Data()
- stackLen := len(stackData)
- caller := scope.Contract.Address()
- switch {
- case stackLen >= 1 && (op == vm.SLOAD || op == vm.SSTORE):
- slot := common.Hash(stackData[stackLen-1].Bytes32())
- t.lookupStorage(caller, slot)
- case stackLen >= 1 && (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT):
- addr := common.Address(stackData[stackLen-1].Bytes20())
- t.lookupAccount(addr)
- if op == vm.SELFDESTRUCT {
- t.deleted[caller] = true
- }
- case stackLen >= 5 && (op == vm.DELEGATECALL || op == vm.CALL || op == vm.STATICCALL || op == vm.CALLCODE):
- addr := common.Address(stackData[stackLen-2].Bytes20())
- t.lookupAccount(addr)
- case op == vm.CREATE:
- nonce := t.env.StateDB.GetNonce(caller)
- addr := crypto.CreateAddress(caller, nonce)
- t.lookupAccount(addr)
- t.created[addr] = true
- case stackLen >= 4 && op == vm.CREATE2:
- offset := stackData[stackLen-2]
- size := stackData[stackLen-3]
- init, err := tracers.GetMemoryCopyPadded(scope.Memory, int64(offset.Uint64()), int64(size.Uint64()))
- if err != nil {
- log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "prestateTracer", "offset", offset, "size", size)
- return
- }
- inithash := crypto.Keccak256(init)
- salt := stackData[stackLen-4]
- addr := crypto.CreateAddress2(caller, salt.Bytes32(), inithash)
- t.lookupAccount(addr)
- t.created[addr] = true
- }
-}
-
-func (t *prestateTracer) CaptureTxStart(gasLimit uint64) {
- t.gasLimit = gasLimit
-}
-
-func (t *prestateTracer) CaptureTxEnd(restGas uint64) {
- if !t.config.DiffMode {
- return
- }
-
- for addr, state := range t.pre {
- // The deleted account's state is pruned from `post` but kept in `pre`
- if _, ok := t.deleted[addr]; ok {
- continue
- }
- modified := false
- postAccount := &account{Storage: make(map[common.Hash]common.Hash)}
- newBalance := t.env.StateDB.GetBalance(addr)
- newNonce := t.env.StateDB.GetNonce(addr)
- newCode := t.env.StateDB.GetCode(addr)
-
- if newBalance.Cmp(t.pre[addr].Balance) != 0 {
- modified = true
- postAccount.Balance = newBalance
- }
- if newNonce != t.pre[addr].Nonce {
- modified = true
- postAccount.Nonce = newNonce
- }
- if !bytes.Equal(newCode, t.pre[addr].Code) {
- modified = true
- postAccount.Code = newCode
- }
-
- for key, val := range state.Storage {
- // don't include the empty slot
- if val == (common.Hash{}) {
- delete(t.pre[addr].Storage, key)
- }
-
- newVal := t.env.StateDB.GetState(addr, key)
- if val == newVal {
- // Omit unchanged slots
- delete(t.pre[addr].Storage, key)
- } else {
- modified = true
- if newVal != (common.Hash{}) {
- postAccount.Storage[key] = newVal
- }
- }
- }
-
- if modified {
- t.post[addr] = postAccount
- } else {
- // if state is not modified, then no need to include into the pre state
- delete(t.pre, addr)
- }
- }
- // the new created contracts' prestate were empty, so delete them
- for a := range t.created {
- // the created contract maybe exists in statedb before the creating tx
- if s := t.pre[a]; s != nil && !s.exists() {
- delete(t.pre, a)
- }
- }
-}
-
-// GetResult returns the json-encoded nested list of call traces, and any
-// error arising from the encoding or forceful termination (via `Stop`).
-func (t *prestateTracer) GetResult() (json.RawMessage, error) {
- var res []byte
- var err error
- if t.config.DiffMode {
- res, err = json.Marshal(struct {
- Post state `json:"post"`
- Pre state `json:"pre"`
- }{t.post, t.pre})
- } else {
- res, err = json.Marshal(t.pre)
- }
- if err != nil {
- return nil, err
- }
- return json.RawMessage(res), t.reason
-}
-
-// Stop terminates execution of the tracer at the first opportune moment.
-func (t *prestateTracer) Stop(err error) {
- t.reason = err
- t.interrupt.Store(true)
-}
-
-// lookupAccount fetches details of an account and adds it to the prestate
-// if it doesn't exist there.
-func (t *prestateTracer) lookupAccount(addr common.Address) {
- if _, ok := t.pre[addr]; ok {
- return
- }
-
- t.pre[addr] = &account{
- Balance: t.env.StateDB.GetBalance(addr),
- Nonce: t.env.StateDB.GetNonce(addr),
- Code: t.env.StateDB.GetCode(addr),
- Storage: make(map[common.Hash]common.Hash),
- }
-}
-
-// lookupStorage fetches the requested storage slot and adds
-// it to the prestate of the given contract. It assumes `lookupAccount`
-// has been performed on the contract before.
-func (t *prestateTracer) lookupStorage(addr common.Address, key common.Hash) {
- if _, ok := t.pre[addr].Storage[key]; ok {
- return
- }
- t.pre[addr].Storage[key] = t.env.StateDB.GetState(addr, key)
-}
diff --git a/eth/tracers/tracers.go b/eth/tracers/tracers.go
deleted file mode 100644
index 7b43b7cf83..0000000000
--- a/eth/tracers/tracers.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2017 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 tracers is a manager for transaction tracing engines.
-package tracers
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm"
-)
-
-// Context contains some contextual infos for a transaction execution that is not
-// available from within the EVM object.
-type Context struct {
- BlockHash common.Hash // Hash of the block the tx is contained within (zero if dangling tx or call)
- BlockNumber *big.Int // Number of the block the tx is contained within (zero if dangling tx or call)
- TxIndex int // Index of the transaction within a block (zero if dangling tx or call)
- TxHash common.Hash // Hash of the transaction being traced (zero if dangling call)
-}
-
-// Tracer interface extends vm.EVMLogger and additionally
-// allows collecting the tracing result.
-type Tracer interface {
- vm.EVMLogger
- GetResult() (json.RawMessage, error)
- // Stop terminates execution of the tracer at the first opportune moment.
- Stop(err error)
-}
-
-type ctorFn func(*Context, json.RawMessage) (Tracer, error)
-type jsCtorFn func(string, *Context, json.RawMessage) (Tracer, error)
-
-type elem struct {
- ctor ctorFn
- isJS bool
-}
-
-// DefaultDirectory is the collection of tracers bundled by default.
-var DefaultDirectory = directory{elems: make(map[string]elem)}
-
-// directory provides functionality to lookup a tracer by name
-// and a function to instantiate it. It falls back to a JS code evaluator
-// if no tracer of the given name exists.
-type directory struct {
- elems map[string]elem
- jsEval jsCtorFn
-}
-
-// Register registers a method as a lookup for tracers, meaning that
-// users can invoke a named tracer through that lookup.
-func (d *directory) Register(name string, f ctorFn, isJS bool) {
- d.elems[name] = elem{ctor: f, isJS: isJS}
-}
-
-// RegisterJSEval registers a tracer that is able to parse
-// dynamic user-provided JS code.
-func (d *directory) RegisterJSEval(f jsCtorFn) {
- d.jsEval = f
-}
-
-// New returns a new instance of a tracer, by iterating through the
-// registered lookups. Name is either name of an existing tracer
-// or an arbitrary JS code.
-func (d *directory) New(name string, ctx *Context, cfg json.RawMessage) (Tracer, error) {
- if elem, ok := d.elems[name]; ok {
- return elem.ctor(ctx, cfg)
- }
- // Assume JS code
- return d.jsEval(name, ctx, cfg)
-}
-
-// IsJS will return true if the given tracer will evaluate
-// JS code. Because code evaluation has high overhead, this
-// info will be used in determining fast and slow code paths.
-func (d *directory) IsJS(name string) bool {
- if elem, ok := d.elems[name]; ok {
- return elem.isJS
- }
- // JS eval will execute JS code
- return true
-}
-
-const (
- memoryPadLimit = 1024 * 1024
-)
-
-// GetMemoryCopyPadded returns offset + size as a new slice.
-// It zero-pads the slice if it extends beyond memory bounds.
-func GetMemoryCopyPadded(m *vm.Memory, offset, size int64) ([]byte, error) {
- if offset < 0 || size < 0 {
- return nil, errors.New("offset or size must not be negative")
- }
- if int(offset+size) < m.Len() { // slice fully inside memory
- return m.GetCopy(offset, size), nil
- }
- paddingNeeded := int(offset+size) - m.Len()
- if paddingNeeded > memoryPadLimit {
- return nil, fmt.Errorf("reached limit for padding memory slice: %d", paddingNeeded)
- }
- cpy := make([]byte, size)
- if overlap := int64(m.Len()) - offset; overlap > 0 {
- copy(cpy, m.GetPtr(offset, overlap))
- }
- return cpy, nil
-}
diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go
deleted file mode 100644
index b4989ec984..0000000000
--- a/eth/tracers/tracers_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2017 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 tracers
-
-import (
- "math/big"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "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/eth/tracers/logger"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/tests"
-)
-
-func BenchmarkTransactionTrace(b *testing.B) {
- key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
- from := crypto.PubkeyToAddress(key.PublicKey)
- gas := uint64(1000000) // 1M gas
- to := common.HexToAddress("0x00000000000000000000000000000000deadbeef")
- signer := types.LatestSignerForChainID(big.NewInt(1337))
- tx, err := types.SignNewTx(key, signer,
- &types.LegacyTx{
- Nonce: 1,
- GasPrice: big.NewInt(500),
- Gas: gas,
- To: &to,
- })
- if err != nil {
- b.Fatal(err)
- }
- txContext := vm.TxContext{
- Origin: from,
- GasPrice: tx.GasPrice(),
- }
- context := vm.BlockContext{
- CanTransfer: core.CanTransfer,
- Transfer: core.Transfer,
- Coinbase: common.Address{},
- BlockNumber: new(big.Int).SetUint64(uint64(5)),
- Time: 5,
- Difficulty: big.NewInt(0xffffffff),
- GasLimit: gas,
- BaseFee: big.NewInt(8),
- }
- alloc := core.GenesisAlloc{}
- // The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns
- // the address
- loop := []byte{
- byte(vm.JUMPDEST), // [ count ]
- byte(vm.PUSH1), 0, // jumpdestination
- byte(vm.JUMP),
- }
- alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = core.GenesisAccount{
- Nonce: 1,
- Code: loop,
- Balance: big.NewInt(1),
- }
- alloc[from] = core.GenesisAccount{
- Nonce: 1,
- Code: []byte{},
- Balance: big.NewInt(500000000000000),
- }
- triedb, _, statedb := tests.MakePreState(rawdb.NewMemoryDatabase(), alloc, false, rawdb.HashScheme)
- defer triedb.Close()
-
- // Create the tracer, the EVM environment and run it
- tracer := logger.NewStructLogger(&logger.Config{
- Debug: false,
- //DisableStorage: true,
- //EnableMemory: false,
- //EnableReturnData: false,
- })
- evm := vm.NewEVM(context, txContext, statedb, params.AllEthashProtocolChanges, vm.Config{Tracer: tracer})
- msg, err := core.TransactionToMessage(tx, signer, nil)
- if err != nil {
- b.Fatalf("failed to prepare transaction for tracing: %v", err)
- }
- b.ResetTimer()
- b.ReportAllocs()
-
- for i := 0; i < b.N; i++ {
- snap := statedb.Snapshot()
- st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
- _, err = st.TransitionDb()
- if err != nil {
- b.Fatal(err)
- }
- statedb.RevertToSnapshot(snap)
- if have, want := len(tracer.StructLogs()), 244752; have != want {
- b.Fatalf("trace wrong, want %d steps, have %d", want, have)
- }
- tracer.Reset()
- }
-}
-
-func TestMemCopying(t *testing.T) {
- for i, tc := range []struct {
- memsize int64
- offset int64
- size int64
- wantErr string
- wantSize int
- }{
- {0, 0, 100, "", 100}, // Should pad up to 100
- {0, 100, 0, "", 0}, // No need to pad (0 size)
- {100, 50, 100, "", 100}, // Should pad 100-150
- {100, 50, 5, "", 5}, // Wanted range fully within memory
- {100, -50, 0, "offset or size must not be negative", 0}, // Errror
- {0, 1, 1024*1024 + 1, "reached limit for padding memory slice: 1048578", 0}, // Errror
- {10, 0, 1024*1024 + 100, "reached limit for padding memory slice: 1048666", 0}, // Errror
-
- } {
- mem := vm.NewMemory()
- mem.Resize(uint64(tc.memsize))
- cpy, err := GetMemoryCopyPadded(mem, tc.offset, tc.size)
- if want := tc.wantErr; want != "" {
- if err == nil {
- t.Fatalf("test %d: want '%v' have no error", i, want)
- }
- if have := err.Error(); want != have {
- t.Fatalf("test %d: want '%v' have '%v'", i, want, have)
- }
- continue
- }
- if err != nil {
- t.Fatalf("test %d: unexpected error: %v", i, err)
- }
- if want, have := tc.wantSize, len(cpy); have != want {
- t.Fatalf("test %d: want %v have %v", i, want, have)
- }
- }
-}
diff --git a/eth/tracers/tracker.go b/eth/tracers/tracker.go
deleted file mode 100644
index 136be37f5c..0000000000
--- a/eth/tracers/tracker.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// 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 tracers
-
-import (
- "fmt"
- "sync"
-)
-
-// stateTracker is an auxiliary tool used to cache the release functions of all
-// used trace states, and to determine whether the creation of trace state needs
-// to be paused in case there are too many states waiting for tracing.
-type stateTracker struct {
- limit int // Maximum number of states allowed waiting for tracing
- oldest uint64 // The number of the oldest state which is still using for trace
- used []bool // List of flags indicating whether the trace state has been used up
- releases []StateReleaseFunc // List of trace state release functions waiting to be called
- cond *sync.Cond
- lock *sync.RWMutex
-}
-
-// newStateTracker initializes the tracker with provided state limits and
-// the number of the first state that will be used.
-func newStateTracker(limit int, oldest uint64) *stateTracker {
- lock := new(sync.RWMutex)
- return &stateTracker{
- limit: limit,
- oldest: oldest,
- used: make([]bool, limit),
- cond: sync.NewCond(lock),
- lock: lock,
- }
-}
-
-// releaseState marks the state specified by the number as released and caches
-// the corresponding release functions internally.
-func (t *stateTracker) releaseState(number uint64, release StateReleaseFunc) {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- // Set the state as used, the corresponding flag is indexed by
- // the distance between the specified state and the oldest state
- // which is still using for trace.
- t.used[int(number-t.oldest)] = true
-
- // If the oldest state is used up, update the oldest marker by moving
- // it to the next state which is not used up.
- if number == t.oldest {
- var count int
- for _, used := range t.used {
- if !used {
- break
- }
- count += 1
- }
- t.oldest += uint64(count)
- copy(t.used, t.used[count:])
-
- // Clean up the array tail since they are useless now.
- for i := t.limit - count; i < t.limit; i++ {
- t.used[i] = false
- }
- // Fire the signal to all waiters that oldest marker is updated.
- t.cond.Broadcast()
- }
- t.releases = append(t.releases, release)
-}
-
-// callReleases invokes all cached release functions.
-func (t *stateTracker) callReleases() {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- for _, release := range t.releases {
- release()
- }
- t.releases = t.releases[:0]
-}
-
-// wait blocks until the accumulated trace states are less than the limit.
-func (t *stateTracker) wait(number uint64) error {
- t.lock.Lock()
- defer t.lock.Unlock()
-
- for {
- if number < t.oldest {
- return fmt.Errorf("invalid state number %d head %d", number, t.oldest)
- }
- if number < t.oldest+uint64(t.limit) {
- // number is now within limit, wait over
- return nil
- }
- t.cond.Wait()
- }
-}
diff --git a/eth/tracers/tracker_test.go b/eth/tracers/tracker_test.go
deleted file mode 100644
index 46f6ac8e51..0000000000
--- a/eth/tracers/tracker_test.go
+++ /dev/null
@@ -1,171 +0,0 @@
-// 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 tracers
-
-import (
- "reflect"
- "testing"
- "time"
-)
-
-func TestTracker(t *testing.T) {
- var cases = []struct {
- limit int
- calls []uint64
- expHead uint64
- }{
- // Release in order
- {
- limit: 3,
- calls: []uint64{0, 1, 2},
- expHead: 3,
- },
- {
- limit: 3,
- calls: []uint64{0, 1, 2, 3, 4, 5},
- expHead: 6,
- },
-
- // Release out of order
- {
- limit: 3,
- calls: []uint64{1, 2, 0},
- expHead: 3,
- },
- {
- limit: 3,
- calls: []uint64{1, 2, 0, 5, 4, 3},
- expHead: 6,
- },
- }
- for _, c := range cases {
- tracker := newStateTracker(c.limit, 0)
- for _, call := range c.calls {
- tracker.releaseState(call, func() {})
- }
- tracker.lock.RLock()
- head := tracker.oldest
- tracker.lock.RUnlock()
-
- if head != c.expHead {
- t.Fatalf("Unexpected head want %d got %d", c.expHead, head)
- }
- }
-
- var calls = []struct {
- number uint64
- expUsed []bool
- expHead uint64
- }{
- // Release the first one, update the oldest flag
- {
- number: 0,
- expUsed: []bool{false, false, false, false, false},
- expHead: 1,
- },
- // Release the second one, oldest shouldn't be updated
- {
- number: 2,
- expUsed: []bool{false, true, false, false, false},
- expHead: 1,
- },
- // Release the forth one, oldest shouldn't be updated
- {
- number: 4,
- expUsed: []bool{false, true, false, true, false},
- expHead: 1,
- },
- // Release the first one, the first two should all be cleaned,
- // and the remaining flags should all be left-shifted.
- {
- number: 1,
- expUsed: []bool{false, true, false, false, false},
- expHead: 3,
- },
- // Release the first one, the first two should all be cleaned
- {
- number: 3,
- expUsed: []bool{false, false, false, false, false},
- expHead: 5,
- },
- }
- tracker := newStateTracker(5, 0) // limit = 5, oldest = 0
- for _, call := range calls {
- tracker.releaseState(call.number, nil)
- tracker.lock.RLock()
- if !reflect.DeepEqual(tracker.used, call.expUsed) {
- t.Fatalf("Unexpected used array")
- }
- if tracker.oldest != call.expHead {
- t.Fatalf("Unexpected head")
- }
- tracker.lock.RUnlock()
- }
-}
-
-func TestTrackerWait(t *testing.T) {
- var (
- tracker = newStateTracker(5, 0) // limit = 5, oldest = 0
- result = make(chan error, 1)
- doCall = func(number uint64) {
- go func() {
- result <- tracker.wait(number)
- }()
- }
- checkNoWait = func() {
- select {
- case <-result:
- return
- case <-time.NewTimer(time.Second).C:
- t.Fatal("No signal fired")
- }
- }
- checkWait = func() {
- select {
- case <-result:
- t.Fatal("Unexpected signal")
- case <-time.NewTimer(time.Millisecond * 100).C:
- }
- }
- )
- // States [0, 5) should all be available
- doCall(0)
- checkNoWait()
-
- doCall(4)
- checkNoWait()
-
- // State 5 is not available
- doCall(5)
- checkWait()
-
- // States [1, 6) are available
- tracker.releaseState(0, nil)
- checkNoWait()
-
- // States [1, 6) are available
- doCall(7)
- checkWait()
-
- // States [2, 7) are available
- tracker.releaseState(1, nil)
- checkWait()
-
- // States [3, 8) are available
- tracker.releaseState(2, nil)
- checkNoWait()
-}