Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test async trace rpc #3051

Open
wants to merge 2 commits into
base: pytest
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion integration_tests/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ def add_remote_nodes(self, num_nodes, ip, user, rpchost=None, binary=None, no_ps
no_pssh=no_pssh,
))

def start_node(self, i, extra_args=None, phase_to_wait=["NormalSyncPhase"], wait_time=30, *args, **kwargs):
def start_node(self, i:int, extra_args=None, phase_to_wait=["NormalSyncPhase"], wait_time=30, *args, **kwargs):
"""Start a bitcoind"""

node = self.nodes[i]
Expand Down
9 changes: 8 additions & 1 deletion integration_tests/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from conflux_web3 import Web3
import pytest
import argparse
import os
from typing import Type

from integration_tests.test_framework.test_framework import ConfluxTestFramework
from integration_tests.conflux.rpc import RpcClient
from web3.tracing import Tracing

TMP_DIR = None

Expand Down Expand Up @@ -138,9 +140,14 @@ def cw3(network: ConfluxTestFramework):
return network.cw3

@pytest.fixture(scope="module")
def ew3(network: ConfluxTestFramework):
def ew3(network: ConfluxTestFramework) -> Web3:
return network.ew3

@pytest.fixture(scope="module")
def ew3_tracing(ew3):
tracing: 'Tracing' = ew3.tracing
return tracing

@pytest.fixture(scope="module")
def core_accounts(network: ConfluxTestFramework):
return network.core_accounts
Expand Down
70 changes: 70 additions & 0 deletions integration_tests/tests/rpc/espace/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from web3 import Web3
from integration_tests.test_framework.util import load_contract_metadata
from integration_tests.test_framework.test_framework import ConfluxTestFramework
from integration_tests.conflux.rpc import RpcClient
from typing import Dict, Type
import pytest
from web3.types import TxReceipt


