Exemple #1
0
    def run_test(self):
        # Prevent easysolc from configuring the root logger to print to stderr
        self.log.propagate = False

        solc = Solc()
        erc20_contract = solc.get_contract_instance(
            source=os.path.dirname(os.path.realpath(__file__)) + "/erc20.sol",
            contract_name="FixedSupplyToken")

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = default_config["GENESIS_PRI_KEY"]
        genesis_addr = privtoaddr(genesis_key)
        nonce = 0
        gas_price = 1
        gas = 50000000
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        self.tx_conf = {
            "from": Web3.toChecksumAddress(encode_hex_0x(genesis_addr)),
            "nonce": int_to_hex(nonce),
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price)
        }
        raw_create = erc20_contract.constructor().buildTransaction(
            self.tx_conf)
        tx_data = decode_hex(raw_create["data"])
        tx_create = create_transaction(pri_key=genesis_key,
                                       receiver=b'',
                                       nonce=nonce,
                                       gas_price=gas_price,
                                       data=tx_data,
                                       gas=gas,
                                       value=0)
        self.nodes[0].p2p.send_protocol_msg(
            Transactions(transactions=[tx_create]))
        self.wait_for_tx([tx_create])
        self.log.info("Contract created, start transfering tokens")

        tx_n = 10
        self.tx_conf["to"] = Web3.toChecksumAddress(
            encode_hex_0x(sha3_256(rlp.encode([genesis_addr, nonce]))[-20:]))
        nonce += 1
        balance_map = {genesis_key: 1000000 * 10**18}
        sender_key = genesis_key
        all_txs = []
        for i in range(tx_n):
            value = int((balance_map[sender_key] -
                         ((tx_n - i) * 21000 * gas_price)) * random.random())
            receiver_sk, _ = ec_random_keys()
            balance_map[receiver_sk] = value
            tx_data = decode_hex(
                erc20_contract.functions.transfer(
                    Web3.toChecksumAddress(encode_hex(
                        privtoaddr(receiver_sk))),
                    value).buildTransaction(self.tx_conf)["data"])
            tx = create_transaction(pri_key=sender_key,
                                    receiver=decode_hex(self.tx_conf["to"]),
                                    value=0,
                                    nonce=nonce,
                                    gas=gas,
                                    gas_price=gas_price,
                                    data=tx_data)
            r = random.randint(0, self.num_nodes - 1)
            self.nodes[r].p2p.send_protocol_msg(
                Transactions(transactions=[tx]))
            nonce += 1
            balance_map[sender_key] -= value
            all_txs.append(tx)
        self.log.info("Wait for transactions to be executed")
        self.wait_for_tx(all_txs)
        self.log.info("Check final token balance")
        for sk in balance_map:
            addr = privtoaddr(sk)
            assert_equal(self.get_balance(erc20_contract, addr, nonce),
                         balance_map[sk])
        block_gen_thread.stop()
        block_gen_thread.join()
        sync_blocks(self.nodes)
        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 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=[FOO_TOPIC]))
        self.check_filter(Filter(topics=[None, self.address_to_topic(sender)]))
        self.check_filter(Filter(topics=[FOO_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")
    def run_test(self):
        file_path = os.path.dirname(os.path.realpath(__file__)).split("/")
        file_path.pop(-1)
        file_path.extend(["internal_contract", "metadata", "Staking.json"])
        file_path = "/".join(file_path)
        staking_contract_dict = json.loads(
            open(os.path.join(file_path), "r").read())
        staking_contract = get_contract_instance(
            contract_dict=staking_contract_dict)
        staking_contract_addr = Web3.toChecksumAddress(
            "0888000000000000000000000000000000000002")

        self.problem = "0x2bc79b7514884ab00da924607d71542cc4fed3beb8518e747726ae30ab6c7944"
        self.solution = "0xc4d2751c52311d0d7efe44e5c4195e058ad5ef4bb89b3e1761b24dc277b132c2"
        self.priv_key = default_config["GENESIS_PRI_KEY"]
        self.sender = encode_hex_0x(priv_to_addr(self.priv_key))
        self.sender_checksum = Web3.toChecksumAddress(self.sender)
        self.pub = []
        self.pri = []
        self.rpc = RpcClient(self.nodes[0])
        gas = CONTRACT_DEFAULT_GAS
        gas_price = 10

        # lock token for genesis account
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.tx_conf['to'] = staking_contract_addr
        tx_data = decode_hex(
            staking_contract.functions.deposit(
                1000000 * 10**18).buildTransaction(self.tx_conf)["data"])
        tx = self.rpc.new_tx(value=0,
                             receiver=staking_contract_addr,
                             data=tx_data,
                             gas=gas,
                             gas_price=gas_price)
        self.rpc.send_tx(tx, True)

        for i in range(10):
            priv_key = random.randint(0, 2**256).to_bytes(32, "big")
            pub_key = encode_hex_0x(priv_to_addr(priv_key))
            self.pub.append(pub_key)
            self.pri.append(priv_key)
            transaction = self.rpc.new_tx(sender=self.sender,
                                          receiver=pub_key,
                                          value=1000000 * 10**18,
                                          priv_key=self.priv_key)
            self.rpc.send_tx(transaction, True)
            # deposit 10000 tokens
            tx_data = decode_hex(
                staking_contract.functions.deposit(
                    10000 * 10**18).buildTransaction(self.tx_conf)["data"])
            tx = self.rpc.new_tx(value=0,
                                 sender=pub_key,
                                 receiver=self.tx_conf["to"],
                                 gas=gas,
                                 data=tx_data,
                                 priv_key=priv_key)
            self.rpc.send_tx(tx)
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.filter = Filter(from_epoch="earliest", to_epoch="latest_state")
        self.testEventContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testBallotContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testPayContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testHTLCContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testDaiContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testMappingContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testDaiJoinContract()
        self.log.info("Pass")
Exemple #4
0
    def run_test(self):
        # Prevent easysolc from configuring the root logger to print to stderr
        self.log.propagate = False

        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"),
        )

        commission_privilege_contract = solc.get_contract_instance(
            abi_file=os.path.join(
                file_dir, "contracts/commission_privilege_control_abi.json"),
            bytecode_file=os.path.join(
                file_dir,
                "contracts/commission_privilege_control_bytecode.dat"),
        )

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = self.genesis_priv_key
        genesis_addr = self.genesis_addr
        self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr)))
        nonce = 0
        gas_price = 1
        gas = 50000000
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        self.tx_conf = {
            "from": Web3.toChecksumAddress(encode_hex_0x(genesis_addr)),
            "nonce": int_to_hex(nonce),
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }

        # Setup balance for node 0
        node = self.nodes[0]
        client = RpcClient(node)
        (addr, priv_key) = client.rand_account()
        self.log.info("addr=%s priv_key=%s", addr, priv_key)
        tx = client.new_tx(value=5 * 10**18,
                           receiver=addr,
                           nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(node.cfx_getBalance(addr), hex(5000000000000000000))
        assert_equal(node.cfx_getBankBalance(addr), hex(0))

        self.tx_conf["to"] = Web3.toChecksumAddress(
            "443c409373ffd5c0bec1dddb7bec830856757b65")
        # deposit 2 * 10**18 / 16
        tx_data = decode_hex(
            staking_contract.functions.deposit(
                2 * 10**18 // 16).buildTransaction(self.tx_conf)["data"])
        tx = client.new_tx(value=0,
                           receiver=self.tx_conf["to"],
                           nonce=self.get_nonce(genesis_addr),
                           gas=gas,
                           data=tx_data)
        client.send_tx(tx, True)
        assert_equal(node.cfx_getBankBalance(encode_hex(genesis_addr)),
                     hex(2 * 10**18 // 16))

        # setup contract
        transaction = self.call_contract_function(
            contract=commission_privilege_contract,
            name="constructor",
            args=[],
            sender_key=self.genesis_priv_key)
        contract_addr = self.wait_for_tx([transaction],
                                         True)[0]['contractCreated']
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(node.cfx_getBalance(contract_addr), hex(0))

        # setup balance
        transaction = self.call_contract_function(
            contract=commission_privilege_contract,
            name="set",
            args=[],
            sender_key=genesis_key,
            contract_addr=contract_addr,
            value=10**18,
            wait=True,
            check_status=True)
        assert_equal(node.cfx_getBalance(contract_addr), hex(10**18))

        # call contract with privilege
        geneis_balance = node.cfx_getBalance(encode_hex(genesis_addr))
        transaction = self.call_contract_function(
            contract=commission_privilege_contract,
            name="foo",
            args=[],
            sender_key=genesis_key,
            contract_addr=contract_addr,
            wait=True,
            check_status=True)
        assert_equal(node.cfx_getBalance(contract_addr), hex(10**18 - gas))
        assert_equal(node.cfx_getBalance(encode_hex(genesis_addr)),
                     geneis_balance)

        # call contract without privilege and remove privilege of genesis
        transaction = self.call_contract_function(
            contract=commission_privilege_contract,
            name="remove",
            args=[],
            sender_key=priv_key,
            contract_addr=contract_addr,
            wait=True,
            check_status=True)
        assert_equal(node.cfx_getBalance(contract_addr), hex(10**18 - gas))
        assert_equal(node.cfx_getBalance(addr), hex(5 * 10**18 - gas))

        # call contract after removing privilege
        geneis_balance = int(node.cfx_getBalance(encode_hex(genesis_addr)), 16)
        transaction = self.call_contract_function(
            contract=commission_privilege_contract,
            name="foo",
            args=[],
            sender_key=genesis_key,
            contract_addr=contract_addr,
            wait=True,
            check_status=True)
        assert_equal(node.cfx_getBalance(contract_addr), hex(10**18 - gas))

        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 #6
0
from eth_utils import decode_hex
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, bytes_to_int
from test_framework.blocktools import encode_hex_0x
from test_framework.test_framework import ConfluxTestFramework
from test_framework.util import assert_equal, assert_ne, 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
        self.conf_parameters["log_level"] = '"trace"'
        self.conf_parameters["pos_pivot_decision_defer_epoch_count"] = '200'

    def setup_network(self):
        self.add_nodes(self.num_nodes)

        self.start_node(FULLNODE0, ["--archive"])
        self.start_node(FULLNODE1, ["--archive"])
    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, 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 (root0 != None)
        assert (root0["delta"] != NULL_NODE)
        assert (root0["intermediate"] == NULL_NODE)
        assert (root0["snapshot"] == NULL_NODE)

        # 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 (root1["delta"] != root0["delta"])
        assert (root1["intermediate"] == root0["intermediate"])
        assert (root1["snapshot"] == root0["snapshot"])

        # go to next era
        self.rpc[FULLNODE0].generate_blocks(SNAPSHOT_EPOCH_COUNT)

        # get storage root; expect: (D2, I2, S2) == (NULL, D1, ?)
        # (the previous delta trie became the current intermediate trie)
        # (note that storage root in the snapshot will not match due to differences in padding)
        root2 = self.rpc[FULLNODE0].get_storage_root(contractAddr)

        assert (root2["delta"] == NULL_NODE)
        assert (root2["intermediate"] == root1["delta"])

        # update storage; expect: (D3, I3, S3) == (?, D2, 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 (root3["delta"] != root2["delta"])
        assert (root3["intermediate"] == root2["intermediate"])
        assert (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 (root4["delta"] == NULL_NODE)
        assert (root4["intermediate"] == root3["delta"])

        # check if other node's storage root matches
        sync_blocks(self.nodes[:])
        root = self.rpc[FULLNODE1].get_storage_root(contractAddr)
        assert (root == root4)

        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):
        file_dir = os.path.dirname(os.path.realpath(__file__))

        test_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/issue988_abi.json"),
            bytecode_file=os.path.join(file_dir,
                                       "contracts/issue988_bytecode.dat"),
        )

        start_p2p_connection(self.nodes)

        genesis_key = self.genesis_priv_key
        genesis_addr = self.genesis_addr
        self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr)))
        nonce = 0
        gas_price = 1
        gas = 50000000
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        self.tx_conf = {
            "from": Web3.toChecksumAddress(encode_hex_0x(genesis_addr)),
            "nonce": int_to_hex(nonce),
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }

        # setup balance for node 0
        node = self.nodes[0]
        client = RpcClient(node)
        (addr, priv_key) = client.rand_account()
        self.log.info("addr=%s priv_key=%s", addr, priv_key)
        tx = client.new_tx(value=20 * 10**18,
                           receiver=addr,
                           nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(node.cfx_getBalance(addr), hex(20000000000000000000))

        # deploy test contract
        c0 = client.get_collateral_for_storage(addr)
        tx = self.call_contract_function(contract=test_contract,
                                         name="constructor",
                                         args=[],
                                         sender_key=priv_key,
                                         storage_limit=10604)
        contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated']
        c1 = client.get_collateral_for_storage(addr)
        assert_equal(c1 - c0, 10604 * 10**18 // 1024)
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(node.cfx_getBalance(contract_addr), hex(0))

        raw_result = self.call_contract_function_rpc(
            contract=test_contract,
            name="ktrriiwhlx",
            args=[],
            contract_addr=contract_addr)
        result = signed_bytes_to_int256(decode_hex(raw_result))
        assert_equal(result, -12076)

        raw_result = self.call_contract_function_rpc(
            contract=test_contract,
            name="qiwmzrxuhd",
            args=[],
            contract_addr=contract_addr)
        result = signed_bytes_to_int256(decode_hex(raw_result))
        assert_equal(result, -2)

        raw_result = self.call_contract_function_rpc(
            contract=test_contract,
            name="wxqpwecckl",
            args=[],
            contract_addr=contract_addr)
        result = signed_bytes_to_int256(decode_hex(raw_result))
        assert_equal(result, -1)

        self.log.info("Pass")
Exemple #10
0
    def run_test(self):
        file_dir = os.path.dirname(os.path.realpath(__file__))
        erc20_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/erc20_abi.json"),
            bytecode_file=os.path.join(file_dir,
                                       "contracts/erc20_bytecode.dat"),
        )

        gas_price = 1
        gas = CONTRACT_DEFAULT_GAS

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = default_config["GENESIS_PRI_KEY"]
        genesis_addr = encode_hex_0x(priv_to_addr(genesis_key))
        nonce = 0
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        self.tx_conf = {
            "from": Web3.toChecksumAddress(genesis_addr),
            "nonce": int_to_hex(nonce),
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        raw_create = erc20_contract.constructor().buildTransaction(
            self.tx_conf)
        tx_data = decode_hex(raw_create["data"])
        tx_create = create_transaction(pri_key=genesis_key,
                                       receiver=b'',
                                       nonce=nonce,
                                       gas_price=gas_price,
                                       data=tx_data,
                                       gas=gas,
                                       value=0,
                                       storage_limit=1920)
        self.client = RpcClient(self.nodes[0])
        c0 = self.client.get_collateral_for_storage(genesis_addr)
        self.client.send_tx(tx_create, True)
        receipt = self.client.get_transaction_receipt(tx_create.hash_hex())
        c1 = self.client.get_collateral_for_storage(genesis_addr)
        assert_equal(c1 - c0, 1920 * 10**18 / 1024)
        contract_addr = receipt['contractCreated']
        self.log.info("Contract " + str(contract_addr) +
                      " created, start transferring tokens")

        tx_n = 10
        self.tx_conf["to"] = contract_addr
        nonce += 1
        balance_map = {genesis_key: 1000000 * 10**18}
        sender_key = genesis_key
        all_txs = []
        for i in range(tx_n):
            value = int((balance_map[sender_key] -
                         ((tx_n - i) * 21000 * gas_price)) * random.random())
            receiver_sk, _ = ec_random_keys()
            balance_map[receiver_sk] = value
            tx_data = decode_hex(
                erc20_contract.functions.transfer(
                    Web3.toChecksumAddress(
                        encode_hex(priv_to_addr(receiver_sk))),
                    value).buildTransaction(self.tx_conf)["data"])
            tx = create_transaction(pri_key=sender_key,
                                    receiver=decode_hex(self.tx_conf["to"]),
                                    value=0,
                                    nonce=nonce,
                                    gas=gas,
                                    gas_price=gas_price,
                                    data=tx_data,
                                    storage_limit=64)
            r = random.randint(0, self.num_nodes - 1)
            self.nodes[r].p2p.send_protocol_msg(
                Transactions(transactions=[tx]))
            nonce += 1
            balance_map[sender_key] -= value
            all_txs.append(tx)
        self.log.info("Wait for transactions to be executed")
        self.wait_for_tx(all_txs)
        self.log.info("Check final token balance")
        for sk in balance_map:
            addr = priv_to_addr(sk)
            assert_equal(self.get_balance(erc20_contract, addr),
                         balance_map[sk])
        c2 = self.client.get_collateral_for_storage(genesis_addr)
        assert_equal(c2 - c1, 64 * tx_n * 10**18 / 1024)
        block_gen_thread.stop()
        block_gen_thread.join()
        sync_blocks(self.nodes)
        self.log.info("Pass")
Exemple #11
0
import eth_utils

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 CrossSpaceLogFilteringTest(ConfluxTestFramework):
Exemple #12
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 i in range(0, NORMAL_CHAIN_LENGTH):
            if i % (2 * ERA_EPOCH_COUNT) == 0:
                # Leave some time for PoS to progress, so we can avoid cross-checkpoint reference.
                time.sleep(1)
            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 #13
0
from eth_utils import encode_hex
from test_framework.blocktools import encode_hex_0x
from test_framework.test_framework import ConfluxTestFramework
from test_framework.util import assert_equal, connect_nodes, sync_blocks

FULLNODE0 = 0
FULLNODE1 = 1
LIGHTNODE = 2

ERA_EPOCH_COUNT = 100
NORMAL_CHAIN_LENGTH = 1000
BLAMED_SECTION_LENGTH = 100
BLAME_CHECK_OFFSET = 30

CONTRACT_PATH = "../contracts/EventsTestContract_bytecode.dat"
FOO_TOPIC = encode_hex_0x(keccak(b"Foo(address,uint32)"))


class LightSyncTest(ConfluxTestFramework):
    def set_test_params(self):
        self.num_nodes = 3

        # set era and snapshot length
        self.conf_parameters["era_epoch_count"] = str(ERA_EPOCH_COUNT)
        self.conf_parameters["dev_snapshot_epoch_count"] = str(
            ERA_EPOCH_COUNT // 2)

        # set other params so that nodes won't crash
        self.conf_parameters["adaptive_weight_beta"] = "1"
        self.conf_parameters["anticone_penalty_ratio"] = "10"
        self.conf_parameters["generate_tx_period_us"] = "100000"
Exemple #14
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")
Exemple #15
0
    def run_test(self):
        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"),
        )
        staking_contract_addr = Web3.toChecksumAddress(
            "443c409373ffd5c0bec1dddb7bec830856757b65")

        self.problem = "0x2bc79b7514884ab00da924607d71542cc4fed3beb8518e747726ae30ab6c7944"
        self.solution = "0xc4d2751c52311d0d7efe44e5c4195e058ad5ef4bb89b3e1761b24dc277b132c2"
        self.priv_key = default_config["GENESIS_PRI_KEY"]
        self.sender = encode_hex_0x(privtoaddr(self.priv_key))
        self.sender_checksum = Web3.toChecksumAddress(self.sender)
        self.pub = []
        self.pri = []
        self.rpc = RpcClient(self.nodes[0])
        gas = 50000000
        gas_price = 10

        # lock token for genesis account
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.tx_conf['to'] = staking_contract_addr
        tx_data = decode_hex(
            staking_contract.functions.deposit(
                1000000 * 10**18).buildTransaction(self.tx_conf)["data"])
        tx = self.rpc.new_tx(value=0,
                             receiver=staking_contract_addr,
                             data=tx_data,
                             gas=gas,
                             gas_price=gas_price)
        self.rpc.send_tx(tx, True)

        for i in range(10):
            priv_key = random.randint(0, 2**256).to_bytes(32, "big")
            pub_key = encode_hex_0x(privtoaddr(priv_key))
            self.pub.append(pub_key)
            self.pri.append(priv_key)
            transaction = self.rpc.new_tx(sender=self.sender,
                                          receiver=pub_key,
                                          value=1000000 * 10**18,
                                          priv_key=self.priv_key)
            self.rpc.send_tx(transaction, True)
            # deposit 10000 tokens
            tx_data = decode_hex(
                staking_contract.functions.deposit(
                    10000 * 10**18).buildTransaction(self.tx_conf)["data"])
            tx = self.rpc.new_tx(value=0,
                                 sender=pub_key,
                                 receiver=self.tx_conf["to"],
                                 gas=gas,
                                 data=tx_data,
                                 priv_key=priv_key)
            self.rpc.send_tx(tx)
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.filter = Filter(from_epoch="earliest", to_epoch="latest_mined")
        self.testEventContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testBallotContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testPayContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testHTLCContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testDaiContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testMappingContract()
        self.tx_conf = {
            "from": self.sender,
            "gas": int_to_hex(gas),
            "gasPrice": int_to_hex(gas_price),
            "chainId": 0
        }
        self.testDaiJoinContract()
        self.log.info("Pass")
Exemple #16
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")
#!/usr/bin/env python3
import os
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, privtoaddr
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

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


class LogFilteringTest(ConfluxTestFramework):
    def set_test_params(self):
        self.setup_clean_chain = True
        self.num_nodes = 1

    def setup_network(self):
        self.setup_nodes()

    def run_test(self):
        priv_key = default_config["GENESIS_PRI_KEY"]
        sender = eth_utils.encode_hex(privtoaddr(priv_key))

        self.rpc = RpcClient(self.nodes[0])
Exemple #18
0
    def run_test(self):
        file_path = os.path.dirname(os.path.realpath(__file__)).split("/")
        file_path.pop(-1)
        file_path.extend(["internal_contract", "metadata", "Staking.json"])
        file_path = "/".join(file_path)
        staking_contract_dict = json.loads(open(os.path.join(file_path), "r").read())
        staking_contract = get_contract_instance(contract_dict=staking_contract_dict)

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = default_config["GENESIS_PRI_KEY"]
        genesis_addr = priv_to_addr(genesis_key)
        nonce = 0
        gas_price = 1
        gas = CONTRACT_DEFAULT_GAS
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        self.tx_conf = {"from":Web3.toChecksumAddress(encode_hex_0x(genesis_addr)), "nonce":int_to_hex(nonce), "gas":int_to_hex(gas), "gasPrice":int_to_hex(gas_price), "chainId":0}

        total_num_blocks = 2 * 60 * 60 * 24 * 365
        accumulate_interest_rate = [2 ** 80 * total_num_blocks]
        for _ in range(1000):
            accumulate_interest_rate.append(accumulate_interest_rate[-1] * (
                40000 + 1000000 * total_num_blocks) // (total_num_blocks * 1000000))

        # Setup balance for node 0
        node = self.nodes[0]
        client = RpcClient(node)
        (addr, priv_key) = client.rand_account()
        self.log.info("addr=%s priv_key=%s", addr, priv_key)
        tx = client.new_tx(value=5 * 10 ** 18, receiver=addr)
        client.send_tx(tx)
        self.wait_for_tx([tx])
        assert_equal(client.get_balance(addr), 5 * 10 ** 18)
        assert_equal(client.get_staking_balance(addr), 0)

        self.tx_conf["to"] = Web3.toChecksumAddress("843c409373ffd5c0bec1dddb7bec830856757b65")
        # deposit 10**18
        tx_data = decode_hex(staking_contract.functions.deposit(10 ** 18).buildTransaction(self.tx_conf)["data"])
        tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key)
        client.send_tx(tx)
        self.wait_for_tx([tx])
        deposit_time = self.get_block_number(client, tx.hash_hex())
        assert_equal(client.get_staking_balance(addr), 10 ** 18)
        assert_equal(client.get_balance(addr), 4 * 10 ** 18 - charged_of_huge_gas(gas))

        # withdraw 5 * 10**17
        balance = client.get_balance(addr)
        capital = 5 * 10 ** 17
        tx_data = decode_hex(staking_contract.functions.withdraw(capital).buildTransaction(self.tx_conf)["data"])
        tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key)
        client.send_tx(tx)
        self.wait_for_tx([tx])
        withdraw_time = self.get_block_number(client, tx.hash_hex())
        interest = capital * accumulate_interest_rate[withdraw_time] // accumulate_interest_rate[deposit_time] - capital
        assert_equal(client.get_staking_balance(addr), 10 ** 18 - capital)
        assert_equal(client.get_balance(addr), balance + capital + interest - charged_of_huge_gas(gas))

        # lock 4 * 10 ** 17 until block number 100000
        balance = client.get_balance(addr)
        tx_data = decode_hex(staking_contract.functions.vote_lock(4 * 10 ** 17, 100000).buildTransaction(self.tx_conf)["data"])
        tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key)
        client.send_tx(tx)
        self.wait_for_tx([tx])
        assert_equal(client.get_balance(addr), balance - charged_of_huge_gas(gas))
        assert_equal(client.get_staking_balance(addr), 5 * 10 ** 17)

        # withdraw 5 * 10**17 and it should fail
        balance = client.get_balance(addr)
        capital = 5 * 10 ** 17
        tx_data = decode_hex(staking_contract.functions.withdraw(capital).buildTransaction(self.tx_conf)["data"])
        tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key)
        client.send_tx(tx)
        self.wait_for_tx([tx])
        assert_equal(client.get_balance(addr), balance - gas)
        assert_equal(client.get_staking_balance(addr), 5 * 10 ** 17)

        # withdraw 10**17 + 1 and it should fail
        balance = client.get_balance(addr)
        tx_data = decode_hex(staking_contract.functions.withdraw(10 ** 17 + 1).buildTransaction(self.tx_conf)["data"])
        tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key)
        client.send_tx(tx)
        self.wait_for_tx([tx])
        assert_equal(client.get_balance(addr), balance - gas)
        assert_equal(client.get_staking_balance(addr), 5 * 10 ** 17)

        # withdraw 10**17 and it should succeed
        balance = client.get_balance(addr)
        capital = 10 ** 17
        tx_data = decode_hex(staking_contract.functions.withdraw(capital).buildTransaction(self.tx_conf)["data"])
        tx = client.new_tx(value=0, sender=addr, receiver=self.tx_conf["to"], gas=gas, data=tx_data, priv_key=priv_key)
        client.send_tx(tx)
        self.wait_for_tx([tx])
        withdraw_time = self.get_block_number(client, tx.hash_hex())
        interest = capital * accumulate_interest_rate[withdraw_time] // accumulate_interest_rate[deposit_time] - capital
        assert_equal(client.get_balance(addr), balance + capital + interest - charged_of_huge_gas(gas))
        assert_equal(client.get_staking_balance(addr), 5 * 10 ** 17 - capital)

        block_gen_thread.stop()
        block_gen_thread.join()
        sync_blocks(self.nodes)
        self.log.info("Pass")