Exemple #1
0
    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")
Exemple #2
0
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
Exemple #3
0
    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")
Exemple #4
0
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")
Exemple #8
0
    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")
Exemple #10
0
    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")
Exemple #11
0
    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"])
Exemple #13
0
    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")
Exemple #14
0
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")
Exemple #16
0
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(
Exemple #17
0
    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")