From 85b292cbb3b898e540e70c0ebc7d50e056fb3e49 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 5 Jan 2024 15:25:22 +0800 Subject: [PATCH 1/9] Problem: block param is not aligned with go-ethereum in debug_traceCall --- CHANGELOG.md | 3 +- rpc/backend/tracing.go | 2 +- tests/integration_tests/test_tracers.py | 42 +++++++++++-------------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a68cfac2b..21d4bfa8bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,7 +69,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (config) [#365](https://github.com/crypto-org-chain/ethermint/pull/365) Avoid redundant parse chainID from gensis when start server. * (rpc) [#382](https://github.com/crypto-org-chain/ethermint/pull/382) Align tracer config with go-ethereum. * (rpc) [#386](https://github.com/crypto-org-chain/ethermint/pull/386) Cleanup unused cancel function in filter. - * (rpc) [#388](https://github.com/crypto-org-chain/ethermint/pull/388) Avoid out of bound panic when error message. +* (rpc) [#388](https://github.com/crypto-org-chain/ethermint/pull/388) Avoid out of bound panic when error message. +* (rpc) [#](https://github.com/crypto-org-chain/ethermint/pull/) Align block param with go-ethereum in debug_traceCall. ### Improvements diff --git a/rpc/backend/tracing.go b/rpc/backend/tracing.go index 2f7f821197..843a8d7d8e 100644 --- a/rpc/backend/tracing.go +++ b/rpc/backend/tracing.go @@ -246,7 +246,7 @@ func (b *Backend) TraceCall( } // minus one to get the context of block beginning - contextHeight := blk.Block.Height - 1 + contextHeight := blk.Block.Height if contextHeight < 1 { // 0 is a special value in `ContextWithHeight` contextHeight = 1 diff --git a/tests/integration_tests/test_tracers.py b/tests/integration_tests/test_tracers.py index 4c0c5e8537..1ed9d99f02 100644 --- a/tests/integration_tests/test_tracers.py +++ b/tests/integration_tests/test_tracers.py @@ -425,32 +425,26 @@ def test_debug_tracecall_state_overrides(ethermint_rpc_ws): assert tx_res[address.lower()]["balance"] == balance -def test_debug_tracecall_return_revert_data_when_call_failed(ethermint): - w3: Web3 = ethermint.w3 - eth_rpc = w3.provider - - test_revert, _ = deploy_contract( - w3, - CONTRACTS["TestRevert"], - ) - - w3_wait_for_new_blocks(w3, 1, sleep=0.1) +def test_debug_tracecall_return_revert_data_when_call_failed(ethermint, geth): + expected = "08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a46756e6374696f6e20686173206265656e207265766572746564000000000000" # noqa: E501 - tx_res = eth_rpc.make_request( - "debug_traceCall", - [ - { + def process(w3): + test_revert, _ = deploy_contract(w3, CONTRACTS["TestRevert"]) + tx_res = w3.provider.make_request( + "debug_traceCall", [{ "value": "0x0", "to": test_revert.address, "from": ADDRS["validator"], "data": "0x9ffb86a5", - }, - "latest", - ], - ) - assert "result" in tx_res - tx_res = tx_res["result"] - assert ( - tx_res["returnValue"] - == "08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a46756e6374696f6e20686173206265656e207265766572746564000000000000" # noqa: E501 - ) + }, "latest"] + ) + assert "result" in tx_res + tx_res = tx_res["result"] + return tx_res["returnValue"] + + providers = [ethermint.w3, geth.w3] + with ThreadPoolExecutor(len(providers)) as exec: + tasks = [exec.submit(process, w3) for w3 in providers] + res = [future.result() for future in as_completed(tasks)] + assert len(res) == len(providers) + assert (res[0] == res[-1] == expected), res From 6a4eb84a30ee294503634ae8082ea8350fcda217 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 5 Jan 2024 15:21:40 +0800 Subject: [PATCH 2/9] test_tracecall_insufficient_funds --- tests/integration_tests/test_tracers.py | 127 ++++++++++++------------ tests/integration_tests/utils.py | 5 + 2 files changed, 67 insertions(+), 65 deletions(-) diff --git a/tests/integration_tests/test_tracers.py b/tests/integration_tests/test_tracers.py index 1ed9d99f02..13ffd962e4 100644 --- a/tests/integration_tests/test_tracers.py +++ b/tests/integration_tests/test_tracers.py @@ -14,7 +14,7 @@ ADDRS, CONTRACTS, deploy_contract, - derive_new_account, + derive_random_account, send_transaction, w3_wait_for_new_blocks, ) @@ -47,13 +47,18 @@ def test_trace_transactions_tracers(ethermint_rpc_ws): assert tx_res["result"] == EXPECTED_CONTRACT_CREATE_TRACER, "" -def test_crosscheck(ethermint, geth): +def fund_acc(w3, acc): + fund = 3000000000000000000 + addr = acc.address + if w3.eth.get_balance(addr, "latest") == 0: + tx = {"to": addr, "value": fund, "gasPrice": w3.eth.gas_price} + send_transaction(w3, tx) + assert w3.eth.get_balance(addr, "latest") == fund + + +def test_trace_tx(ethermint, geth): method = "debug_traceTransaction" tracer = {"tracer": "callTracer"} - acc = derive_new_account(4) - sender = acc.address - # fund new sender to deploy contract with same address - fund = 3000000000000000000 tracers = [ [], [tracer], @@ -62,11 +67,11 @@ def test_crosscheck(ethermint, geth): [tracer | {"tracerConfig": {"diffMode": True}}], ] iterations = 1 + acc = derive_random_account() def process(w3): - tx = {"to": sender, "value": fund, "gasPrice": w3.eth.gas_price} - send_transaction(w3, tx) - assert w3.eth.get_balance(sender, "latest") == fund + # fund new sender to deploy contract with same address + fund_acc(w3, acc) contract, _ = deploy_contract(w3, CONTRACTS["TestMessageCall"], key=acc.key) tx = contract.functions.test(iterations).build_transaction() tx_hash = send_transaction(w3, tx)["transactionHash"].hex() @@ -86,64 +91,56 @@ def process(w3): assert res[0] == res[1], res -def test_tracecall_insufficient_funds(ethermint_rpc_ws): - w3: Web3 = ethermint_rpc_ws.w3 - eth_rpc = w3.provider - gas_price = w3.eth.gas_price - - # Insufficient funds - tx = { - # an non-exist address - "from": "0x1000000000000000000000000000000000000000", - "to": ADDRS["community"], - "value": hex(100), - "gasPrice": hex(gas_price), - "gas": hex(21000), - } - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "prestateTracer"}] - ) - assert "error" in tx_res - assert tx_res["error"] == { - "code": -32000, - "message": "rpc error: code = Internal desc = insufficient balance for transfer", # noqa: E501 - }, "" - - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "callTracer"}] - ) - assert "error" in tx_res - assert tx_res["error"] == { - "code": -32000, - "message": "rpc error: code = Internal desc = insufficient balance for transfer", # noqa: #E501 - }, "" - - from_addr = ADDRS["validator"] - to_addr = ADDRS["community"] - tx = { - "from": from_addr, - "to": to_addr, - "value": hex(100), - "gas": hex(21000), - } - - tx_res = eth_rpc.make_request("debug_traceCall", [tx, "latest"]) - assert tx_res["result"] == EXPECTED_STRUCT_TRACER, "" +def test_tracecall_insufficient_funds(ethermint, geth): + method = "debug_traceCall" + acc = derive_random_account() + sender = acc.address + receiver = ADDRS["community"] + value = hex(100) + gas = hex(21000) - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "callTracer"}] - ) - assert tx_res["result"] == EXPECTED_CALLTRACERS, "" + def process(w3): + fund_acc(w3, acc) + # Insufficient funds + tx = { + # an non-exist address + "from": "0x1000000000000000000000000000000000000000", + "to": receiver, + "value": value, + "gasPrice": hex(w3.eth.gas_price), + "gas": gas, + } + call = w3.provider.make_request + tracers = ["prestateTracer", "callTracer"] + with ThreadPoolExecutor(len(tracers)) as exec: + params = [([tx, "latest", {"tracer": tracer}]) for tracer in tracers] + for resp in exec.map(call, itertools.repeat(method), params): + assert "error" in resp + assert "insufficient" in resp["error"]["message"], resp["error"] + + tx = {"from": sender, "to": receiver, "value": value, "gas": gas} + tracer = {"tracer": "callTracer"} + tracers = [ + [], + [tracer], + [tracer | {"tracerConfig": {"onlyTopCall": True}}], + ] + res = [] + with ThreadPoolExecutor(len(tracers)) as exec: + params = [([tx, "latest"] + cfg) for cfg in tracers] + exec_map = exec.map(call, itertools.repeat(method), params) + res = [json.dumps(resp["result"], sort_keys=True) for resp in exec_map] + return res - tx_res = eth_rpc.make_request( - "debug_traceCall", - [ - tx, - "latest", - {"tracer": "callTracer", "tracerConfig": {'onlyTopCall': True}}, - ], - ) - assert tx_res["result"] == EXPECTED_CALLTRACERS, "" + providers = [ethermint.w3, geth.w3] + expected = json.dumps(EXPECTED_CALLTRACERS | {"from": sender.lower()}) + with ThreadPoolExecutor(len(providers)) as exec: + tasks = [exec.submit(process, w3) for w3 in providers] + res = [future.result() for future in as_completed(tasks)] + assert len(res) == len(providers) + assert (res[0] == res[1] == [ + json.dumps(EXPECTED_STRUCT_TRACER), expected, expected, + ]), res def test_js_tracers(ethermint): diff --git a/tests/integration_tests/utils.py b/tests/integration_tests/utils.py index 4d3df4f76c..4b9a75ab21 100644 --- a/tests/integration_tests/utils.py +++ b/tests/integration_tests/utils.py @@ -1,6 +1,7 @@ import json import os import re +import secrets import socket import subprocess import sys @@ -237,6 +238,10 @@ def derive_new_account(n=1): return Account.from_mnemonic(mnemonic, account_path=account_path) +def derive_random_account(): + return derive_new_account(secrets.randbelow(10000) + 1) + + def send_raw_transactions(w3, raw_transactions): with ThreadPoolExecutor(len(raw_transactions)) as exec: tasks = [ From 3559e06d0e73b036eaf3c43fdee7d2d8d2a45a62 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 5 Jan 2024 15:23:47 +0800 Subject: [PATCH 3/9] test_debug_tracecall_call_tracer --- tests/integration_tests/expected_constants.py | 2 + tests/integration_tests/test_tracers.py | 75 +++++++++---------- 2 files changed, 36 insertions(+), 41 deletions(-) diff --git a/tests/integration_tests/expected_constants.py b/tests/integration_tests/expected_constants.py index cc491d167a..7109a896bb 100644 --- a/tests/integration_tests/expected_constants.py +++ b/tests/integration_tests/expected_constants.py @@ -159,3 +159,5 @@ "type": "CREATE", "value": "0x0", } + +EXPECTED_DEFAULT_GASCAP = 25000000 diff --git a/tests/integration_tests/test_tracers.py b/tests/integration_tests/test_tracers.py index 13ffd962e4..52f4d7638a 100644 --- a/tests/integration_tests/test_tracers.py +++ b/tests/integration_tests/test_tracers.py @@ -7,6 +7,7 @@ from .expected_constants import ( EXPECTED_CALLTRACERS, EXPECTED_CONTRACT_CREATE_TRACER, + EXPECTED_DEFAULT_GASCAP, EXPECTED_STRUCT_TRACER, ) from .network import Ethermint @@ -339,55 +340,47 @@ def test_tracecall_prestate_tracer(ethermint: Ethermint): } -def test_debug_tracecall_call_tracer(ethermint_rpc_ws): - w3: Web3 = ethermint_rpc_ws.w3 - eth_rpc = w3.provider - - tx = { - "from": ADDRS["signer1"], - "to": ADDRS["signer2"], - "value": hex(1), - "gas": hex(21000), - } +def test_debug_tracecall_call_tracer(ethermint, geth): + method = "debug_traceCall" + acc = derive_random_account() + sender = acc.address + receiver = ADDRS["signer2"] - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "callTracer"}] - ) + def process(w3, gas): + fund_acc(w3, acc) + tx = {"from": sender, "to": receiver, "value": hex(1)} + if gas is not None: + # set gas limit in tx + tx["gas"] = hex(gas) + tx_res = w3.provider.make_request( + method, [tx, "latest", {"tracer": "callTracer"}], + ) + assert "result" in tx_res + return tx_res["result"] - assert "result" in tx_res - assert tx_res["result"] == { + providers = [ethermint.w3, geth.w3] + gas = 21000 + expected = { "type": "CALL", - "from": ADDRS["signer1"].lower(), - "to": ADDRS["signer2"].lower(), + "from": sender.lower(), + "to": receiver.lower(), "value": hex(1), - "gas": hex(21000), - "gasUsed": hex(21000), + "gas": hex(gas), + "gasUsed": hex(gas), "input": "0x", } + with ThreadPoolExecutor(len(providers)) as exec: + tasks = [exec.submit(process, w3, gas) for w3 in providers] + res = [future.result() for future in as_completed(tasks)] + assert len(res) == len(providers) + assert (res[0] == res[-1] == expected), res # no gas limit set in tx - tx = { - "from": ADDRS["signer1"], - "to": ADDRS["signer2"], - "value": hex(1), - } - - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "callTracer"}] - ) - - gas_cap = 25000000 - - assert "result" in tx_res - assert tx_res["result"] == { - "type": "CALL", - "from": ADDRS["signer1"].lower(), - "to": ADDRS["signer2"].lower(), - "value": hex(1), - "gas": hex(gas_cap), - "gasUsed": hex(int(gas_cap / 2)), - "input": "0x", - } + res = process(ethermint.w3, None) + assert res == expected | { + "gas": hex(EXPECTED_DEFAULT_GASCAP), + "gasUsed": hex(int(EXPECTED_DEFAULT_GASCAP / 2)), + }, res def test_debug_tracecall_state_overrides(ethermint_rpc_ws): From 7a471cb0ad8a69790726d8f80e634a2438f6b82f Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 5 Jan 2024 15:24:17 +0800 Subject: [PATCH 4/9] test_debug_tracecall_state_overrides --- tests/integration_tests/test_tracers.py | 53 +++++++++++++------------ 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/tests/integration_tests/test_tracers.py b/tests/integration_tests/test_tracers.py index 52f4d7638a..39efe3c514 100644 --- a/tests/integration_tests/test_tracers.py +++ b/tests/integration_tests/test_tracers.py @@ -383,36 +383,37 @@ def process(w3, gas): }, res -def test_debug_tracecall_state_overrides(ethermint_rpc_ws): - w3: Web3 = ethermint_rpc_ws.w3 - eth_rpc = w3.provider - - # generate random address, set balance in stateOverrides, - # use prestateTracer to check balance +def test_debug_tracecall_state_overrides(ethermint, geth): balance = "0xffffffff" - address = w3.eth.account.create().address - - tx = { - "from": address, - "to": ADDRS["signer2"], - "value": hex(1), - } - - config = { - "tracer": "prestateTracer", - "stateOverrides": { - address: { - "balance": balance, + def process(w3): + # generate random address, set balance in stateOverrides, + # use prestateTracer to check balance + address = w3.eth.account.create().address + tx = { + "from": address, + "to": ADDRS["signer2"], + "value": hex(1), + } + config = { + "tracer": "prestateTracer", + "stateOverrides": { + address: { + "balance": balance, + }, }, - }, - } - - tx_res = eth_rpc.make_request("debug_traceCall", [tx, "latest", config]) + } + tx_res = w3.provider.make_request("debug_traceCall", [tx, "latest", config]) + assert "result" in tx_res + tx_res = tx_res["result"] + return tx_res[address.lower()]["balance"] - assert "result" in tx_res - tx_res = tx_res["result"] - assert tx_res[address.lower()]["balance"] == balance + providers = [ethermint.w3, geth.w3] + with ThreadPoolExecutor(len(providers)) as exec: + tasks = [exec.submit(process, w3) for w3 in providers] + res = [future.result() for future in as_completed(tasks)] + assert len(res) == len(providers) + assert (res[0] == res[-1] == balance), res def test_debug_tracecall_return_revert_data_when_call_failed(ethermint, geth): From 82531ee5a4a147094bd7e7b79c27c69ac4d9f8db Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 5 Jan 2024 18:04:36 +0800 Subject: [PATCH 5/9] test_tracecall_struct_tracer --- tests/integration_tests/test_tracers.py | 56 +++++++++++-------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/tests/integration_tests/test_tracers.py b/tests/integration_tests/test_tracers.py index 39efe3c514..6346176059 100644 --- a/tests/integration_tests/test_tracers.py +++ b/tests/integration_tests/test_tracers.py @@ -10,7 +10,6 @@ EXPECTED_DEFAULT_GASCAP, EXPECTED_STRUCT_TRACER, ) -from .network import Ethermint from .utils import ( ADDRS, CONTRACTS, @@ -253,40 +252,35 @@ def test_custom_js_tracers(ethermint): assert tx_res[0] == "0:PUSH1" -def test_tracecall_struct_tracer(ethermint: Ethermint): - w3 = ethermint.w3 - eth_rpc = w3.provider +def test_tracecall_struct_tracer(ethermint, geth): + method = "debug_traceCall" + acc = derive_random_account() + sender = acc.address + receiver = ADDRS["signer2"] - # set gas limit in tx - from_addr = ADDRS["signer1"] - to_addr = ADDRS["signer2"] - tx = { - "from": from_addr, - "to": to_addr, - "value": hex(100), - "gas": hex(21000), - } + def process(w3, gas): + fund_acc(w3, acc) + tx = {"from": sender, "to": receiver, "value": hex(100)} + if gas is not None: + # set gas limit in tx + tx["gas"] = hex(gas) + tx_res = w3.provider.make_request(method, [tx, "latest"]) + assert "result" in tx_res + return tx_res["result"] - tx_res = eth_rpc.make_request("debug_traceCall", [tx, "latest"]) - assert tx_res["result"] == EXPECTED_STRUCT_TRACER, "" + providers = [ethermint.w3, geth.w3] + gas = 21000 + with ThreadPoolExecutor(len(providers)) as exec: + tasks = [exec.submit(process, w3, gas) for w3 in providers] + res = [future.result() for future in as_completed(tasks)] + assert len(res) == len(providers) + assert (res[0] == res[-1] == EXPECTED_STRUCT_TRACER), res # no gas limit set in tx - # default GasCap in ethermint - gas_cap = 25000000 - - tx = { - "from": from_addr, - "to": to_addr, - "value": hex(100), - } - - tx_res = eth_rpc.make_request("debug_traceCall", [tx, "latest"]) - assert tx_res["result"] == { - "failed": False, - "gas": gas_cap / 2, - "returnValue": "", - "structLogs": [], - } + res = process(ethermint.w3, None) + assert res == EXPECTED_STRUCT_TRACER | { + "gas": EXPECTED_DEFAULT_GASCAP / 2, + }, res def test_tracecall_prestate_tracer(ethermint: Ethermint): From ed18a4ea7d13727ea480c0c61c1579581e236a99 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 5 Jan 2024 18:16:56 +0800 Subject: [PATCH 6/9] test_custom_js_tracers --- tests/integration_tests/expected_constants.py | 2 + tests/integration_tests/test_tracers.py | 159 ++++++------------ 2 files changed, 56 insertions(+), 105 deletions(-) diff --git a/tests/integration_tests/expected_constants.py b/tests/integration_tests/expected_constants.py index 7109a896bb..6777108e79 100644 --- a/tests/integration_tests/expected_constants.py +++ b/tests/integration_tests/expected_constants.py @@ -161,3 +161,5 @@ } EXPECTED_DEFAULT_GASCAP = 25000000 + +EXPECTED_JS_TRACERS = ['{"ADD-ADD": 2, "ADD-AND": 1, "ADD-CALLDATACOPY": 1, "ADD-DUP2": 2, "ADD-DUP3": 1, "ADD-DUP5": 1, "ADD-GT": 1, "ADD-MLOAD": 1, "ADD-MSTORE": 2, "ADD-OR": 1, "ADD-PUSH1": 6, "ADD-PUSH2": 2, "ADD-SLT": 1, "ADD-SWAP1": 2, "ADD-SWAP2": 1, "ADD-SWAP3": 3, "AND-DUP1": 1, "AND-DUP2": 2, "AND-DUP4": 1, "AND-PUSH1": 1, "AND-SWAP2": 1, "AND-SWAP3": 1, "CALLDATACOPY-PUSH1": 1, "CALLDATALOAD-DUP2": 1, "CALLDATALOAD-PUSH1": 1, "CALLDATALOAD-PUSH8": 1, "CALLDATASIZE-LT": 1, "CALLDATASIZE-PUSH1": 1, "CALLER-DUP3": 1, "CALLVALUE-DUP1": 1, "DIV-DUP2": 1, "DUP1-ADD": 1, "DUP1-DUP3": 3, "DUP1-DUP5": 1, "DUP1-ISZERO": 1, "DUP1-MLOAD": 2, "DUP1-PUSH2": 1, "DUP1-PUSH4": 3, "DUP1-SLOAD": 1, "DUP1-SWAP2": 1, "DUP2-ADD": 4, "DUP2-AND": 1, "DUP2-CALLDATALOAD": 2, "DUP2-DUP2": 5, "DUP2-DUP4": 1, "DUP2-DUP5": 1, "DUP2-DUP6": 1, "DUP2-EQ": 1, "DUP2-GT": 2, "DUP2-LT": 2, "DUP2-MLOAD": 1, "DUP2-MSTORE": 2, "DUP2-PUSH1": 1, "DUP2-SHR": 1, "DUP2-SSTORE": 1, "DUP2-SWAP1": 1, "DUP3-ADD": 3, "DUP3-AND": 2, "DUP3-DUP1": 1, "DUP3-DUP2": 1, "DUP3-DUP5": 1, "DUP3-GT": 4, "DUP3-LT": 1, "DUP3-PUSH1": 3, "DUP3-PUSH2": 1, "DUP4-ADD": 4, "DUP4-AND": 1, "DUP4-DUP1": 1, "DUP4-DUP3": 1, "DUP4-DUP8": 1, "DUP4-LT": 1, "DUP5-ADD": 2, "DUP5-DUP8": 1, "DUP5-MSTORE": 1, "DUP5-PUSH1": 1, "DUP5-PUSH2": 1, "DUP5-SUB": 1, "DUP6-ADD": 1, "DUP6-SSTORE": 1, "DUP7-ADD": 1, "DUP7-DUP4": 1, "DUP8-ADD": 2, "DUP8-PUSH1": 1, "EQ-ISZERO": 1, "EQ-PUSH2": 3, "GT-DUP2": 1, "GT-ISZERO": 6, "ISZERO-PUSH2": 12, "JUMP-JUMPDEST": 17, "JUMPDEST-DUP1": 3, "JUMPDEST-DUP2": 7, "JUMPDEST-DUP3": 3, "JUMPDEST-JUMPDEST": 1, "JUMPDEST-POP": 7, "JUMPDEST-PUSH1": 7, "JUMPDEST-PUSH2": 2, "JUMPDEST-STOP": 1, "JUMPDEST-SWAP1": 1, "JUMPDEST-SWAP5": 1, "JUMPI-DUP1": 3, "JUMPI-JUMPDEST": 12, "JUMPI-PUSH1": 5, "KECCAK256-SWAP1": 1, "LOG1-POP": 1, "LT-DUP2": 1, "LT-ISZERO": 2, "LT-OR": 1, "LT-PUSH2": 2, "MLOAD-DUP1": 2, "MLOAD-DUP7": 1, "MLOAD-PUSH1": 2, "MLOAD-PUSH2": 2, "MSTORE-ADD": 1, "MSTORE-CALLVALUE": 1, "MSTORE-DUP3": 1, "MSTORE-DUP8": 1, "MSTORE-JUMPDEST": 1, "MSTORE-POP": 1, "MSTORE-PUSH1": 4, "NOT-AND": 2, "NOT-SWAP1": 1, "OR-DUP6": 1, "OR-ISZERO": 1, "POP-DUP5": 1, "POP-JUMP": 5, "POP-JUMPDEST": 1, "POP-POP": 8, "POP-PUSH1": 2, "POP-PUSH2": 2, "POP-PUSH32": 1, "POP-SWAP1": 2, "POP-SWAP2": 1, "POP-SWAP6": 1, "PUSH1-ADD": 6, "PUSH1-CALLDATALOAD": 1, "PUSH1-CALLDATASIZE": 1, "PUSH1-DUP2": 4, "PUSH1-DUP3": 5, "PUSH1-DUP4": 3, "PUSH1-DUP5": 2, "PUSH1-DUP7": 1, "PUSH1-JUMPDEST": 1, "PUSH1-KECCAK256": 1, "PUSH1-LT": 1, "PUSH1-MLOAD": 3, "PUSH1-MSTORE": 3, "PUSH1-NOT": 3, "PUSH1-PUSH1": 7, "PUSH1-PUSH2": 1, "PUSH1-SHL": 1, "PUSH1-SHR": 1, "PUSH1-SWAP1": 3, "PUSH1-SWAP3": 1, "PUSH2-CALLDATASIZE": 1, "PUSH2-JUMP": 10, "PUSH2-JUMPI": 20, "PUSH2-PUSH2": 1, "PUSH2-SWAP1": 3, "PUSH2-SWAP3": 2, "PUSH32-CALLER": 1, "PUSH4-EQ": 3, "PUSH8-DUP1": 1, "SHL-SUB": 1, "SHR-DUP1": 1, "SHR-SWAP1": 1, "SLOAD-PUSH2": 1, "SLT-ISZERO": 1, "SLT-PUSH2": 1, "SSTORE-PUSH1": 1, "SSTORE-PUSH2": 1, "SUB-DUP4": 1, "SUB-SLT": 1, "SUB-SWAP1": 1, "SWAP1-DIV": 1, "SWAP1-DUP2": 1, "SWAP1-DUP3": 1, "SWAP1-DUP4": 2, "SWAP1-JUMP": 2, "SWAP1-LOG1": 1, "SWAP1-MSTORE": 1, "SWAP1-POP": 1, "SWAP1-PUSH1": 4, "SWAP1-PUSH2": 4, "SWAP1-SWAP3": 2, "SWAP2-POP": 4, "SWAP2-SUB": 1, "SWAP2-SWAP1": 2, "SWAP3-ADD": 1, "SWAP3-DUP2": 1, "SWAP3-DUP3": 1, "SWAP3-MSTORE": 1, "SWAP3-SWAP1": 2, "SWAP3-SWAP2": 3, "SWAP4-POP": 1, "SWAP5-POP": 1, "SWAP5-SWAP4": 1, "SWAP6-SWAP5": 1}', '[{"depth": 1, "len": 2, "op": 96, "result": ["80"]}, {"depth": 1, "len": 2, "op": 96, "result": ["40"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "op": 52, "result": ["0"]}, {"depth": 1, "op": 128, "result": ["0", "0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["10"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 16, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["4"]}, {"depth": 1, "op": 54, "result": ["64"]}, {"depth": 1, "op": 16, "result": ["0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["57"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "op": 53, "result": ["a413686200000000000000000000000000000000000000000000000000000000"]}, {"depth": 1, "len": 2, "op": 96, "result": ["e0"]}, {"depth": 1, "op": 28, "result": []}, {"depth": 1, "op": 128, "result": ["a4136862", "a4136862"]}, {"depth": 1, "len": 5, "op": 99, "result": ["c4dae88"]}, {"depth": 1, "op": 20, "result": ["0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["5c"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 128, "result": ["a4136862", "a4136862"]}, {"depth": 1, "len": 5, "op": 99, "result": ["2e52d606"]}, {"depth": 1, "op": 20, "result": ["0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["73"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 128, "result": ["a4136862", "a4136862"]}, {"depth": 1, "len": 5, "op": 99, "result": ["a4136862"]}, {"depth": 1, "op": 20, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["7c"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 124, "result": []}, {"depth": 1, "len": 3, "op": 97, "result": ["8f"]}, {"depth": 1, "len": 3, "op": 97, "result": ["8a"]}, {"depth": 1, "op": 54, "result": ["64"]}, {"depth": 1, "len": 2, "op": 96, "result": ["4"]}, {"depth": 1, "len": 3, "op": 97, "result": ["2cd"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 717, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 130, "result": ["4", "20", "0", "4"]}, {"depth": 1, "op": 132, "result": ["64", "4", "20", "0", "4", "64"]}, {"depth": 1, "op": 3, "result": ["60"]}, {"depth": 1, "op": 18, "result": ["0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["2df"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 735, "result": []}, {"depth": 1, "op": 129, "result": ["4", "0", "4"]}, {"depth": 1, "op": 53, "result": ["20"]}, {"depth": 1, "len": 9, "op": 103, "result": ["ffffffffffffffff"]}, {"depth": 1, "op": 128, "result": ["ffffffffffffffff", "ffffffffffffffff"]}, {"depth": 1, "op": 130, "result": ["20", "ffffffffffffffff", "ffffffffffffffff", "20"]}, {"depth": 1, "op": 17, "result": ["0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["2f7"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 759, "result": []}, {"depth": 1, "op": 129, "result": ["20", "ffffffffffffffff", "20"]}, {"depth": 1, "op": 132, "result": ["4", "20", "ffffffffffffffff", "20", "0", "4"]}, {"depth": 1, "op": 1, "result": ["24"]}, {"depth": 1, "op": 145, "result": ["20", "ffffffffffffffff", "24"]}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 132, "result": ["64", "ffffffffffffffff", "24", "0", "4", "64"]}, {"depth": 1, "len": 2, "op": 96, "result": ["1f"]}, {"depth": 1, "op": 131, "result": ["24", "1f", "64", "ffffffffffffffff", "24"]}, {"depth": 1, "op": 1, "result": ["43"]}, {"depth": 1, "op": 18, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["30b"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 779, "result": []}, {"depth": 1, "op": 129, "result": ["24", "ffffffffffffffff", "24"]}, {"depth": 1, "op": 53, "result": ["5"]}, {"depth": 1, "op": 129, "result": ["ffffffffffffffff", "5", "ffffffffffffffff"]}, {"depth": 1, "op": 129, "result": ["5", "ffffffffffffffff", "5"]}, {"depth": 1, "op": 17, "result": ["0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["31d"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 797, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["40"]}, {"depth": 1, "op": 81, "result": ["80"]}, {"depth": 1, "len": 2, "op": 96, "result": ["1f"]}, {"depth": 1, "op": 130, "result": ["5", "1f", "80", "5"]}, {"depth": 1, "op": 1, "result": ["24"]}, {"depth": 1, "len": 2, "op": 96, "result": ["1f"]}, {"depth": 1, "op": 25, "result": ["ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"]}, {"depth": 1, "op": 144, "result": ["24", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"]}, {"depth": 1, "op": 129, "result": ["ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0", "24", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"]}, {"depth": 1, "op": 22, "result": ["20"]}, {"depth": 1, "len": 2, "op": 96, "result": ["3f"]}, {"depth": 1, "op": 1, "result": ["5f"]}, {"depth": 1, "op": 22, "result": ["40"]}, {"depth": 1, "op": 129, "result": ["80", "40", "80"]}, {"depth": 1, "op": 1, "result": ["c0"]}, {"depth": 1, "op": 144, "result": ["80", "c0"]}, {"depth": 1, "op": 131, "result": ["ffffffffffffffff", "80", "c0", "5", "ffffffffffffffff"]}, {"depth": 1, "op": 130, "result": ["c0", "ffffffffffffffff", "80", "c0"]}, {"depth": 1, "op": 17, "result": ["0"]}, {"depth": 1, "op": 129, "result": ["80", "0", "80"]}, {"depth": 1, "op": 131, "result": ["c0", "80", "0", "80", "c0"]}, {"depth": 1, "op": 16, "result": ["0"]}, {"depth": 1, "op": 23, "result": ["0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["345"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 837, "result": []}, {"depth": 1, "op": 129, "result": ["c0", "80", "c0"]}, {"depth": 1, "len": 2, "op": 96, "result": ["40"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "op": 130, "result": ["5", "80", "c0", "5"]}, {"depth": 1, "op": 129, "result": ["80", "5", "80"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "op": 135, "result": ["64", "80", "c0", "5", "ffffffffffffffff", "24", "0", "4", "64"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 132, "result": ["5", "20", "64", "80", "c0", "5"]}, {"depth": 1, "op": 135, "result": ["24", "5", "20", "64", "80", "c0", "5", "ffffffffffffffff", "24"]}, {"depth": 1, "op": 1, "result": ["29"]}, {"depth": 1, "op": 1, "result": ["49"]}, {"depth": 1, "op": 17, "result": ["0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["35e"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 862, "result": []}, {"depth": 1, "op": 130, "result": ["5", "80", "c0", "5"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 134, "result": ["24", "20", "5", "80", "c0", "5", "ffffffffffffffff", "24"]}, {"depth": 1, "op": 1, "result": ["44"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 131, "result": ["80", "20", "44", "5", "80"]}, {"depth": 1, "op": 1, "result": ["a0"]}, {"depth": 1, "op": 55, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "op": 146, "result": ["5", "80", "c0", "0"]}, {"depth": 1, "op": 129, "result": ["80", "5", "80"]}, {"depth": 1, "op": 1, "result": ["85"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 1, "result": ["a5"]}, {"depth": 1, "op": 146, "result": ["0", "80", "c0", "a5"]}, {"depth": 1, "op": 144, "result": ["80", "0"]}, {"depth": 1, "op": 146, "result": ["a5", "0", "c0", "80"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 149, "result": ["8a", "ffffffffffffffff", "24", "0", "4", "64", "80"]}, {"depth": 1, "op": 148, "result": ["64", "ffffffffffffffff", "24", "0", "4", "8a"]}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 138, "result": []}, {"depth": 1, "len": 3, "op": 97, "result": ["ae"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 174, "result": []}, {"depth": 1, "op": 128, "result": ["80", "80"]}, {"depth": 1, "op": 81, "result": ["5"]}, {"depth": 1, "len": 3, "op": 97, "result": ["c1"]}, {"depth": 1, "op": 144, "result": ["5", "c1"]}, {"depth": 1, "len": 2, "op": 96, "result": ["1"]}, {"depth": 1, "op": 144, "result": ["5", "1"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 132, "result": ["80", "20", "5", "1", "c1", "80"]}, {"depth": 1, "op": 1, "result": ["a0"]}, {"depth": 1, "op": 144, "result": ["5", "a0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["21e"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 542, "result": []}, {"depth": 1, "op": 130, "result": ["1", "5", "a0", "1"]}, {"depth": 1, "op": 128, "result": ["1", "1"]}, {"depth": 1, "op": 84, "result": ["48656c6c6f00000000000000000000000000000000000000000000000000000a"]}, {"depth": 1, "len": 3, "op": 97, "result": ["22a"]}, {"depth": 1, "op": 144, "result": ["48656c6c6f00000000000000000000000000000000000000000000000000000a", "22a"]}, {"depth": 1, "len": 3, "op": 97, "result": ["411"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 1041, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["1"]}, {"depth": 1, "op": 129, "result": ["48656c6c6f00000000000000000000000000000000000000000000000000000a", "1", "48656c6c6f00000000000000000000000000000000000000000000000000000a"]}, {"depth": 1, "op": 129, "result": ["1", "48656c6c6f00000000000000000000000000000000000000000000000000000a", "1"]}, {"depth": 1, "op": 28, "result": []}, {"depth": 1, "op": 144, "result": ["1", "2432b63637800000000000000000000000000000000000000000000000000005"]}, {"depth": 1, "op": 130, "result": ["48656c6c6f00000000000000000000000000000000000000000000000000000a", "1", "2432b63637800000000000000000000000000000000000000000000000000005", "48656c6c6f00000000000000000000000000000000000000000000000000000a"]}, {"depth": 1, "op": 22, "result": ["0"]}, {"depth": 1, "op": 128, "result": ["0", "0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["425"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["7f"]}, {"depth": 1, "op": 130, "result": ["2432b63637800000000000000000000000000000000000000000000000000005", "7f", "0", "2432b63637800000000000000000000000000000000000000000000000000005"]}, {"depth": 1, "op": 22, "result": ["5"]}, {"depth": 1, "op": 145, "result": ["2432b63637800000000000000000000000000000000000000000000000000005", "0", "5"]}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 91, "pc": 1061, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 130, "result": ["5", "20", "0", "5"]}, {"depth": 1, "op": 16, "result": ["1"]}, {"depth": 1, "op": 129, "result": ["0", "1", "0"]}, {"depth": 1, "op": 20, "result": ["0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["446"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 1094, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 145, "result": ["22a", "48656c6c6f00000000000000000000000000000000000000000000000000000a", "5"]}, {"depth": 1, "op": 144, "result": ["48656c6c6f00000000000000000000000000000000000000000000000000000a", "22a"]}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 554, "result": []}, {"depth": 1, "op": 144, "result": ["1", "5"]}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "op": 32, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"]}, {"depth": 1, "op": 144, "result": ["5", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"]}, {"depth": 1, "len": 2, "op": 96, "result": ["1f"]}, {"depth": 1, "op": 1, "result": ["24"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 144, "result": ["24", "20"]}, {"depth": 1, "op": 4, "result": ["1"]}, {"depth": 1, "op": 129, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "1", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"]}, {"depth": 1, "op": 1, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"]}, {"depth": 1, "op": 146, "result": ["a0", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "5", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"]}, {"depth": 1, "op": 130, "result": ["5", "a0", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "5"]}, {"depth": 1, "len": 3, "op": 97, "result": ["24c"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 588, "result": []}, {"depth": 1, "op": 130, "result": ["5", "a0", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "5"]}, {"depth": 1, "len": 2, "op": 96, "result": ["1f"]}, {"depth": 1, "op": 16, "result": ["0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["265"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 128, "result": ["a0", "a0"]}, {"depth": 1, "op": 81, "result": ["776f726c64000000000000000000000000000000000000000000000000000000"]}, {"depth": 1, "len": 2, "op": 96, "result": ["ff"]}, {"depth": 1, "op": 25, "result": ["ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00"]}, {"depth": 1, "op": 22, "result": ["776f726c64000000000000000000000000000000000000000000000000000000"]}, {"depth": 1, "op": 131, "result": ["5", "776f726c64000000000000000000000000000000000000000000000000000000", "a0", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "5"]}, {"depth": 1, "op": 128, "result": ["5", "5"]}, {"depth": 1, "op": 1, "result": ["a"]}, {"depth": 1, "op": 23, "result": ["776f726c6400000000000000000000000000000000000000000000000000000a"]}, {"depth": 1, "op": 133, "result": ["1", "776f726c6400000000000000000000000000000000000000000000000000000a", "a0", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "5", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7", "1"]}, {"depth": 1, "op": 85, "result": []}, {"depth": 1, "len": 3, "op": 97, "result": ["292"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 658, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "len": 3, "op": 97, "result": ["29e"]}, {"depth": 1, "op": 146, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "5", "29e"]}, {"depth": 1, "op": 145, "result": ["5", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"]}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "len": 3, "op": 97, "result": ["2a2"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 674, "result": []}, {"depth": 1, "op": 91, "pc": 675, "result": []}, {"depth": 1, "op": 128, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"]}, {"depth": 1, "op": 130, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"]}, {"depth": 1, "op": 17, "result": ["1"]}, {"depth": 1, "op": 21, "result": ["0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["29e"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "op": 129, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", "0", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"]}, {"depth": 1, "op": 85, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["1"]}, {"depth": 1, "op": 1, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"]}, {"depth": 1, "len": 3, "op": 97, "result": ["2a3"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 675, "result": []}, {"depth": 1, "op": 128, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"]}, {"depth": 1, "op": 130, "result": ["b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"]}, {"depth": 1, "op": 17, "result": ["0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["29e"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 670, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 144, "result": ["29e", "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 670, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 144, "result": ["c1", "1"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 193, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "len": 33, "op": 127, "result": ["61ae4cbae83f72235cd9fa781d18fcb08ff5fa4a44fcc1630fde673bb0041151"]}, {"depth": 1, "op": 51, "result": ["b6a2f15a37aac3b6fdd39afa356b64f51ca8314a"]}, {"depth": 1, "op": 130, "result": ["80", "b6a2f15a37aac3b6fdd39afa356b64f51ca8314a", "61ae4cbae83f72235cd9fa781d18fcb08ff5fa4a44fcc1630fde673bb0041151", "80"]}, {"depth": 1, "len": 2, "op": 96, "result": ["40"]}, {"depth": 1, "op": 81, "result": ["c0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["f3"]}, {"depth": 1, "op": 146, "result": ["b6a2f15a37aac3b6fdd39afa356b64f51ca8314a", "c0", "80", "f3"]}, {"depth": 1, "op": 145, "result": ["80", "c0", "b6a2f15a37aac3b6fdd39afa356b64f51ca8314a"]}, {"depth": 1, "op": 144, "result": ["c0", "80"]}, {"depth": 1, "len": 3, "op": 97, "result": ["3e5"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 997, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["1"]}, {"depth": 1, "len": 2, "op": 96, "result": ["1"]}, {"depth": 1, "len": 2, "op": 96, "result": ["a0"]}, {"depth": 1, "op": 27, "result": []}, {"depth": 1, "op": 3, "result": ["ffffffffffffffffffffffffffffffffffffffff"]}, {"depth": 1, "op": 131, "result": ["b6a2f15a37aac3b6fdd39afa356b64f51ca8314a", "ffffffffffffffffffffffffffffffffffffffff", "c0", "80", "b6a2f15a37aac3b6fdd39afa356b64f51ca8314a"]}, {"depth": 1, "op": 22, "result": ["b6a2f15a37aac3b6fdd39afa356b64f51ca8314a"]}, {"depth": 1, "op": 129, "result": ["c0", "b6a2f15a37aac3b6fdd39afa356b64f51ca8314a", "c0"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["40"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 130, "result": ["c0", "20", "40", "c0"]}, {"depth": 1, "op": 1, "result": ["e0"]}, {"depth": 1, "op": 129, "result": ["40", "e0", "40"]}, {"depth": 1, "op": 144, "result": ["e0", "40"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "op": 144, "result": ["40", "0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["409"]}, {"depth": 1, "op": 144, "result": ["40", "409"]}, {"depth": 1, "op": 131, "result": ["c0", "40", "409", "0", "c0"]}, {"depth": 1, "op": 1, "result": ["100"]}, {"depth": 1, "op": 132, "result": ["80", "100", "409", "0", "c0", "80"]}, {"depth": 1, "len": 3, "op": 97, "result": ["37e"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 894, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "op": 129, "result": ["80", "0", "80"]}, {"depth": 1, "op": 81, "result": ["5"]}, {"depth": 1, "op": 128, "result": ["5", "5"]}, {"depth": 1, "op": 132, "result": ["100", "5", "5", "0", "80", "100"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "op": 91, "pc": 904, "result": []}, {"depth": 1, "op": 129, "result": ["5", "0", "5"]}, {"depth": 1, "op": 129, "result": ["0", "5", "0"]}, {"depth": 1, "op": 16, "result": ["1"]}, {"depth": 1, "op": 21, "result": ["0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["3a4"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 129, "result": ["0", "20", "0"]}, {"depth": 1, "op": 133, "result": ["80", "0", "20", "0", "5", "0", "80"]}, {"depth": 1, "op": 1, "result": ["80"]}, {"depth": 1, "op": 129, "result": ["20", "80", "20"]}, {"depth": 1, "op": 1, "result": ["a0"]}, {"depth": 1, "op": 81, "result": ["776f726c64000000000000000000000000000000000000000000000000000000"]}, {"depth": 1, "op": 134, "result": ["100", "776f726c64000000000000000000000000000000000000000000000000000000", "20", "0", "5", "0", "80", "100"]}, {"depth": 1, "op": 131, "result": ["0", "100", "776f726c64000000000000000000000000000000000000000000000000000000", "20", "0"]}, {"depth": 1, "op": 1, "result": ["100"]}, {"depth": 1, "op": 130, "result": ["20", "100", "776f726c64000000000000000000000000000000000000000000000000000000", "20"]}, {"depth": 1, "op": 1, "result": ["120"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "op": 1, "result": ["20"]}, {"depth": 1, "len": 3, "op": 97, "result": ["388"]}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 904, "result": []}, {"depth": 1, "op": 129, "result": ["5", "20", "5"]}, {"depth": 1, "op": 129, "result": ["20", "5", "20"]}, {"depth": 1, "op": 16, "result": ["0"]}, {"depth": 1, "op": 21, "result": ["1"]}, {"depth": 1, "len": 3, "op": 97, "result": ["3a4"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "op": 91, "pc": 932, "result": []}, {"depth": 1, "op": 129, "result": ["5", "20", "5"]}, {"depth": 1, "op": 129, "result": ["20", "5", "20"]}, {"depth": 1, "op": 17, "result": ["1"]}, {"depth": 1, "op": 21, "result": ["0"]}, {"depth": 1, "len": 3, "op": 97, "result": ["3b6"]}, {"depth": 1, "op": 87, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["0"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 131, "result": ["5", "20", "0", "20", "5"]}, {"depth": 1, "op": 135, "result": ["100", "5", "20", "0", "20", "5", "0", "80", "100"]}, {"depth": 1, "op": 1, "result": ["105"]}, {"depth": 1, "op": 1, "result": ["125"]}, {"depth": 1, "op": 82, "result": []}, {"depth": 1, "op": 91, "pc": 950, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["1f"]}, {"depth": 1, "op": 1, "result": ["24"]}, {"depth": 1, "len": 2, "op": 96, "result": ["1f"]}, {"depth": 1, "op": 25, "result": ["ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0"]}, {"depth": 1, "op": 22, "result": ["20"]}, {"depth": 1, "op": 146, "result": ["100", "0", "80", "20"]}, {"depth": 1, "op": 144, "result": ["0", "100"]}, {"depth": 1, "op": 146, "result": ["20", "100", "80", "0"]}, {"depth": 1, "op": 1, "result": ["120"]}, {"depth": 1, "len": 2, "op": 96, "result": ["20"]}, {"depth": 1, "op": 1, "result": ["140"]}, {"depth": 1, "op": 146, "result": ["409", "80", "0", "140"]}, {"depth": 1, "op": 145, "result": ["0", "80", "409"]}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 1033, "result": []}, {"depth": 1, "op": 148, "result": ["f3", "0", "c0", "80", "b6a2f15a37aac3b6fdd39afa356b64f51ca8314a", "140"]}, {"depth": 1, "op": 147, "result": ["b6a2f15a37aac3b6fdd39afa356b64f51ca8314a", "0", "c0", "80", "f3"]}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 243, "result": []}, {"depth": 1, "len": 2, "op": 96, "result": ["40"]}, {"depth": 1, "op": 81, "result": ["c0"]}, {"depth": 1, "op": 128, "result": ["c0", "c0"]}, {"depth": 1, "op": 145, "result": ["140", "c0", "c0"]}, {"depth": 1, "op": 3, "result": ["80"]}, {"depth": 1, "op": 144, "result": ["c0", "80"]}, {"depth": 1, "op": 161, "result": []}, {"depth": 1, "op": 80, "result": []}, {"depth": 1, "op": 86, "result": []}, {"depth": 1, "op": 91, "pc": 143, "result": []}, {"depth": 1, "op": 0, "result": []}]', '415', '{"--PUSH1": 1, "-PUSH1-MSTORE": 1, "ADD-ADD-GT": 1, "ADD-ADD-MSTORE": 1, "ADD-AND-DUP2": 1, "ADD-CALLDATACOPY-PUSH1": 1, "ADD-DUP2-ADD": 1, "ADD-DUP2-SWAP1": 1, "ADD-DUP3-ADD": 1, "ADD-DUP5-PUSH2": 1, "ADD-GT-ISZERO": 1, "ADD-MLOAD-DUP7": 1, "ADD-MSTORE-ADD": 1, "ADD-MSTORE-JUMPDEST": 1, "ADD-OR-DUP6": 1, "ADD-PUSH1-ADD": 2, "ADD-PUSH1-DUP4": 1, "ADD-PUSH1-NOT": 2, "ADD-PUSH1-SWAP1": 1, "ADD-PUSH2-JUMP": 2, "ADD-SLT-PUSH2": 1, "ADD-SWAP1-DUP4": 1, "ADD-SWAP1-PUSH2": 1, "ADD-SWAP2-POP": 1, "ADD-SWAP3-DUP3": 1, "ADD-SWAP3-SWAP1": 1, "ADD-SWAP3-SWAP2": 1, "AND-DUP1-PUSH2": 1, "AND-DUP2-ADD": 1, "AND-DUP2-MSTORE": 1, "AND-DUP4-DUP1": 1, "AND-PUSH1-ADD": 1, "AND-SWAP2-POP": 1, "AND-SWAP3-SWAP1": 1, "CALLDATACOPY-PUSH1-SWAP3": 1, "CALLDATALOAD-DUP2-DUP2": 1, "CALLDATALOAD-PUSH1-SHR": 1, "CALLDATALOAD-PUSH8-DUP1": 1, "CALLDATASIZE-LT-PUSH2": 1, "CALLDATASIZE-PUSH1-PUSH2": 1, "CALLER-DUP3-PUSH1": 1, "CALLVALUE-DUP1-ISZERO": 1, "DIV-DUP2-ADD": 1, "DUP1-ADD-OR": 1, "DUP1-DUP3-GT": 3, "DUP1-DUP5-MSTORE": 1, "DUP1-ISZERO-PUSH2": 1, "DUP1-MLOAD-PUSH1": 1, "DUP1-MLOAD-PUSH2": 1, "DUP1-PUSH2-JUMPI": 1, "DUP1-PUSH4-EQ": 3, "DUP1-SLOAD-PUSH2": 1, "DUP1-SWAP2-SUB": 1, "DUP2-ADD-MLOAD": 1, "DUP2-ADD-PUSH1": 1, "DUP2-ADD-SWAP1": 1, "DUP2-ADD-SWAP3": 1, "DUP2-AND-PUSH1": 1, "DUP2-CALLDATALOAD-DUP2": 1, "DUP2-CALLDATALOAD-PUSH8": 1, "DUP2-DUP2-GT": 2, "DUP2-DUP2-LT": 2, "DUP2-DUP2-SHR": 1, "DUP2-DUP4-LT": 1, "DUP2-DUP5-ADD": 1, "DUP2-DUP6-ADD": 1, "DUP2-EQ-ISZERO": 1, "DUP2-GT-ISZERO": 2, "DUP2-LT-ISZERO": 2, "DUP2-MLOAD-DUP1": 1, "DUP2-MSTORE-DUP8": 1, "DUP2-MSTORE-PUSH1": 1, "DUP2-PUSH1-MSTORE": 1, "DUP2-SHR-SWAP1": 1, "DUP2-SSTORE-PUSH1": 1, "DUP2-SWAP1-MSTORE": 1, "DUP3-ADD-DUP2": 1, "DUP3-ADD-MSTORE": 1, "DUP3-ADD-PUSH1": 1, "DUP3-AND-DUP1": 1, "DUP3-AND-SWAP2": 1, "DUP3-DUP1-SLOAD": 1, "DUP3-DUP2-MSTORE": 1, "DUP3-DUP5-SUB": 1, "DUP3-GT-DUP2": 1, "DUP3-GT-ISZERO": 3, "DUP3-LT-DUP2": 1, "DUP3-PUSH1-DUP7": 1, "DUP3-PUSH1-LT": 1, "DUP3-PUSH1-MLOAD": 1, "DUP3-PUSH2-JUMPI": 1, "DUP4-ADD-CALLDATACOPY": 1, "DUP4-ADD-DUP3": 1, "DUP4-ADD-DUP5": 1, "DUP4-ADD-SLT": 1, "DUP4-AND-DUP2": 1, "DUP4-DUP1-ADD": 1, "DUP4-DUP3-GT": 1, "DUP4-DUP8-ADD": 1, "DUP4-LT-OR": 1, "DUP5-ADD-SWAP1": 1, "DUP5-ADD-SWAP2": 1, "DUP5-DUP8-ADD": 1, "DUP5-MSTORE-PUSH1": 1, "DUP5-PUSH1-DUP4": 1, "DUP5-PUSH2-JUMP": 1, "DUP5-SUB-SLT": 1, "DUP6-ADD-DUP2": 1, "DUP6-SSTORE-PUSH2": 1, "DUP7-ADD-PUSH1": 1, "DUP7-DUP4-ADD": 1, "DUP8-ADD-ADD": 2, "DUP8-PUSH1-DUP5": 1, "EQ-ISZERO-PUSH2": 1, "EQ-PUSH2-JUMPI": 3, "GT-DUP2-DUP4": 1, "GT-ISZERO-PUSH2": 6, "ISZERO-PUSH2-JUMPI": 12, "JUMP-JUMPDEST-DUP1": 2, "JUMP-JUMPDEST-DUP2": 1, "JUMP-JUMPDEST-DUP3": 1, "JUMP-JUMPDEST-JUMPDEST": 1, "JUMP-JUMPDEST-POP": 3, "JUMP-JUMPDEST-PUSH1": 5, "JUMP-JUMPDEST-PUSH2": 1, "JUMP-JUMPDEST-STOP": 1, "JUMP-JUMPDEST-SWAP1": 1, "JUMP-JUMPDEST-SWAP5": 1, "JUMPDEST-DUP1-DUP3": 2, "JUMPDEST-DUP1-MLOAD": 1, "JUMPDEST-DUP2-CALLDATALOAD": 2, "JUMPDEST-DUP2-DUP2": 3, "JUMPDEST-DUP2-DUP5": 1, "JUMPDEST-DUP2-PUSH1": 1, "JUMPDEST-DUP3-DUP1": 1, "JUMPDEST-DUP3-PUSH1": 2, "JUMPDEST-JUMPDEST-DUP1": 1, "JUMPDEST-POP-PUSH1": 2, "JUMPDEST-POP-PUSH2": 1, "JUMPDEST-POP-PUSH32": 1, "JUMPDEST-POP-SWAP1": 2, "JUMPDEST-POP-SWAP2": 1, "JUMPDEST-PUSH1-DUP2": 2, "JUMPDEST-PUSH1-DUP3": 1, "JUMPDEST-PUSH1-MLOAD": 2, "JUMPDEST-PUSH1-PUSH1": 2, "JUMPDEST-PUSH2-JUMP": 1, "JUMPDEST-PUSH2-PUSH2": 1, "JUMPDEST-SWAP1-PUSH1": 1, "JUMPDEST-SWAP5-SWAP4": 1, "JUMPI-DUP1-MLOAD": 1, "JUMPI-DUP1-PUSH4": 2, "JUMPI-JUMPDEST-DUP2": 5, "JUMPI-JUMPDEST-DUP3": 2, "JUMPI-JUMPDEST-POP": 3, "JUMPI-JUMPDEST-PUSH1": 1, "JUMPI-JUMPDEST-PUSH2": 1, "JUMPI-PUSH1-CALLDATALOAD": 1, "JUMPI-PUSH1-DUP2": 2, "JUMPI-PUSH1-DUP3": 1, "JUMPI-PUSH1-PUSH1": 1, "KECCAK256-SWAP1-PUSH1": 1, "LOG1-POP-JUMP": 1, "LT-DUP2-EQ": 1, "LT-ISZERO-PUSH2": 2, "LT-OR-ISZERO": 1, "LT-PUSH2-JUMPI": 2, "MLOAD-DUP1-DUP5": 1, "MLOAD-DUP1-SWAP2": 1, "MLOAD-DUP7-DUP4": 1, "MLOAD-PUSH1-DUP3": 1, "MLOAD-PUSH1-NOT": 1, "MLOAD-PUSH2-SWAP1": 1, "MLOAD-PUSH2-SWAP3": 1, "MSTORE-ADD-PUSH2": 1, "MSTORE-CALLVALUE-DUP1": 1, "MSTORE-DUP3-DUP2": 1, "MSTORE-DUP8-PUSH1": 1, "MSTORE-JUMPDEST-POP": 1, "MSTORE-POP-SWAP6": 1, "MSTORE-PUSH1-JUMPDEST": 1, "MSTORE-PUSH1-PUSH1": 2, "MSTORE-PUSH1-SWAP1": 1, "NOT-AND-DUP4": 1, "NOT-AND-SWAP3": 1, "NOT-SWAP1-DUP2": 1, "OR-DUP6-SSTORE": 1, "OR-ISZERO-PUSH2": 1, "POP-DUP5-PUSH1": 1, "POP-JUMP-JUMPDEST": 5, "POP-JUMPDEST-PUSH1": 1, "POP-POP-JUMP": 3, "POP-POP-POP": 5, "POP-PUSH1-ADD": 1, "POP-PUSH1-CALLDATASIZE": 1, "POP-PUSH2-JUMP": 1, "POP-PUSH2-SWAP3": 1, "POP-PUSH32-CALLER": 1, "POP-SWAP1-JUMP": 2, "POP-SWAP2-SWAP1": 1, "POP-SWAP6-SWAP5": 1, "PUSH1-ADD-AND": 1, "PUSH1-ADD-PUSH1": 2, "PUSH1-ADD-PUSH2": 1, "PUSH1-ADD-SWAP3": 2, "PUSH1-CALLDATALOAD-PUSH1": 1, "PUSH1-CALLDATASIZE-LT": 1, "PUSH1-DUP2-DUP2": 1, "PUSH1-DUP2-DUP6": 1, "PUSH1-DUP2-MLOAD": 1, "PUSH1-DUP2-SSTORE": 1, "PUSH1-DUP3-ADD": 2, "PUSH1-DUP3-AND": 1, "PUSH1-DUP3-DUP5": 1, "PUSH1-DUP3-LT": 1, "PUSH1-DUP4-ADD": 2, "PUSH1-DUP4-DUP8": 1, "PUSH1-DUP5-ADD": 1, "PUSH1-DUP5-DUP8": 1, "PUSH1-DUP7-ADD": 1, "PUSH1-JUMPDEST-DUP2": 1, "PUSH1-KECCAK256-SWAP1": 1, "PUSH1-LT-PUSH2": 1, "PUSH1-MLOAD-DUP1": 1, "PUSH1-MLOAD-PUSH1": 1, "PUSH1-MLOAD-PUSH2": 1, "PUSH1-MSTORE-CALLVALUE": 1, "PUSH1-MSTORE-DUP3": 1, "PUSH1-MSTORE-PUSH1": 1, "PUSH1-NOT-AND": 2, "PUSH1-NOT-SWAP1": 1, "PUSH1-PUSH1-DUP3": 2, "PUSH1-PUSH1-DUP4": 1, "PUSH1-PUSH1-KECCAK256": 1, "PUSH1-PUSH1-PUSH1": 1, "PUSH1-PUSH1-SHL": 1, "PUSH1-PUSH2-JUMP": 1, "PUSH1-SHL-SUB": 1, "PUSH1-SHR-DUP1": 1, "PUSH1-SWAP1-DIV": 1, "PUSH1-SWAP1-PUSH1": 1, "PUSH1-SWAP1-PUSH2": 1, "PUSH1-SWAP3-DUP2": 1, "PUSH2-CALLDATASIZE-PUSH1": 1, "PUSH2-JUMP-JUMPDEST": 10, "PUSH2-JUMPI-DUP1": 3, "PUSH2-JUMPI-JUMPDEST": 12, "PUSH2-JUMPI-PUSH1": 5, "PUSH2-PUSH2-CALLDATASIZE": 1, "PUSH2-SWAP1-DUP4": 1, "PUSH2-SWAP1-PUSH1": 1, "PUSH2-SWAP1-PUSH2": 1, "PUSH2-SWAP3-SWAP2": 2, "PUSH32-CALLER-DUP3": 1, "PUSH4-EQ-PUSH2": 3, "PUSH8-DUP1-DUP3": 1, "SHL-SUB-DUP4": 1, "SHR-DUP1-PUSH4": 1, "SHR-SWAP1-DUP3": 1, "SLOAD-PUSH2-SWAP1": 1, "SLT-ISZERO-PUSH2": 1, "SLT-PUSH2-JUMPI": 1, "SSTORE-PUSH1-ADD": 1, "SSTORE-PUSH2-JUMP": 1, "SUB-DUP4-AND": 1, "SUB-SLT-ISZERO": 1, "SUB-SWAP1-LOG1": 1, "SWAP1-DIV-DUP2": 1, "SWAP1-DUP2-AND": 1, "SWAP1-DUP3-AND": 1, "SWAP1-DUP4-ADD": 1, "SWAP1-DUP4-DUP3": 1, "SWAP1-JUMP-JUMPDEST": 2, "SWAP1-LOG1-POP": 1, "SWAP1-MSTORE-PUSH1": 1, "SWAP1-POP-JUMP": 1, "SWAP1-PUSH1-ADD": 1, "SWAP1-PUSH1-DUP5": 1, "SWAP1-PUSH1-MSTORE": 1, "SWAP1-PUSH1-SWAP1": 1, "SWAP1-PUSH2-JUMP": 3, "SWAP1-PUSH2-SWAP1": 1, "SWAP1-SWAP3-ADD": 1, "SWAP1-SWAP3-MSTORE": 1, "SWAP2-POP-DUP5": 1, "SWAP2-POP-JUMPDEST": 1, "SWAP2-POP-POP": 1, "SWAP2-POP-PUSH2": 1, "SWAP2-SUB-SWAP1": 1, "SWAP2-SWAP1-POP": 1, "SWAP2-SWAP1-PUSH2": 1, "SWAP3-ADD-PUSH1": 1, "SWAP3-DUP2-ADD": 1, "SWAP3-DUP3-PUSH2": 1, "SWAP3-MSTORE-POP": 1, "SWAP3-SWAP1-SWAP3": 2, "SWAP3-SWAP2-POP": 2, "SWAP3-SWAP2-SWAP1": 1, "SWAP4-POP-POP": 1, "SWAP5-POP-POP": 1, "SWAP5-SWAP4-POP": 1, "SWAP6-SWAP5-POP": 1}', '{"ADD": 28, "AND": 7, "CALLDATACOPY": 1, "CALLDATALOAD": 3, "CALLDATASIZE": 2, "CALLER": 1, "CALLVALUE": 1, "DIV": 1, "DUP1": 14, "DUP2": 27, "DUP3": 17, "DUP4": 9, "DUP5": 7, "DUP6": 2, "DUP7": 2, "DUP8": 3, "EQ": 4, "GT": 7, "ISZERO": 12, "JUMP": 17, "JUMPDEST": 33, "JUMPI": 20, "KECCAK256": 1, "LOG1": 1, "LT": 6, "MLOAD": 7, "MSTORE": 10, "NOT": 3, "OR": 2, "POP": 24, "PUSH1": 49, "PUSH2": 37, "PUSH32": 1, "PUSH4": 3, "PUSH8": 1, "SHL": 1, "SHR": 2, "SLOAD": 1, "SLT": 2, "SSTORE": 2, "STOP": 1, "SUB": 3, "SWAP1": 20, "SWAP2": 7, "SWAP3": 9, "SWAP4": 1, "SWAP5": 2, "SWAP6": 1}', '["0", "32", "192", "100", "18446744073709551615", "36", "0", "4", "16372862481753577294267620541204082621793577260386896888229232294795359027205", "0", "32745724963507154588535241082408165243587154520773793776458464589590718054410", "160", "5", "80084422859880547211683076133703299733277748156566366325829078699459944778999", "80084422859880547211683076133703299733277748156566366325829078699459944778999", "1", "32", "0", "128", "1042670065772417531265339626254010608318119686474", "0", "192", "128", "128"]', '["0:PUSH1", "2:PUSH1", "4:MSTORE", "5:CALLVALUE", "6:DUP1", "7:ISZERO", "8:PUSH2", "11:JUMPI", "16:JUMPDEST", "17:POP", "18:PUSH1", "20:CALLDATASIZE", "21:LT", "22:PUSH2", "25:JUMPI", "26:PUSH1", "28:CALLDATALOAD", "29:PUSH1", "31:SHR", "32:DUP1", "33:PUSH4", "38:EQ", "39:PUSH2", "42:JUMPI", "43:DUP1", "44:PUSH4", "49:EQ", "50:PUSH2", "53:JUMPI", "54:DUP1", "55:PUSH4", "60:EQ", "61:PUSH2", "64:JUMPI", "124:JUMPDEST", "125:PUSH2", "128:PUSH2", "131:CALLDATASIZE", "132:PUSH1", "134:PUSH2", "137:JUMP", "717:JUMPDEST", "718:PUSH1", "720:PUSH1", "722:DUP3", "723:DUP5", "724:SUB", "725:SLT", "726:ISZERO", "727:PUSH2", "730:JUMPI", "735:JUMPDEST", "736:DUP2", "737:CALLDATALOAD", "738:PUSH8", "747:DUP1", "748:DUP3", "749:GT", "750:ISZERO", "751:PUSH2", "754:JUMPI", "759:JUMPDEST", "760:DUP2", "761:DUP5", "762:ADD", "763:SWAP2", "764:POP", "765:DUP5", "766:PUSH1", "768:DUP4", "769:ADD", "770:SLT", "771:PUSH2", "774:JUMPI", "779:JUMPDEST", "780:DUP2", "781:CALLDATALOAD", "782:DUP2", "783:DUP2", "784:GT", "785:ISZERO", "786:PUSH2", "789:JUMPI", "797:JUMPDEST", "798:PUSH1", "800:MLOAD", "801:PUSH1", "803:DUP3", "804:ADD", "805:PUSH1", "807:NOT", "808:SWAP1", "809:DUP2", "810:AND", "811:PUSH1", "813:ADD", "814:AND", "815:DUP2", "816:ADD", "817:SWAP1", "818:DUP4", "819:DUP3", "820:GT", "821:DUP2", "822:DUP4", "823:LT", "824:OR", "825:ISZERO", "826:PUSH2", "829:JUMPI", "837:JUMPDEST", "838:DUP2", "839:PUSH1", "841:MSTORE", "842:DUP3", "843:DUP2", "844:MSTORE", "845:DUP8", "846:PUSH1", "848:DUP5", "849:DUP8", "850:ADD", "851:ADD", "852:GT", "853:ISZERO", "854:PUSH2", "857:JUMPI", "862:JUMPDEST", "863:DUP3", "864:PUSH1", "866:DUP7", "867:ADD", "868:PUSH1", "870:DUP4", "871:ADD", "872:CALLDATACOPY", "873:PUSH1", "875:SWAP3", "876:DUP2", "877:ADD", "878:PUSH1", "880:ADD", "881:SWAP3", "882:SWAP1", "883:SWAP3", "884:MSTORE", "885:POP", "886:SWAP6", "887:SWAP5", "888:POP", "889:POP", "890:POP", "891:POP", "892:POP", "893:JUMP", "138:JUMPDEST", "139:PUSH2", "142:JUMP", "174:JUMPDEST", "175:DUP1", "176:MLOAD", "177:PUSH2", "180:SWAP1", "181:PUSH1", "183:SWAP1", "184:PUSH1", "186:DUP5", "187:ADD", "188:SWAP1", "189:PUSH2", "192:JUMP", "542:JUMPDEST", "543:DUP3", "544:DUP1", "545:SLOAD", "546:PUSH2", "549:SWAP1", "550:PUSH2", "553:JUMP", "1041:JUMPDEST", "1042:PUSH1", "1044:DUP2", "1045:DUP2", "1046:SHR", "1047:SWAP1", "1048:DUP3", "1049:AND", "1050:DUP1", "1051:PUSH2", "1054:JUMPI", "1055:PUSH1", "1057:DUP3", "1058:AND", "1059:SWAP2", "1060:POP", "1061:JUMPDEST", "1062:PUSH1", "1064:DUP3", "1065:LT", "1066:DUP2", "1067:EQ", "1068:ISZERO", "1069:PUSH2", "1072:JUMPI", "1094:JUMPDEST", "1095:POP", "1096:SWAP2", "1097:SWAP1", "1098:POP", "1099:JUMP", "554:JUMPDEST", "555:SWAP1", "556:PUSH1", "558:MSTORE", "559:PUSH1", "561:PUSH1", "563:KECCAK256", "564:SWAP1", "565:PUSH1", "567:ADD", "568:PUSH1", "570:SWAP1", "571:DIV", "572:DUP2", "573:ADD", "574:SWAP3", "575:DUP3", "576:PUSH2", "579:JUMPI", "588:JUMPDEST", "589:DUP3", "590:PUSH1", "592:LT", "593:PUSH2", "596:JUMPI", "597:DUP1", "598:MLOAD", "599:PUSH1", "601:NOT", "602:AND", "603:DUP4", "604:DUP1", "605:ADD", "606:OR", "607:DUP6", "608:SSTORE", "609:PUSH2", "612:JUMP", "658:JUMPDEST", "659:POP", "660:PUSH2", "663:SWAP3", "664:SWAP2", "665:POP", "666:PUSH2", "669:JUMP", "674:JUMPDEST", "675:JUMPDEST", "676:DUP1", "677:DUP3", "678:GT", "679:ISZERO", "680:PUSH2", "683:JUMPI", "684:PUSH1", "686:DUP2", "687:SSTORE", "688:PUSH1", "690:ADD", "691:PUSH2", "694:JUMP", "675:JUMPDEST", "676:DUP1", "677:DUP3", "678:GT", "679:ISZERO", "680:PUSH2", "683:JUMPI", "670:JUMPDEST", "671:POP", "672:SWAP1", "673:JUMP", "670:JUMPDEST", "671:POP", "672:SWAP1", "673:JUMP", "193:JUMPDEST", "194:POP", "195:PUSH32", "228:CALLER", "229:DUP3", "230:PUSH1", "232:MLOAD", "233:PUSH2", "236:SWAP3", "237:SWAP2", "238:SWAP1", "239:PUSH2", "242:JUMP", "997:JUMPDEST", "998:PUSH1", "1000:PUSH1", "1002:PUSH1", "1004:SHL", "1005:SUB", "1006:DUP4", "1007:AND", "1008:DUP2", "1009:MSTORE", "1010:PUSH1", "1012:PUSH1", "1014:DUP3", "1015:ADD", "1016:DUP2", "1017:SWAP1", "1018:MSTORE", "1019:PUSH1", "1021:SWAP1", "1022:PUSH2", "1025:SWAP1", "1026:DUP4", "1027:ADD", "1028:DUP5", "1029:PUSH2", "1032:JUMP", "894:JUMPDEST", "895:PUSH1", "897:DUP2", "898:MLOAD", "899:DUP1", "900:DUP5", "901:MSTORE", "902:PUSH1", "904:JUMPDEST", "905:DUP2", "906:DUP2", "907:LT", "908:ISZERO", "909:PUSH2", "912:JUMPI", "913:PUSH1", "915:DUP2", "916:DUP6", "917:ADD", "918:DUP2", "919:ADD", "920:MLOAD", "921:DUP7", "922:DUP4", "923:ADD", "924:DUP3", "925:ADD", "926:MSTORE", "927:ADD", "928:PUSH2", "931:JUMP", "904:JUMPDEST", "905:DUP2", "906:DUP2", "907:LT", "908:ISZERO", "909:PUSH2", "912:JUMPI", "932:JUMPDEST", "933:DUP2", "934:DUP2", "935:GT", "936:ISZERO", "937:PUSH2", "940:JUMPI", "941:PUSH1", "943:PUSH1", "945:DUP4", "946:DUP8", "947:ADD", "948:ADD", "949:MSTORE", "950:JUMPDEST", "951:POP", "952:PUSH1", "954:ADD", "955:PUSH1", "957:NOT", "958:AND", "959:SWAP3", "960:SWAP1", "961:SWAP3", "962:ADD", "963:PUSH1", "965:ADD", "966:SWAP3", "967:SWAP2", "968:POP", "969:POP", "970:JUMP", "1033:JUMPDEST", "1034:SWAP5", "1035:SWAP4", "1036:POP", "1037:POP", "1038:POP", "1039:POP", "1040:JUMP", "243:JUMPDEST", "244:PUSH1", "246:MLOAD", "247:DUP1", "248:SWAP2", "249:SUB", "250:SWAP1", "251:LOG1", "252:POP", "253:JUMP", "143:JUMPDEST", "144:STOP"]'] # noqa: E501 diff --git a/tests/integration_tests/test_tracers.py b/tests/integration_tests/test_tracers.py index 6346176059..1f44d34a11 100644 --- a/tests/integration_tests/test_tracers.py +++ b/tests/integration_tests/test_tracers.py @@ -8,12 +8,14 @@ EXPECTED_CALLTRACERS, EXPECTED_CONTRACT_CREATE_TRACER, EXPECTED_DEFAULT_GASCAP, + EXPECTED_JS_TRACERS, EXPECTED_STRUCT_TRACER, ) from .utils import ( ADDRS, CONTRACTS, deploy_contract, + derive_new_account, derive_random_account, send_transaction, w3_wait_for_new_blocks, @@ -143,113 +145,60 @@ def process(w3): ]), res -def test_js_tracers(ethermint): - w3: Web3 = ethermint.w3 - eth_rpc = w3.provider - - from_addr = ADDRS["validator"] - - contract, _ = deploy_contract(w3, CONTRACTS["Greeter"]) - w3_wait_for_new_blocks(w3, 1, sleep=0.1) - - tx = contract.functions.setGreeting("world").build_transaction() - - tx = { - "from": from_addr, - "to": contract.address, - "data": tx["data"], - } - - # bigramTracer - # https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers#js-tracers - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "bigramTracer"}] - ) - assert "result" in tx_res - tx_res = tx_res["result"] - assert tx_res["ADD-ADD"] == 2 - assert tx_res["ADD-PUSH1"] == 6 - - # evmdis - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "evmdisTracer"}] - ) - assert "result" in tx_res - tx_res = tx_res["result"] - assert tx_res[0] == {"depth": 1, "len": 2, "op": 96, "result": ["80"]} - - # opcount - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "opcountTracer"}] - ) - assert "result" in tx_res - tx_res = tx_res["result"] - assert tx_res > 0 - - # trigram - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "trigramTracer"}] - ) - assert "result" in tx_res - tx_res = tx_res["result"] - assert tx_res["ADD-ADD-MSTORE"] == 1 - assert tx_res["DUP2-MLOAD-DUP1"] == 1 - - # unigram - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "unigramTracer"}] - ) - assert "result" in tx_res - tx_res = tx_res["result"] - assert tx_res["POP"] == 24 - - -def test_custom_js_tracers(ethermint): - w3: Web3 = ethermint.w3 - eth_rpc = w3.provider - - from_addr = ADDRS["validator"] - - contract, _ = deploy_contract(w3, CONTRACTS["Greeter"]) - w3_wait_for_new_blocks(w3, 1, sleep=0.1) - - tx = contract.functions.setGreeting("world").build_transaction() +def test_js_tracers(ethermint, geth): + method = "debug_traceCall" + acc = derive_new_account(n=2) + sender = acc.address - tx = { - "from": from_addr, - "to": contract.address, - "data": tx["data"], - } + def process(w3): + # fund new sender to deploy contract with same address + fund_acc(w3, acc) + contract, _ = deploy_contract(w3, CONTRACTS["Greeter"], key=acc.key) + tx = contract.functions.setGreeting("world").build_transaction() + tx = {"from": sender, "to": contract.address, "data": tx["data"]} + # https://geth.ethereum.org/docs/developers/evm-tracing/built-in-tracers#js-tracers + tracers = [ + "bigramTracer", + "evmdisTracer", + "opcountTracer", + "trigramTracer", + "unigramTracer", + """{ + data: [], + fault: function(log) {}, + step: function(log) { + if(log.op.toString() == "POP") this.data.push(log.stack.peek(0)); + }, + result: function() { return this.data; } + }""", + """{ + retVal: [], + step: function(log,db) { + this.retVal.push(log.getPC() + ":" + log.op.toString()) + }, + fault: function(log,db) { + this.retVal.push("FAULT: " + JSON.stringify(log)) + }, + result: function(ctx,db) { + return this.retVal + } + } + """ + ] + res = [] + call = w3.provider.make_request + with ThreadPoolExecutor(len(tracers)) as exec: + params = [[tx, "latest", {"tracer": tracer}] for tracer in tracers] + exec_map = exec.map(call, itertools.repeat(method), params) + res = [json.dumps(resp["result"], sort_keys=True) for resp in exec_map] + return res - tracer = """{ - data: [], - fault: function(log) {}, - step: function(log) { - if(log.op.toString() == "POP") this.data.push(log.stack.peek(0)); - }, - result: function() { return this.data; } - }""" - tx_res = eth_rpc.make_request("debug_traceCall", [tx, "latest", {"tracer": tracer}]) - assert "result" in tx_res - tx_res = tx_res["result"] - - tracer = """{ - retVal: [], - step: function(log,db) { - this.retVal.push(log.getPC() + ":" + log.op.toString()) - }, - fault: function(log,db) { - this.retVal.push("FAULT: " + JSON.stringify(log)) - }, - result: function(ctx,db) { - return this.retVal - } - } - """ - tx_res = eth_rpc.make_request("debug_traceCall", [tx, "latest", {"tracer": tracer}]) - assert "result" in tx_res - tx_res = tx_res["result"] - assert tx_res[0] == "0:PUSH1" + providers = [ethermint.w3, geth.w3] + with ThreadPoolExecutor(len(providers)) as exec: + tasks = [exec.submit(process, w3) for w3 in providers] + res = [future.result() for future in as_completed(tasks)] + assert len(res) == len(providers) + assert (res[0] == res[1] == EXPECTED_JS_TRACERS), res def test_tracecall_struct_tracer(ethermint, geth): From b325829264c3ef108e3203c72e3fc8b310711435 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Fri, 5 Jan 2024 15:23:18 +0800 Subject: [PATCH 7/9] test_tracecall_prestate_tracer --- tests/integration_tests/test_tracers.py | 77 ++++++++++--------------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/tests/integration_tests/test_tracers.py b/tests/integration_tests/test_tracers.py index 1f44d34a11..1b8da0ac48 100644 --- a/tests/integration_tests/test_tracers.py +++ b/tests/integration_tests/test_tracers.py @@ -232,55 +232,38 @@ def process(w3, gas): }, res -def test_tracecall_prestate_tracer(ethermint: Ethermint): - w3 = ethermint.w3 - eth_rpc = w3.provider - - sender = ADDRS["signer1"] - receiver = ADDRS["signer2"] - - # make a transaction make sure the nonce is not 0 - w3.eth.send_transaction( - { - "from": sender, - "to": receiver, - "value": hex(1), - } - ) - - w3.eth.send_transaction( - { - "from": receiver, - "to": sender, - "value": hex(1), - } - ) - w3_wait_for_new_blocks(w3, 1, sleep=0.1) - - sender_nonce = w3.eth.get_transaction_count(sender) - sender_bal = w3.eth.get_balance(sender) - receiver_nonce = w3.eth.get_transaction_count(receiver) - receiver_bal = w3.eth.get_balance(receiver) +def test_tracecall_prestate_tracer(ethermint, geth): + method = "debug_traceCall" + tracer = {"tracer": "prestateTracer"} + sender_acc = derive_random_account() + sender = sender_acc.address + receiver_acc = derive_random_account() + receiver = receiver_acc.address + addrs = [sender.lower(), receiver.lower()] - tx = { - "from": sender, - "to": receiver, - "value": hex(1), - } - w3_wait_for_new_blocks(w3, 1, sleep=0.1) - tx_res = eth_rpc.make_request( - "debug_traceCall", [tx, "latest", {"tracer": "prestateTracer"}] - ) + def process(w3): + fund_acc(w3, sender_acc) + fund_acc(w3, receiver_acc) + tx = {"value": 1, "gas": 21000, "gasPrice": 88500000000} + # make a transaction make sure the nonce is not 0 + send_transaction(w3, tx | {"from": sender, "to": receiver}, key=sender_acc.key) + tx = tx | {"from": receiver, "to": sender} + send_transaction(w3, tx, key=receiver_acc.key) + tx = {"from": sender, "to": receiver, "value": hex(1)} + tx_res = w3.provider.make_request(method, [tx, "latest", tracer]) + assert "result" in tx_res + assert all(tx_res["result"][addr.lower()] == { + "balance": hex(w3.eth.get_balance(addr)), + "nonce": w3.eth.get_transaction_count(addr), + } for addr in [sender, receiver]), tx_res["result"] + return tx_res["result"] - assert "result" in tx_res - assert tx_res["result"][sender.lower()] == { - "balance": hex(sender_bal), - "nonce": sender_nonce, - } - assert tx_res["result"][receiver.lower()] == { - "balance": hex(receiver_bal), - "nonce": receiver_nonce, - } + providers = [ethermint.w3, geth.w3] + with ThreadPoolExecutor(len(providers)) as exec: + tasks = [exec.submit(process, w3) for w3 in providers] + res = [future.result() for future in as_completed(tasks)] + assert len(res) == len(providers) + assert all(res[0][addr] == res[-1][addr] for addr in addrs), res def test_debug_tracecall_call_tracer(ethermint, geth): From d2ddc1f2a9e443b2215f40364f38ff736903312b Mon Sep 17 00:00:00 2001 From: mmsqe Date: Mon, 8 Jan 2024 09:08:17 +0800 Subject: [PATCH 8/9] Update CHANGELOG.md Signed-off-by: mmsqe --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21d4bfa8bd..18f2a70073 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,7 +70,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (rpc) [#382](https://github.com/crypto-org-chain/ethermint/pull/382) Align tracer config with go-ethereum. * (rpc) [#386](https://github.com/crypto-org-chain/ethermint/pull/386) Cleanup unused cancel function in filter. * (rpc) [#388](https://github.com/crypto-org-chain/ethermint/pull/388) Avoid out of bound panic when error message. -* (rpc) [#](https://github.com/crypto-org-chain/ethermint/pull/) Align block param with go-ethereum in debug_traceCall. +* (rpc) [#391](https://github.com/crypto-org-chain/ethermint/pull/391) Align block param with go-ethereum in debug_traceCall. ### Improvements From 986a4e1c3828a82738e83e6d57b5470e2ad15715 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Mon, 8 Jan 2024 10:21:43 +0800 Subject: [PATCH 9/9] Apply suggestions from code review for more info, https://github.com/ethereum/go-ethereum/blob/release/1.11/eth/tracers/api.go#L919 --- rpc/backend/tracing.go | 2 +- tests/integration_tests/test_tracers.py | 39 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/rpc/backend/tracing.go b/rpc/backend/tracing.go index 843a8d7d8e..a6feaa03fc 100644 --- a/rpc/backend/tracing.go +++ b/rpc/backend/tracing.go @@ -245,7 +245,7 @@ func (b *Backend) TraceCall( traceCallRequest.TraceConfig = b.convertConfig(config) } - // minus one to get the context of block beginning + // get the context of provided block contextHeight := blk.Block.Height if contextHeight < 1 { // 0 is a special value in `ContextWithHeight` diff --git a/tests/integration_tests/test_tracers.py b/tests/integration_tests/test_tracers.py index 1b8da0ac48..2285a4e35a 100644 --- a/tests/integration_tests/test_tracers.py +++ b/tests/integration_tests/test_tracers.py @@ -266,6 +266,45 @@ def process(w3): assert all(res[0][addr] == res[-1][addr] for addr in addrs), res +def test_tracecall_diff(ethermint, geth): + method = "debug_traceCall" + tracer = {"tracer": "prestateTracer", "tracerConfig": {"diffMode": True}} + sender_acc = derive_new_account(4) + sender = sender_acc.address + receiver = derive_new_account(5).address + fund = 3000000000000000000 + gas = 21000 + price = 88500000000 + fee = gas * price + + def process(w3): + fund_acc(w3, sender_acc) + tx = {"from": sender, "to": receiver, "value": 1, "gas": gas, "gasPrice": price} + send_transaction(w3, tx, key=sender_acc.key) + res = send_transaction(w3, tx, key=sender_acc.key) + send_transaction(w3, tx, key=sender_acc.key) + tx = {"from": sender, "to": receiver, "value": hex(1)} + tx_res = w3.provider.make_request(method, [tx, hex(res["blockNumber"]), tracer]) + return json.dumps(tx_res["result"], sort_keys=True) + + providers = [ethermint.w3, geth.w3] + expected = json.dumps({ + "post": { + receiver.lower(): {"balance": hex(3)}, + sender.lower(): {"balance": hex(fund - 3 - fee * 2), "nonce": 3} + }, + "pre": { + receiver.lower(): {"balance": hex(2)}, + sender.lower(): {"balance": hex(fund - 2 - fee * 2), "nonce": 2} + } + }, sort_keys=True) + with ThreadPoolExecutor(len(providers)) as exec: + tasks = [exec.submit(process, w3) for w3 in providers] + res = [future.result() for future in as_completed(tasks)] + assert len(res) == len(providers) + assert (res[0] == res[-1] == expected), res + + def test_debug_tracecall_call_tracer(ethermint, geth): method = "debug_traceCall" acc = derive_random_account()