def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) # deploy contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) self.log.info("contract deployed") contract_epoch = hex(self.rpc[FULLNODE0].epoch_number()) # call method once receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()"))) call_epoch = hex(self.rpc[FULLNODE0].epoch_number()) # deploy another instance of the contract _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) # call method multiple times for ii in range(0, NUM_CALLS - 3): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()"))) # make sure we have enough blocks to be certain about the validity of previous blocks self.log.info("generating blocks...") for _ in range(50): self.generate_correct_block(FULLNODE0) self.log.info("syncing full nodes...") sync_blocks(self.nodes[FULLNODE0:FULLNODE1]) # connect light node to full nodes connect_nodes(self.nodes, LIGHTNODE, FULLNODE0) connect_nodes(self.nodes, LIGHTNODE, FULLNODE1) # make sure we all nodes are in sync self.log.info("syncing light node...") sync_blocks(self.nodes[:]) # retrieve contract code self.log.info("retrieving contract code...") self.check_code(contractAddr, contract_epoch) # apply filter, we expect a single log with 2 topics self.log.info("testing filter range...") self.check_filter( Filter(from_epoch="earliest", to_epoch=contract_epoch)) self.check_filter(Filter(from_epoch="earliest", to_epoch=call_epoch)) self.check_filter(Filter()) self.check_filter(Filter(from_epoch="0x0", to_epoch="0x0")) # apply filter for specific block, we expect a single log with 3 topics self.check_filter(Filter(block_hashes=[receipt["blockHash"]])) # apply filter for specific topics self.log.info("testing filter topics...") self.check_filter(Filter(topics=[CONSTRUCTED_TOPIC])) self.check_filter(Filter(topics=[CALLED_TOPIC])) self.check_filter(Filter(topics=[None, self.address_to_topic(sender)])) self.check_filter( Filter(topics=[ CALLED_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ])) # apply filter with limit self.log.info("testing filter limit...") self.check_filter(Filter(limit=("0x%x" % (NUM_CALLS // 2)))) # apply filter for specific contract address self.log.info("testing address filtering...") self.check_filter(Filter(address=[contractAddr])) self.check_filter(Filter(address=[contractAddr2])) self.log.info("Pass")
import eth_utils from conflux.config import default_config from conflux.filter import Filter from conflux.pubsub import PubSubClient from conflux.rpc import RpcClient from conflux.utils import sha3 as keccak, priv_to_addr from test_framework.blocktools import encode_hex_0x from test_framework.test_framework import ConfluxTestFramework from test_framework.util import assert_equal, assert_is_hex_string, connect_nodes, sync_blocks FULLNODE0 = 0 FULLNODE1 = 1 CONTRACT_PATH = "../contracts/EventsTestContract_bytecode.dat" FOO_TOPIC = encode_hex_0x(keccak(b"foo()")) NUM_CALLS = 20 class PubSubTest(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 2 def setup_network(self): self.add_nodes(self.num_nodes) self.start_node(FULLNODE0, ["--archive"]) self.start_node(FULLNODE1, ["--archive"]) # set up RPC clients
def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) # deploy storage test contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() tx = self.rpc.new_contract_tx(receiver="", data_hex=bytecode, sender=sender, priv_key=priv_key, storage_limit=20000) assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex()) receipt = self.rpc.get_transaction_receipt(tx.hash_hex()) contractAddr = receipt["contractCreated"] assert_is_hex_string(contractAddr) # --- --- # .-----------------| D |.... .----------------| H |..... # V --- | V --- | # --- --- --- --- --- --- --- # ... <-- | A | <- | B | <- | C | <- | E | <- | F | <- | G | <- | I | <- ... # --- --- --- --- --- --- --- # # A --- B --- C --- D --- E --- F --- G --- H --- I # block number 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | # epoch number 0 | 1 | 2 | 3 | 4 | 5 | 6 | start_nonce = self.rpc.get_nonce(self.rpc.GENESIS_ADDR) txs = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 0, sender=sender, priv_key=priv_key, storage_limit=64), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 1, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 2, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 3, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 4, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 5, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 6, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 7, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 8, sender=sender, priv_key=priv_key), ] block_0 = self.rpc.block_by_epoch("latest_mined")['hash'] epoch_0 = int(self.rpc.block_by_hash(block_0)['epochNumber'], 0) block_number_0 = int(self.rpc.block_by_hash(block_0)['blockNumber'], 0) block_a = self.rpc.generate_custom_block(parent_hash=block_0, referee=[], txs=[txs[0]]) block_b = self.rpc.generate_custom_block(parent_hash=block_a, referee=[], txs=[txs[1]]) block_c = self.rpc.generate_custom_block(parent_hash=block_b, referee=[], txs=[txs[2]]) block_d = self.rpc.generate_custom_block(parent_hash=block_a, referee=[], txs=[txs[3]]) block_e = self.rpc.generate_custom_block(parent_hash=block_c, referee=[block_d], txs=[txs[4]]) block_f = self.rpc.generate_custom_block(parent_hash=block_e, referee=[], txs=[txs[5]]) block_g = self.rpc.generate_custom_block(parent_hash=block_f, referee=[], txs=[txs[6]]) block_h = self.rpc.generate_custom_block(parent_hash=block_e, referee=[], txs=[txs[7]]) block_i = self.rpc.generate_custom_block(parent_hash=block_g, referee=[block_h], txs=[txs[8]]) # make sure transactions have been executed parent_hash = block_i for _ in range(5): block = self.rpc.generate_custom_block(parent_hash=parent_hash, referee=[], txs=[]) parent_hash = block # check logs block_number_a = int(self.rpc.block_by_hash(block_a)['blockNumber'], 0) block_number_i = int(self.rpc.block_by_hash(block_i)['blockNumber'], 0) self.check_logs(block_number_a, block_number_i, sender) # check logs in old era for _ in range(10 * SNAPSHOT_EPOCH_COUNT): block = self.rpc.generate_custom_block(parent_hash=parent_hash, referee=[], txs=[]) parent_hash = block self.check_logs(block_number_a, block_number_i, sender) self.log.info("Pass")
import os, sys sys.path.insert(1, os.path.join(sys.path[0], '..')) import eth_utils from conflux.config import default_config from conflux.filter import Filter from conflux.rpc import RpcClient from conflux.utils import sha3 as keccak, priv_to_addr from test_framework.blocktools import create_transaction, encode_hex_0x from test_framework.test_framework import ConfluxTestFramework from test_framework.util import assert_equal, assert_is_hex_string, assert_is_hash_string from test_framework.util import * CONTRACT_PATH = "../contracts/EventsTestContract_bytecode.dat" CONSTRUCTED_TOPIC = encode_hex_0x(keccak(b"Constructed(address)")) CALLED_TOPIC = encode_hex_0x(keccak(b"Called(address,uint32)")) NUM_CALLS = 20 FULLNODE0 = 0 FULLNODE1 = 1 LIGHTNODE = 2 class LogFilteringTest(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 3 def setup_network(self): self.add_nodes(self.num_nodes)
sys.path.insert(1, os.path.join(sys.path[0], '..')) import eth_utils import rlp from conflux.filter import Filter from conflux.utils import sha3 as keccak, priv_to_addr from test_framework.blocktools import encode_hex_0x, wait_for_initial_nonce_for_address from test_framework.util import * from test_framework.mininode import * from base import Web3Base CONFLUX_CONTRACT_PATH = "../contracts/CrossSpaceEventTest/CrossSpaceEventTestConfluxSide.bytecode" EVM_CONTRACT_PATH = "../contracts/CrossSpaceEventTest/CrossSpaceEventTestEVMSide.bytecode" TEST_EVENT_TOPIC = encode_hex_0x(keccak(b"TestEvent(uint256)")) CALL_EVENT_TOPIC = encode_hex_0x( keccak(b"Call(bytes20,bytes20,uint256,uint256,bytes)")) OUTCOME_EVENT_TOPIC = encode_hex_0x(keccak(b"Outcome(bool)")) def encode_u256(number): return ("%x" % number).zfill(64) def encode_bytes20(hex): return hex.ljust(64, '0') def number_to_topic(number): return "0x" + encode_u256(number)
def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) # check storage root of non-existent contract root = self.rpc[FULLNODE0].get_storage_root( "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6") assert_equal(root["delta"], None) assert_equal(root["delta"], None) assert_equal(root["delta"], None) # deploy storage test contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # get storage root; expect: (D0, I0, S0) = (?, NULL, NULL) root0 = self.rpc[FULLNODE0].get_storage_root(contractAddr) assert_is_hash_string(root0["delta"]) assert_equal(root0["intermediate"], None) assert_equal(root0["snapshot"], None) # update storage; expect: (D1, I1, S1) == (?, I0, S0) # NOTE: call_contract will generate some blocks but it should be < SNAPSHOT_EPOCH_COUNT self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"increment()"))) root1 = self.rpc[FULLNODE0].get_storage_root(contractAddr) assert_is_hash_string(root1["delta"]) assert_ne(root1["delta"], root0["delta"]) assert_equal(root1["intermediate"], None) assert_equal(root1["snapshot"], None) # go to next era self.rpc[FULLNODE0].generate_blocks(SNAPSHOT_EPOCH_COUNT) # get storage root; expect: (D2, I2, S2) == (NULL, D1, NULL) # (the previous delta trie became the current intermediate trie) root2 = self.rpc[FULLNODE0].get_storage_root(contractAddr) assert_equal(root2["delta"], None) assert_equal(root2["intermediate"], root1["delta"]) assert_equal(root2["snapshot"], None) # update storage; expect: (D3, I3, S3) == (?, I2, S2) # NOTE: call_contract will generate some blocks but it should be < SNAPSHOT_EPOCH_COUNT self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"increment()"))) root3 = self.rpc[FULLNODE0].get_storage_root(contractAddr) assert_is_hash_string(root3["delta"]) assert_ne(root3["delta"], root2["delta"]) assert_equal(root3["intermediate"], root2["intermediate"]) assert_equal(root3["snapshot"], root2["snapshot"]) # go to next era self.rpc[FULLNODE0].generate_blocks(SNAPSHOT_EPOCH_COUNT) # get storage root; expect: (D4, I4, S4) == (NULL, D3, ?) # (the previous delta trie became the current intermediate trie) # (note that storage root in the snapshot will not match due to differences in padding) root4 = self.rpc[FULLNODE0].get_storage_root(contractAddr) assert_equal(root4["delta"], None) assert_equal(root4["intermediate"], root3["delta"]) assert_is_hash_string(root4["snapshot"]) # check if other node's storage root matches sync_blocks(self.nodes[:]) wait_until(lambda: self.rpc[FULLNODE0].epoch_number("latest_state") == self.rpc[FULLNODE1].epoch_number("latest_state")) root = self.rpc[FULLNODE1].get_storage_root(contractAddr) assert (root == root4) # destroy account # NOTE: call_contract will generate some blocks but it should be < SNAPSHOT_EPOCH_COUNTs self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"destroy()"))) root5 = self.rpc[FULLNODE0].get_storage_root(contractAddr) assert_equal(root5["delta"], "TOMBSTONE") assert_equal(root5["intermediate"], root4["intermediate"]) assert_equal(root5["snapshot"], root4["snapshot"]) self.log.info("Pass")
def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) # deploy storage test contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() tx = self.rpc.new_contract_tx(receiver="", data_hex=bytecode, sender=sender, priv_key=priv_key, storage_limit=20000) assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex()) receipt = self.rpc.get_transaction_receipt(tx.hash_hex()) contractAddr = receipt["contractCreated"] assert_is_hex_string(contractAddr) # --- # .-----------------| D |.... # V --- | # --- --- --- --- # ... <-- | A | <- | B | <- | C | <- | E | <- ... # --- --- --- --- # # A --- B --- C --- D --- E # block number 0 | 1 | 2 | 3 | 4 | # epoch number 0 | 1 | 2 | 3 | start_nonce = self.rpc.get_nonce(self.rpc.GENESIS_ADDR) txs = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 0, sender=sender, priv_key=priv_key, storage_limit=64), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 1, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 2, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), nonce=start_nonce + 3, sender=sender, priv_key=priv_key), ] block_0 = self.rpc.block_by_epoch("latest_mined")['hash'] epoch_0 = int(self.rpc.block_by_hash(block_0)['epochNumber'], 0) block_number_0 = int(self.rpc.block_by_hash(block_0)['blockNumber'], 0) block_a = self.rpc.generate_custom_block(parent_hash=block_0, referee=[], txs=[]) block_b = self.rpc.generate_custom_block(parent_hash=block_a, referee=[], txs=[]) block_c = self.rpc.generate_custom_block(parent_hash=block_b, referee=[], txs=[]) block_d = self.rpc.generate_custom_block(parent_hash=block_a, referee=[], txs=txs[0:2]) block_e = self.rpc.generate_custom_block(parent_hash=block_c, referee=[block_d], txs=txs[2:4]) # make sure transactions have been executed parent_hash = block_e for _ in range(5): block = self.rpc.generate_custom_block(parent_hash=parent_hash, referee=[], txs=[]) parent_hash = block # check logs block_number_a = int(self.rpc.block_by_hash(block_a)['blockNumber'], 0) block_number_d = int(self.rpc.block_by_hash(block_d)['blockNumber'], 0) filter = Filter(from_block=hex(block_number_a), to_block=hex(block_number_d), offset=hex(0), limit=hex(1)) logs = self.rpc.get_logs(filter) assert_equal(len(logs), 1) assert_equal(logs[0]["topics"][2], number_to_topic(2)) filter = Filter(from_block=hex(block_number_a), to_block=hex(block_number_d), offset=hex(1), limit=hex(1)) logs = self.rpc.get_logs(filter) assert_equal(len(logs), 1) assert_equal(logs[0]["topics"][2], number_to_topic(1)) filter = Filter(from_block=hex(block_number_a), to_block=hex(block_number_d), offset=hex(0), limit=hex(2)) logs = self.rpc.get_logs(filter) assert_equal(len(logs), 2) assert_equal(logs[0]["topics"][2], number_to_topic(1)) assert_equal(logs[1]["topics"][2], number_to_topic(2)) self.log.info("Pass")
def run_test(self): # initialize EVM account self.evmAccount = self.w3.eth.account.privateKeyToAccount( '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' ) print(f'Using EVM account {self.evmAccount.address}') self.cross_space_transfer(self.evmAccount.address, 1 * 10**18) assert_equal(self.nodes[0].eth_getBalance(self.evmAccount.address), hex(1 * 10**18)) # deploy Conflux space contract confluxContractAddr = self.deploy_conflux_space(CONFLUX_CONTRACT_PATH) print(f'Conflux contract: {confluxContractAddr}') # deploy EVM space contract evmContractAddr = self.deploy_evm_space(EVM_CONTRACT_PATH) print(f'EVM contract: {evmContractAddr}') # #1: call emitConflux(1) # this will emit 1 event in the Conflux space data_hex = encode_hex_0x( keccak(b"emitConflux(uint256)"))[:10] + encode_u256(1) receipt = self.call_conflux_space(confluxContractAddr, data_hex) assert_equal(len(receipt["logs"]), 1) assert_equal(receipt["logs"][0]["data"], number_to_topic(1)) # TestEvent(1) # #2: call emitBoth(2) # this will emit 2 events in the Conflux space (our contract + internal contract) and 1 event in the EVM space data_hex = encode_hex_0x( keccak(b"emitBoth(uint256,bytes20)"))[:10] + encode_u256( 2) + encode_bytes20(evmContractAddr.replace('0x', '')) receipt = self.call_conflux_space(confluxContractAddr, data_hex) assert_equal(len(receipt["logs"]), 2) assert_equal(receipt["logs"][0]["data"], number_to_topic(2)) # TestEvent(2) # NOTE: EVM-space events are not returned here # #3: call emitEVM(3) # this will emit 1 event in the EVM space data_hex = encode_hex_0x( keccak(b"emitEVM(uint256)"))[:10] + encode_u256(3) receipt = self.call_evm_space(evmContractAddr, data_hex) assert_equal(len(receipt["logs"]), 1) assert_equal(receipt["logs"][0]["data"], number_to_topic(3)) # TestEvent(3) # NOTE: EVM-space events are not returned here # check Conflux events # we expect two events from #1 and #2 filter = Filter(topics=[TEST_EVENT_TOPIC], from_epoch="earliest", to_epoch="latest_state") logs = self.rpc.get_logs(filter) assert_equal(len(logs), 2) assert_equal(logs[0]["data"], number_to_topic(1)) # TestEvent(1) assert_equal(logs[1]["data"], number_to_topic(2)) # TestEvent(2) # check EVM events # we expect two events from #2 and #3 filter = { "topics": [TEST_EVENT_TOPIC], "fromBlock": "earliest", "toBlock": "latest" } logs = self.nodes[0].eth_getLogs(filter) assert_equal(len(logs), 2) assert_equal(logs[0]["data"], number_to_topic(2)) # TestEvent(2) assert_equal(logs[0]["address"], evmContractAddr.lower()) assert_equal(logs[0]["removed"], False) assert_equal(logs[1]["data"], number_to_topic(3)) # TestEvent(3) assert_equal(logs[1]["address"], evmContractAddr.lower()) assert_equal(logs[1]["removed"], False) # TODO(thegaram): add more detailed tests once we have more control over block production # - events in pivot and non-pivot blocks # - log.blockHash and log.blockNumber should correspond to pivot block # - logIndex, transactionIndex, transactionLogIndex self.log.info("Pass")
def run_test(self): time.sleep(7) priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(privtoaddr(priv_key)) self.rpc = RpcClient(self.nodes[0]) # lock tokens in bank solc = Solc() file_dir = os.path.dirname(os.path.realpath(__file__)) staking_contract = solc.get_contract_instance( abi_file=os.path.join( file_dir, "contracts/storage_interest_staking_abi.json"), bytecode_file=os.path.join( file_dir, "contracts/storage_interest_staking_bytecode.dat"), ) gas_price = 1 gas = 50000000 self.tx_conf = { "gas": int_to_hex(gas), "gasPrice": int_to_hex(gas_price), "chainId": 0 } staking_contract_addr = Web3.toChecksumAddress( "443c409373ffd5c0bec1dddb7bec830856757b65") self.tx_conf["to"] = staking_contract_addr tx_data = eth_utils.decode_hex( staking_contract.functions.deposit( 10000 * 10**18).buildTransaction(self.tx_conf)["data"]) genesis_key = default_config["GENESIS_PRI_KEY"] genesis_addr = privtoaddr(genesis_key) tx = self.rpc.new_tx(value=0, receiver=staking_contract_addr, nonce=0, data=tx_data, gas=gas, gas_price=gas_price) self.rpc.send_tx(tx, True) # apply filter, we expect no logs filter = Filter(from_epoch="earliest", to_epoch="latest_mined") result = self.rpc.get_logs(filter) assert_equal(result, []) # deploy contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # apply filter, we expect a single log with 2 topics filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs0 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs0) assert_equal(len(logs0), 1) assert_equal(len(logs0[0]["topics"]), 2) assert_equal(logs0[0]["topics"][0], CONSTRUCTED_TOPIC) assert_equal(logs0[0]["topics"][1], self.address_to_topic(sender)) assert_equal(logs0[0]["data"], self.address_to_topic(sender)) # call method receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()"))) # apply filter, we expect two logs with 2 and 3 topics respectively filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs1 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs1) assert_equal(len(logs1), 2) assert_equal(logs1[0], logs0[0]) assert_equal(len(logs1[1]["topics"]), 3) assert_equal(logs1[1]["topics"][0], CALLED_TOPIC) assert_equal(logs1[1]["topics"][1], self.address_to_topic(sender)) assert_equal(logs1[1]["topics"][2], self.number_to_topic(1)) # apply filter for specific block, we expect a single log with 3 topics filter = Filter(block_hashes=[receipt["blockHash"]]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) assert_equal(logs[0], logs1[1]) # call many times for ii in range(0, NUM_CALLS - 2): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()"))) # apply filter, we expect NUM_CALLS log entries with inreasing uint32 fields filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) for ii in range(2, NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # apply filter for specific topics filter = Filter(topics=[CONSTRUCTED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) filter = Filter(topics=[CALLED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS - 1) filter = Filter(topics=[None, self.address_to_topic(sender)]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) # find logs with `CALLED_TOPIC` as 1st topic and `3` or `4` as 3rd topic filter = Filter(topics=[ CALLED_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 2) # apply filter with limit filter = Filter(limit=("0x%x" % (NUM_CALLS // 2))) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS // 2) # apply filter for specific contract address _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) filter = Filter(address=[contractAddr]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) filter = Filter(address=[contractAddr2]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) # apply filter to very first epoch, we expect no logs filter = Filter(from_epoch="0x0", to_epoch="0x0") result = self.rpc.get_logs(filter) assert_equal(result, []) self.log.info("Pass")
def generate_blocks(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = encode_hex(priv_to_addr(priv_key)) # deploy contract bytecode_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert(os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() _, contract_addr = self.deploy_contract(sender, priv_key, bytecode) self.log.info("Contract deployed") parent_hash = self.rpc[FULLNODE0].block_by_epoch("latest_mined")['hash'] nonce = self.rpc[FULLNODE0].get_nonce(sender) hashes = [] num_events = 0 num_blamed = 0 for _ in range(0, NORMAL_CHAIN_LENGTH): rnd = random.random() # ~20% of all block have events if rnd < 0.2: tx = self.rpc[FULLNODE0].new_contract_tx( receiver=contract_addr, data_hex=encode_hex_0x(keccak(b"foo()")), sender=sender, priv_key=priv_key, storage_limit=64, nonce = nonce ) parent_hash = self.rpc[FULLNODE0].generate_custom_block(parent_hash=parent_hash, txs=[tx], referee=[]) nonce += 1 hashes.append(tx.hash_hex()) num_events += 1 # ~10% of all blocks are incorrect and blamed elif rnd < 0.3: blame_info = {} blame_info['blame'] = "0x1" blame_info['deferredStateRoot'] = "0x1111111111111111111111111111111111111111111111111111111111111111" parent_hash = self.nodes[FULLNODE0].test_generateblockwithblameinfo(1, 0, blame_info) num_blamed += 1 # the rest are empty else: parent_hash = self.rpc[FULLNODE0].generate_block_with_parent(parent_hash=parent_hash) # TODO: generate blamed blocks with txs in them (overlap) # generate a pivot chain section where we might not be able to decide blaming # in this section, all headers will have blame=1 # odd-numbered blocks are incorrect, even-numbered blocks are correct for _ in range(0, BLAMED_SECTION_LENGTH): blame_info = {} blame_info['blame'] = "0x1" parent_hash = self.nodes[FULLNODE0].test_generateblockwithblameinfo(1, 0, blame_info) num_blamed += BLAMED_SECTION_LENGTH // 2 # mine some more blocks to keep blame check offset for _ in range(0, BLAMED_SECTION_LENGTH): parent_hash = self.rpc[FULLNODE0].generate_custom_block(parent_hash=parent_hash, txs=[], referee=[]) # check if all txs have been executed successfully for hash in hashes: receipt = self.rpc[FULLNODE0].get_transaction_receipt(hash) assert_equal(receipt["outcomeStatus"], "0x0") length = NORMAL_CHAIN_LENGTH + 2 * BLAMED_SECTION_LENGTH self.log.info(f"Generated {length} blocks with {num_events} events and {num_blamed} incorrect blocks")
def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) self.rpc = RpcClient(self.nodes[0]) # apply filter, we expect no logs filter = Filter() result = self.rpc.get_logs(filter) assert_equal(result, []) # deploy contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # apply filter, we expect a single log with 2 topics filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs0 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs0) assert_equal(len(logs0), 1) assert_equal(len(logs0[0]["topics"]), 2) assert_equal(logs0[0]["topics"][0], CONSTRUCTED_TOPIC) assert_equal(logs0[0]["topics"][1], self.address_to_topic(sender)) assert_equal(logs0[0]["data"], self.address_to_topic(sender)) # call method receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=64) # apply filter, we expect two logs with 2 and 3 topics respectively filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs1 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs1) assert_equal(len(logs1), 2) assert_equal(logs1[0], logs0[0]) assert_equal(len(logs1[1]["topics"]), 3) assert_equal(logs1[1]["topics"][0], CALLED_TOPIC) assert_equal(logs1[1]["topics"][1], self.address_to_topic(sender)) assert_equal(logs1[1]["topics"][2], self.number_to_topic(1)) # apply filter for specific block, we expect a single log with 3 topics filter = Filter(block_hashes=[receipt["blockHash"]]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) assert_equal(logs[0], logs1[1]) # call many times for ii in range(2, NUM_CALLS): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=0) # apply filter, we expect NUM_CALLS log entries with increasing uint32 fields filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) for ii in range(2, NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # apply filter for specific topics filter = Filter(topics=[CONSTRUCTED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) filter = Filter(topics=[CALLED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS - 1) filter = Filter(topics=[None, self.address_to_topic(sender)]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) # find logs with `CALLED_TOPIC` as 1st topic and `3` or `4` as 3rd topic filter = Filter(topics=[ CALLED_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 2) # apply filter with limit filter = Filter(limit=hex(NUM_CALLS // 2)) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS // 2) # apply filter for specific contract address _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) filter = Filter(address=[contractAddr]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) filter = Filter(address=[contractAddr2]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) # apply filter to very first epoch, we expect no logs filter = Filter(from_epoch="earliest", to_epoch="earliest") result = self.rpc.get_logs(filter) assert_equal(result, []) # generate two blocks with `NUM_CALLS` valid logs in each parent_hash = self.rpc.block_by_epoch("latest_mined")['hash'] start_nonce = self.rpc.get_nonce(sender) txs = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), sender=sender, priv_key=priv_key, storage_limit=64, nonce=start_nonce + ii) for ii in range(0, NUM_CALLS) ] block_hash_1 = self.rpc.generate_custom_block(parent_hash=parent_hash, referee=[], txs=txs) txs = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"foo()")), sender=sender, priv_key=priv_key, storage_limit=64, nonce=start_nonce + NUM_CALLS + ii) for ii in range(0, NUM_CALLS) ] block_hash_2 = self.rpc.generate_custom_block(parent_hash=block_hash_1, referee=[], txs=txs) # blocks not executed yet, filtering should fail filter = Filter(block_hashes=[block_hash_1, block_hash_2]) assert_raises_rpc_error(None, None, self.rpc.get_logs, filter) # generate some more blocks to ensure our two blocks are executed self.rpc.generate_blocks(10) # filtering for these two blocks should return logs in correct order filter = Filter(block_hashes=[block_hash_1, block_hash_2]) logs = self.rpc.get_logs(filter) assert_equal(len(logs), 2 * NUM_CALLS) for ii in range(0, 2 * NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii + NUM_CALLS)) # block hash order should not affect log order filter = Filter(block_hashes=[block_hash_2, block_hash_1]) logs2 = self.rpc.get_logs(filter) assert_equal(logs, logs2) # given a limit, we should receive the _last_ few logs filter = Filter(block_hashes=[block_hash_1, block_hash_2], limit=hex(NUM_CALLS + NUM_CALLS // 2)) logs = self.rpc.get_logs(filter) assert_equal(len(logs), NUM_CALLS + NUM_CALLS // 2) for ii in range(0, NUM_CALLS + NUM_CALLS // 2): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii + NUM_CALLS + NUM_CALLS // 2)) self.log.info("Pass")
import os, sys sys.path.insert(1, os.path.join(sys.path[0], '..')) import eth_utils from conflux.config import default_config from conflux.filter import Filter from conflux.rpc import RpcClient from conflux.utils import sha3 as keccak, priv_to_addr from test_framework.blocktools import create_transaction, encode_hex_0x from test_framework.test_framework import ConfluxTestFramework from test_framework.util import assert_equal, assert_is_hex_string, assert_is_hash_string from test_framework.util import * CONTRACT_PATH = "../contracts/EventsTestContract_bytecode.dat" CONSTRUCTED_TOPIC = encode_hex_0x(keccak(b"Constructed(address)")) FOO_TOPIC = encode_hex_0x(keccak(b"Foo(address,uint32)")) NUM_CALLS = 20 FULLNODE0 = 0 FULLNODE1 = 1 LIGHTNODE = 2 class LogFilteringTest(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 3 def setup_network(self): self.add_nodes(self.num_nodes) self.start_node(FULLNODE0, ["--archive"])
def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) self.rpc = RpcClient(self.nodes[0]) # apply filter, we expect no logs filter = Filter() result = self.rpc.get_logs(filter) assert_equal(result, []) # deploy contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # apply filter, we expect a single log with 2 topics filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs0 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs0) assert_equal(len(logs0), 1) assert_equal(len(logs0[0]["topics"]), 2) assert_equal(logs0[0]["topics"][0], CONSTRUCTED_TOPIC) assert_equal(logs0[0]["topics"][1], self.address_to_topic(sender)) assert_equal(logs0[0]["data"], self.address_to_topic(sender)) # call method receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=64) # apply filter, we expect two logs with 2 and 3 topics respectively filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs1 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs1) assert_equal(len(logs1), 2) assert_equal(logs1[0], logs0[0]) assert_equal(len(logs1[1]["topics"]), 3) assert_equal(logs1[1]["topics"][0], FOO_TOPIC) assert_equal(logs1[1]["topics"][1], self.address_to_topic(sender)) assert_equal(logs1[1]["topics"][2], self.number_to_topic(1)) # apply filter for specific block, we expect a single log with 3 topics filter = Filter(block_hashes=[receipt["blockHash"]]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) assert_equal(logs[0], logs1[1]) # call many times for ii in range(2, NUM_CALLS): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()")), storage_limit=0) # apply filter, we expect NUM_CALLS log entries with increasing uint32 fields filter = Filter(from_epoch="earliest", to_epoch="latest_state") logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) for ii in range(2, NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], FOO_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # apply filter for specific topics filter = Filter(topics=[CONSTRUCTED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) filter = Filter(topics=[FOO_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS - 1) filter = Filter(topics=[None, self.address_to_topic(sender)]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) # find logs with `FOO_TOPIC` as 1st topic and `3` or `4` as 3rd topic filter = Filter(topics=[ FOO_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 2) # apply filter with limit filter = Filter(limit=hex(NUM_CALLS // 2)) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS // 2) # apply filter for specific contract address _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) filter = Filter(address=[contractAddr]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) filter = Filter(address=[contractAddr2]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) # apply filter to very first epoch, we expect no logs filter = Filter(from_epoch="earliest", to_epoch="earliest") result = self.rpc.get_logs(filter) assert_equal(result, []) # generate two blocks with `NUM_CALLS` transactions in each; # transactions will generate 2 logs each parent_hash = self.rpc.block_by_epoch("latest_mined")['hash'] start_nonce = self.rpc.get_nonce(sender) txs1 = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"bar()")), sender=sender, priv_key=priv_key, storage_limit=64, nonce=start_nonce + ii) for ii in range(0, NUM_CALLS) ] block_hash_1 = self.rpc.generate_custom_block(parent_hash=parent_hash, referee=[], txs=txs1) epoch_1 = self.rpc.block_by_hash(block_hash_1)["epochNumber"] txs2 = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x(keccak(b"bar()")), sender=sender, priv_key=priv_key, storage_limit=64, nonce=start_nonce + NUM_CALLS + ii) for ii in range(0, NUM_CALLS) ] block_hash_2 = self.rpc.generate_custom_block(parent_hash=block_hash_1, referee=[], txs=txs2) epoch_2 = self.rpc.block_by_hash(block_hash_2)["epochNumber"] txs = txs1 txs.extend(txs2) # blocks not executed yet, filtering should fail # filter = Filter(block_hashes=[block_hash_1, block_hash_2], topics=[BAR_TOPIC]) # assert_raises_rpc_error(None, None, self.rpc.get_logs, filter) # generate some more blocks to ensure our two blocks are executed self.rpc.generate_blocks(10) # filtering for these two blocks should return logs in correct order filter = Filter(block_hashes=[block_hash_1, block_hash_2], topics=[BAR_TOPIC]) logs = self.rpc.get_logs(filter) assert_equal(len(logs), 4 * NUM_CALLS) log_index = 0 transaction_index = 0 transaction_log_index = 0 for ii in range(0, 4 * NUM_CALLS): assert_equal(logs[ii]["address"], contractAddr) assert_equal(logs[ii]["blockHash"], block_hash_1 if ii < 2 * NUM_CALLS else block_hash_2) assert_equal(logs[ii]["epochNumber"], epoch_1 if ii < 2 * NUM_CALLS else epoch_2) assert_equal(logs[ii]["transactionHash"], txs[ii // 2].hash_hex()) assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], BAR_TOPIC) assert_equal(logs[ii]["topics"][1], self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # logIndex: # 0, 1, 2, 3, 4, 6, 7, 8, ..., 2 * NUM_CALLS, 0, 1, 2, ... assert_equal(logs[ii]["logIndex"], hex(log_index % (2 * NUM_CALLS))) log_index += 1 # transactionIndex: # 0, 0, 1, 1, 2, 2, 3, 3, ..., NUM_CALLS, 0, 0, 1, 1, ... assert_equal(logs[ii]["transactionIndex"], hex((transaction_index // 2) % NUM_CALLS)) transaction_index += 1 # transactionLogIndex: # 0, 1, 0, 1, 0, 1, 0, 1, ... assert_equal(logs[ii]["transactionLogIndex"], hex(transaction_log_index % 2)) transaction_log_index += 1 # block hash order should not affect log order filter = Filter(block_hashes=[block_hash_2, block_hash_1], topics=[BAR_TOPIC]) logs2 = self.rpc.get_logs(filter) assert_equal(logs, logs2) # given a limit, we should receive the _last_ few logs filter = Filter(block_hashes=[block_hash_1, block_hash_2], limit=hex(3 * NUM_CALLS + NUM_CALLS // 2), topics=[BAR_TOPIC]) logs = self.rpc.get_logs(filter) assert_equal(len(logs), 3 * NUM_CALLS + NUM_CALLS // 2) for ii in range(0, 3 * NUM_CALLS + NUM_CALLS // 2): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], BAR_TOPIC) assert_equal(logs[ii]["topics"][1], self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(NUM_CALLS // 2 + ii)) # get-logs-filter-max-epoch-range should limit the number of epochs queried. self.stop_node(0) self.start_node(0, ["--get-logs-filter-max-epoch-range", "16"]) filter = Filter(from_epoch="0x0", to_epoch="0x0f", topics=[BAR_TOPIC]) # should not raise error self.rpc.get_logs(filter) filter = Filter(from_epoch="0x0", to_epoch="0x10", topics=[BAR_TOPIC]) assert_raises_rpc_error(None, None, self.rpc.get_logs, filter) self.log.info("Pass")
import eth_utils import rlp from conflux.filter import Filter from conflux.rpc import RpcClient from conflux.utils import sha3 as keccak, priv_to_addr from test_framework.blocktools import encode_hex_0x, wait_for_initial_nonce_for_address from test_framework.test_framework import ConfluxTestFramework from test_framework.util import * from test_framework.mininode import * from web3 import Web3 CONFLUX_CONTRACT_PATH = "../contracts/CrossSpaceEventTest/CrossSpaceEventTestConfluxSide.bytecode" EVM_CONTRACT_PATH = "../contracts/CrossSpaceEventTest/CrossSpaceEventTestEVMSide.bytecode" TEST_EVENT_TOPIC = encode_hex_0x(keccak(b"TestEvent(uint256)")) def encode_u256(number): return ("%x" % number).zfill(64) def encode_bytes20(hex): return hex.ljust(64, '0') def number_to_topic(number): return "0x" + encode_u256(number) class PhantomTransactionTest(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 1 self.conf_parameters["chain_id"] = str(10) self.conf_parameters["evm_chain_id"] = str(11)
def run_test(self): time.sleep(7) priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(privtoaddr(priv_key)) self.rpc = RpcClient(self.nodes[0]) # apply filter, we expect no logs filter = Filter(from_epoch="earliest", to_epoch="latest_mined") result = self.rpc.get_logs(filter) assert_equal(result, []) # deploy contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() _, contractAddr = self.deploy_contract(sender, priv_key, bytecode) # apply filter, we expect a single log with 2 topics filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs0 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs0) assert_equal(len(logs0), 1) assert_equal(len(logs0[0]["topics"]), 2) assert_equal(logs0[0]["topics"][0], CONSTRUCTED_TOPIC) assert_equal(logs0[0]["topics"][1], self.address_to_topic(sender)) # call method receipt = self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()"))) # apply filter, we expect two logs with 2 and 3 topics respectively filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs1 = self.rpc.get_logs(filter) self.assert_response_format_correct(logs1) assert_equal(len(logs1), 2) assert_equal(logs1[0], logs0[0]) assert_equal(len(logs1[1]["topics"]), 3) assert_equal(logs1[1]["topics"][0], CALLED_TOPIC) assert_equal(logs1[1]["topics"][1], self.address_to_topic(sender)) assert_equal(logs1[1]["topics"][2], self.number_to_topic(1)) # apply filter for specific block, we expect a single log with 3 topics filter = Filter(block_hashes=[receipt["blockHash"]]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) assert_equal(logs[0], logs1[1]) # call many times for ii in range(0, NUM_CALLS - 2): self.call_contract(sender, priv_key, contractAddr, encode_hex_0x(keccak(b"foo()"))) # apply filter, we expect NUM_CALLS log entries with inreasing uint32 fields filter = Filter(from_epoch="earliest", to_epoch="latest_mined") logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) for ii in range(2, NUM_CALLS): assert_equal(len(logs[ii]["topics"]), 3) assert_equal(logs[ii]["topics"][0], CALLED_TOPIC) assert (logs[ii]["topics"][1] == self.address_to_topic(sender)) assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii)) # apply filter for specific topics filter = Filter(topics=[CONSTRUCTED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) filter = Filter(topics=[CALLED_TOPIC]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS - 1) filter = Filter(topics=[None, self.address_to_topic(sender)]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) # find logs with `CALLED_TOPIC` as 1st topic and `3` or `4` as 3rd topic filter = Filter(topics=[ CALLED_TOPIC, None, [self.number_to_topic(3), self.number_to_topic(4)] ]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 2) # apply filter with limit filter = Filter(limit=("0x%x" % (NUM_CALLS // 2))) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS // 2) # apply filter for specific contract address _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode) filter = Filter(address=[contractAddr]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), NUM_CALLS) filter = Filter(address=[contractAddr2]) logs = self.rpc.get_logs(filter) self.assert_response_format_correct(logs) assert_equal(len(logs), 1) # apply filter to very first epoch, we expect no logs filter = Filter(from_epoch="0x0", to_epoch="0x0") result = self.rpc.get_logs(filter) assert_equal(result, []) self.log.info("Pass")
import os, sys, time import eth_utils sys.path.insert(1, os.path.dirname(sys.path[0])) from conflux.config import default_config from conflux.filter import Filter from conflux.rpc import RpcClient from conflux.utils import sha3 as keccak, priv_to_addr from test_framework.blocktools import create_transaction, encode_hex_0x from test_framework.test_framework import ConfluxTestFramework from test_framework.util import * from test_framework.mininode import * CONTRACT_PATH = "../contracts/EventsTestContract_bytecode.dat" FOO_TOPIC = encode_hex_0x(keccak(b"Foo(address,uint32)")) ARCHIVE_NODE = 0 FULL_NODE = 1 NUM_ERAS = 10 ERA_EPOCH_COUNT = 100 class Issue1513Test(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 2 # set era and snapshot length self.conf_parameters["era_epoch_count"] = str(ERA_EPOCH_COUNT) self.conf_parameters["dev_snapshot_epoch_count"] = str(
def run_test(self): priv_key = default_config["GENESIS_PRI_KEY"] sender = eth_utils.encode_hex(priv_to_addr(priv_key)) # deploy storage test contract bytecode_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH) assert (os.path.isfile(bytecode_file)) bytecode = open(bytecode_file).read() tx = self.rpc.new_contract_tx(receiver="", data_hex=bytecode, sender=sender, priv_key=priv_key, storage_limit=20000) assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex()) receipt = self.rpc.get_transaction_receipt(tx.hash_hex()) contractAddr = receipt["contractCreated"] assert_is_hex_string(contractAddr) # --- --- --- --- # .- | A | <--- | C | <--- | D | <--- | E | <--- ... # --- | --- --- --- --- # ... <--- | P | <-* . # --- | --- . # .- | B | <.................. # --- # 0 --- A --- C --- B --- D --- # block number: x | x+1 | x+2 | x+3 | x+4 | # epoch number: y | y+1 | y+2 | y + 3 | start_nonce = self.rpc.get_nonce(self.rpc.GENESIS_ADDR) epoch_number_p = int( self.rpc.block_by_epoch("latest_mined")['epochNumber'], 0) block_number_p = int( self.rpc.block_by_epoch("latest_mined")['epochNumber'], 0) assert_equal(epoch_number_p, block_number_p) block_p = self.rpc.block_by_epoch("latest_mined")['hash'] txs = [ self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x( keccak(b"getBlockNumber()")), nonce=start_nonce + 0, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x( keccak(b"getEpochNumber()")), nonce=start_nonce + 1, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x( keccak(b"getBlockNumber()")), nonce=start_nonce + 2, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x( keccak(b"getEpochNumber()")), nonce=start_nonce + 3, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x( keccak(b"getBlockNumber()")), nonce=start_nonce + 4, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x( keccak(b"getEpochNumber()")), nonce=start_nonce + 5, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x( keccak(b"getBlockNumber()")), nonce=start_nonce + 6, sender=sender, priv_key=priv_key), self.rpc.new_contract_tx(receiver=contractAddr, data_hex=encode_hex_0x( keccak(b"getEpochNumber()")), nonce=start_nonce + 7, sender=sender, priv_key=priv_key), ] block_a = self.rpc.generate_custom_block(parent_hash=block_p, referee=[], txs=txs[0:2]) block_c = self.rpc.generate_custom_block(parent_hash=block_a, referee=[], txs=txs[2:4]) block_b = self.rpc.generate_custom_block(parent_hash=block_p, referee=[], txs=txs[4:6]) block_d = self.rpc.generate_custom_block(parent_hash=block_c, referee=[block_b], txs=txs[6:8]) # make sure transactions have been executed parent_hash = block_d for _ in range(5): block = self.rpc.generate_custom_block(parent_hash=parent_hash, referee=[], txs=[]) parent_hash = block # transactions in block A # note: topic-1 of each log is the emitted block/epoch number block_number_a = int( self.rpc.get_transaction_receipt( txs[0].hash_hex())['logs'][0]['topics'][1], 16) epoch_number_a = int( self.rpc.get_transaction_receipt( txs[1].hash_hex())['logs'][0]['topics'][1], 16) assert_equal(block_number_a, block_number_p + 1) assert_equal(epoch_number_a, epoch_number_p + 1) # transactions in block B block_number_b = int( self.rpc.get_transaction_receipt( txs[4].hash_hex())['logs'][0]['topics'][1], 16) epoch_number_b = int( self.rpc.get_transaction_receipt( txs[5].hash_hex())['logs'][0]['topics'][1], 16) assert_equal(block_number_b, block_number_p + 3) assert_equal(epoch_number_b, epoch_number_p + 3) # transactions in block C block_number_c = int( self.rpc.get_transaction_receipt( txs[2].hash_hex())['logs'][0]['topics'][1], 16) epoch_number_c = int( self.rpc.get_transaction_receipt( txs[3].hash_hex())['logs'][0]['topics'][1], 16) assert_equal(block_number_c, block_number_p + 2) assert_equal(epoch_number_c, epoch_number_p + 2) # transactions in block d block_number_d = int( self.rpc.get_transaction_receipt( txs[6].hash_hex())['logs'][0]['topics'][1], 16) epoch_number_d = int( self.rpc.get_transaction_receipt( txs[7].hash_hex())['logs'][0]['topics'][1], 16) assert_equal(block_number_d, block_number_p + 4) assert_equal(epoch_number_d, epoch_number_p + 3) self.log.info("Pass")