@pytest.fixture(scope="module")
def framework_class() -> Type[ConfluxTestFramework]:
class DefaultFramework(ConfluxTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.conf_parameters["min_native_base_price"] = 10000
self.conf_parameters["next_hardfork_transition_height"] = 1
self.conf_parameters["next_hardfork_transition_number"] = 1
self.conf_parameters["public_evm_rpc_async_apis"] = (
'"all"' # open all async apis
)
self.conf_parameters["executive_trace"] = "true"

def setup_network(self):
self.setup_nodes()
self.rpc = RpcClient(self.nodes[0])

return DefaultFramework


@pytest.fixture(scope="module")
def erc20_contract(ew3, evm_accounts):
account = evm_accounts[0]
contract_meta = load_contract_metadata("MyToken")
# deploy contract
TokenContract = ew3.eth.contract(
abi=contract_meta["abi"], bytecode=contract_meta["bytecode"]
)
tx_hash = TokenContract.constructor(account.address).transact()
ew3.eth.wait_for_transaction_receipt(tx_hash)

# create erc20 contract instance
deploy_receipt = ew3.eth.get_transaction_receipt(tx_hash)
assert deploy_receipt["status"] == 1
erc20_address = deploy_receipt["contractAddress"]
token_contract = ew3.eth.contract(address=erc20_address, abi=contract_meta["abi"])

# mint 100 tokens to creator
mint_hash = token_contract.functions.mint(
account.address, ew3.to_wei(100, "ether")
).transact()
ew3.eth.wait_for_transaction_receipt(mint_hash)

return {
"contract": token_contract,
"deploy_hash": tx_hash,
}


@pytest.fixture(scope="module")
def erc20_token_transfer(erc20_contract, ew3: Web3) -> Dict[str, TxReceipt]:
to_address = ew3.eth.account.create().address
token_contract = erc20_contract["contract"]
transfer_hash = token_contract.functions.transfer(
to_address, ew3.to_wei(1, "ether")
).transact()
receipt: TxReceipt = ew3.eth.wait_for_transaction_receipt(transfer_hash)
return {
"tx_hash": transfer_hash,
"receipt": receipt,
}
76 changes: 10 additions & 66 deletions integration_tests/tests/rpc/espace/test_debug_rpc.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,3 @@
import pytest
from integration_tests.test_framework.test_framework import ConfluxTestFramework
from integration_tests.test_framework.util import load_contract_metadata
from integration_tests.conflux.rpc import RpcClient
from typing import Type

@pytest.fixture(scope="module")
def framework_class() -> Type[ConfluxTestFramework]:
class DefaultFramework(ConfluxTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.conf_parameters["min_native_base_price"] = 10000
self.conf_parameters["next_hardfork_transition_height"] = 1
self.conf_parameters["next_hardfork_transition_number"] = 1
self.conf_parameters["public_evm_rpc_async_apis"] = "\"all\"" # open all async apis

def setup_network(self):
self.setup_nodes()
self.rpc = RpcClient(self.nodes[0])

return DefaultFramework

@pytest.fixture(scope="module")
def erc20_contract(ew3, evm_accounts):
account = evm_accounts[0]
contract_meta = load_contract_metadata("MyToken")
# deploy contract
TokenContract = ew3.eth.contract(abi=contract_meta['abi'], bytecode=contract_meta['bytecode'])
tx_hash = TokenContract.constructor(account.address).transact()
ew3.eth.wait_for_transaction_receipt(tx_hash)

# create erc20 contract instance
deploy_receipt = ew3.eth.get_transaction_receipt(tx_hash)
assert deploy_receipt["status"] == 1
erc20_address = deploy_receipt["contractAddress"]
token_contract = ew3.eth.contract(address=erc20_address, abi=contract_meta['abi'])

# mint 100 tokens to creator
mint_hash = token_contract.functions.mint(account.address, ew3.to_wei(100, "ether")).transact()
ew3.eth.wait_for_transaction_receipt(mint_hash)

return {
"contract": token_contract,
"deploy_hash": tx_hash,
}

@pytest.fixture(scope="module")
def token_transfer(erc20_contract, ew3):
to_address = ew3.eth.account.create().address
token_contract = erc20_contract["contract"]
transfer_hash = token_contract.functions.transfer(to_address, ew3.to_wei(1, "ether")).transact()
ew3.eth.wait_for_transaction_receipt(transfer_hash)
return {
"tx_hash": transfer_hash,
}

def test_trace_simple_cfx_transfer(ew3, evm_accounts):
account = evm_accounts[0]
to_address = ew3.eth.account.create().address
Expand Down Expand Up @@ -86,36 +30,36 @@ def test_trace_deploy_contract(ew3, erc20_contract):

assert tx_trace["structLogs"][oplog_len-1]["op"] == "RETURN"

def test_transfer_trace(ew3, token_transfer):
transfer_hash = token_transfer["tx_hash"]
def test_transfer_trace(ew3, erc20_token_transfer):
transfer_hash = erc20_token_transfer["tx_hash"]
transfer_trace = ew3.manager.request_blocking('debug_traceTransaction', [transfer_hash])

assert transfer_trace["failed"] == False
oplog_len = len(transfer_trace["structLogs"])
assert oplog_len > 0
assert transfer_trace["structLogs"][oplog_len-1]["op"] == "RETURN"

def test_noop_trace(ew3, token_transfer):
transfer_hash = token_transfer["tx_hash"]
def test_noop_trace(ew3, erc20_token_transfer):
transfer_hash = erc20_token_transfer["tx_hash"]
noop_trace = ew3.manager.request_blocking('debug_traceTransaction', [transfer_hash, {"tracer": "noopTracer"}])
assert noop_trace == {}

def test_four_byte_trace(ew3, token_transfer):
transfer_hash = token_transfer["tx_hash"]
def test_four_byte_trace(ew3, erc20_token_transfer):
transfer_hash = erc20_token_transfer["tx_hash"]
four_byte_trace = ew3.manager.request_blocking('debug_traceTransaction', [transfer_hash, {"tracer": "4byteTracer"}])
assert four_byte_trace == {'0xa9059cbb-64': 1}

def test_call_trace(ew3, token_transfer):
transfer_hash = token_transfer["tx_hash"]
def test_call_trace(ew3, erc20_token_transfer):
transfer_hash = erc20_token_transfer["tx_hash"]
call_trace = ew3.manager.request_blocking('debug_traceTransaction', [transfer_hash, {"tracer": "callTracer"}])
assert call_trace["from"] == "0x0e768d12395c8abfdedf7b1aeb0dd1d27d5e2a7f"
# assert call_trace["to"] == "0xe2182fba747b5706a516d6cf6bf62d6117ef86ea"
assert call_trace["type"] == 'CALL'
assert call_trace["value"] == "0x0"
assert call_trace["output"] == "0x0000000000000000000000000000000000000000000000000000000000000001"

def test_opcode_trace_with_config(ew3, token_transfer):
tx_hash = token_transfer["tx_hash"]
def test_opcode_trace_with_config(ew3, erc20_token_transfer):
tx_hash = erc20_token_transfer["tx_hash"]
trace = ew3.manager.request_blocking('debug_traceTransaction', [tx_hash, {
"enableMemory": True,
"disableStack": False,
Expand Down
45 changes: 45 additions & 0 deletions integration_tests/tests/rpc/espace/test_trace_rpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import json
from web3.tracing import Tracing
from web3 import Web3
from typing import List
from web3.types import FilterTrace, TxReceipt


def verify_erc20_token_transfer_trace(traces: List[FilterTrace], receipt: TxReceipt):
assert len(traces) == 1

trace0 = traces[0]
assert trace0["type"] == "call"
assert trace0["transactionHash"] == receipt["transactionHash"]
assert trace0["blockHash"] == receipt["blockHash"]
assert trace0["blockNumber"] == receipt["blockNumber"]
assert trace0["transactionPosition"] == 0
assert trace0["valid"] == True
assert trace0["result"] != None

action = trace0["action"]
assert action["from"] == receipt["from"]
assert action["to"] == receipt["to"]
assert action["callType"] == "call"


def test_trace_filter(ew3_tracing, erc20_token_transfer):
receipt = erc20_token_transfer["receipt"]
traces = ew3_tracing.trace_filter(
{"fromBlock": Web3.to_hex(receipt["blockNumber"])}
)
verify_erc20_token_transfer_trace(traces, receipt)


def test_trace_block(ew3_tracing, erc20_token_transfer):
receipt = erc20_token_transfer["receipt"]
traces = ew3_tracing.trace_block(receipt["blockNumber"])
verify_erc20_token_transfer_trace(traces, receipt)


def test_trace_transaction(ew3_tracing, erc20_token_transfer):
receipt = erc20_token_transfer["receipt"]
tx_hash = erc20_token_transfer["tx_hash"]

traces = ew3_tracing.trace_transaction(tx_hash)
verify_erc20_token_transfer_trace(traces, receipt)
2 changes: 1 addition & 1 deletion tests/test_contracts