示例#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")
        file_dir = os.path.dirname(os.path.realpath(__file__))
        erc20_contract = solc.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"),
        )

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

        # lock tokens in bank
        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 = decode_hex(
            staking_contract.functions.deposit(
                10000 * 10**18).buildTransaction(self.tx_conf)["data"])
        node = self.nodes[0]
        client = RpcClient(node)
        genesis_key = default_config["GENESIS_PRI_KEY"]
        genesis_addr = privtoaddr(genesis_key)
        tx = client.new_tx(value=0,
                           receiver=staking_contract_addr,
                           nonce=0,
                           data=tx_data,
                           gas=gas,
                           gas_price=gas_price)
        client.send_tx(tx, True)

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = default_config["GENESIS_PRI_KEY"]
        genesis_addr = privtoaddr(genesis_key)
        nonce = 1
        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
        }
        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):
        sponsor_whitelist_contract_addr = Web3.toChecksumAddress(
            "8ad036480160591706c831f0da19d1a424e39469")
        collateral_per_storage_key = 10**18 // 16
        upper_bound = 5 * 10**7

        file_dir = os.path.dirname(os.path.realpath(__file__))

        control_contract_file_path = os.path.dirname(
            os.path.realpath(__file__)).split("/")
        control_contract_file_path.pop(-1)
        control_contract_file_path.extend(
            ["internal_contract", "metadata", "SponsorWhitelistControl.json"])
        control_contract_file_path = "/".join(control_contract_file_path)
        control_contract_dict = json.loads(
            open(os.path.join(control_contract_file_path), "r").read())

        control_contract = get_contract_instance(
            contract_dict=control_contract_dict)

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

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = self.genesis_priv_key
        genesis_addr = encode_hex(self.genesis_addr)
        self.log.info("genesis_addr={}".format(genesis_addr))
        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(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)
        (addr1, priv_key1) = client.rand_account()
        self.log.info("addr1={}".format(addr1))
        tx = client.new_tx(sender=genesis_addr,
                           priv_key=genesis_key,
                           value=10**6,
                           nonce=self.get_nonce(self.genesis_addr),
                           receiver=addr1)
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr1), 10**6)

        # setup contract
        transaction = self.call_contract_function(
            contract=test_contract,
            name="constructor",
            args=[],
            sender_key=self.genesis_priv_key,
            storage_limit=20000)
        contract_addr = self.wait_for_tx([transaction],
                                         True)[0]['contractCreated']
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(client.get_balance(contract_addr), 0)

        # sponsor the contract succeed
        b0 = client.get_balance(genesis_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_gas",
            args=[Web3.toChecksumAddress(contract_addr), upper_bound],
            value=10**18,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18)
        assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr)
        assert_equal(client.get_sponsor_gas_bound(contract_addr), upper_bound)
        assert_equal(client.get_balance(genesis_addr),
                     b0 - 10**18 - charged_of_huge_gas(gas))

        # set privilege for addr1
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="add",
                                    args=[Web3.toChecksumAddress(addr1)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True,
                                    storage_limit=64)
        assert_equal(
            client.get_balance(genesis_addr),
            b0 - charged_of_huge_gas(gas) - collateral_per_storage_key)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + collateral_per_storage_key)

        # addr1 call contract with privilege without enough cfx for gas fee
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_balance(addr1), 10**6)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sb - charged_of_huge_gas(gas))

        self.log.info("Pass")
示例#3
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(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()")),
                                     storage_limit=64)

        # 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()")),
                               storage_limit=0)

        # 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")
示例#4
0
    def run_test(self):
        num_blocks = 200
        snapshot_epoch = 150

        # Generate checkpoint on node[0]
        archive_node_client = RpcClient(self.nodes[0])
        self.genesis_nonce = archive_node_client.get_nonce(
            archive_node_client.GENESIS_ADDR)
        blocks_in_era = []
        for i in range(num_blocks):
            txs = self._generate_txs(0, random.randint(50, 100))
            block_hash = archive_node_client.generate_block_with_fake_txs(txs)
            if i >= snapshot_epoch:
                blocks_in_era.append(block_hash)
        sync_blocks(self.nodes[:-1])
        self.log.info("All archive nodes synced")

        # Start node[full_node_index] as full node to sync checkpoint
        # Change phase from CatchUpSyncBlockHeader to CatchUpCheckpoint
        # only when there is at least one connected peer.
        full_node_index = self.num_nodes - 1
        self.start_node(full_node_index, ["--full"], phase_to_wait=None)
        for i in range(self.num_nodes - 1):
            connect_nodes(self.nodes, full_node_index, i)

        self.log.info("Wait for full node to sync, index=%d", full_node_index)
        self.nodes[full_node_index].wait_for_phase(["NormalSyncPhase"],
                                                   wait_time=240)

        sync_blocks(self.nodes, sync_count=False)

        full_node_client = RpcClient(self.nodes[full_node_index])

        # At epoch 1, block header exists while body not synchronized
        try:
            print(
                full_node_client.block_by_epoch(full_node_client.EPOCH_NUM(1)))
        except ReceivedErrorResponseError as e:
            assert 'Internal error' == e.response.message

        # There is no state from epoch 1 to snapshot_epoch
        # Note, state of genesis epoch always exists
        assert full_node_client.epoch_number() >= snapshot_epoch
        wait_until(
            lambda: full_node_client.epoch_number() == archive_node_client.
            epoch_number() and full_node_client.epoch_number("latest_state") ==
            archive_node_client.epoch_number("latest_state"))
        # We have snapshot_epoch for state execution but
        # don't offer snapshot_epoch for Rpc clients.
        for i in range(1, snapshot_epoch + 1):
            try:
                full_node_client.get_balance(full_node_client.GENESIS_ADDR,
                                             full_node_client.EPOCH_NUM(i))
                raise AssertionError(
                    "should not have state for epoch {}".format(i))
            except ReceivedErrorResponseError as e:
                assert "State for epoch" in e.response.message
                assert "does not exist" in e.response.message

        # Wait for execution to complete.
        time.sleep(1)

        # There should be states after checkpoint
        for i in range(snapshot_epoch + 1,
                       full_node_client.epoch_number() - 3):
            full_balance = full_node_client.get_balance(
                full_node_client.GENESIS_ADDR, full_node_client.EPOCH_NUM(i))
            archive_balance = archive_node_client.get_balance(
                archive_node_client.GENESIS_ADDR,
                archive_node_client.EPOCH_NUM(i))
            assert_equal(full_balance, archive_balance)

        # Blocks within execution defer (5 epochs) and reward_defer (12 epochs) do not have state_valid
        available_blocks = blocks_in_era[:-17]
        assert_blocks_valid(self.nodes[:-1], available_blocks)
        assert_blocks_valid(self.nodes[-1:], available_blocks)
    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")
class CrossSpaceLogFilteringTest(ConfluxTestFramework):
    def set_test_params(self):
        self.num_nodes = 1
        self.conf_parameters["evm_chain_id"] = str(10)
        self.conf_parameters["evm_transaction_block_ratio"] = str(1)

    def setup_network(self):
        self.add_nodes(self.num_nodes)
        self.start_node(0, ["--archive"])
        self.rpc = RpcClient(self.nodes[0])

        ip = self.nodes[0].ip
        port = self.nodes[0].rpcport
        self.w3 = Web3(Web3.HTTPProvider(f'http://{ip}:{port}/'))
        assert_equal(self.w3.isConnected(), True)

    def run_test(self):
        # initialize Conflux account
        self.cfxPrivkey = default_config['GENESIS_PRI_KEY']
        self.cfxAccount = self.rpc.GENESIS_ADDR
        print(f'Using Conflux account {self.cfxAccount}')

        # 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}')

        #                              ---
        #           .-----------------| D |....
        #           V                  ---    |
        #          ---      ---      ---      ---
        # ... <-- | A | <- | B | <- | C | <- | E | <- ...
        #          ---      ---      ---      ---
        #
        #                 A --- B --- C --- D --- E
        # block number    0  |  1  |  2  |  3  |  4  |
        # epoch number    0  |  1  |  2  |     3     |

        cfx_next_nonce = self.rpc.get_nonce(self.cfxAccount)
        cfx_tx_hashes = []

        evm_next_nonce = self.w3.eth.getTransactionCount(
            self.evmAccount.address)
        evm_tx_hashes = []

        def emitConflux(n):
            nonlocal cfx_next_nonce, cfx_tx_hashes
            data_hex = (encode_hex_0x(keccak(b"emitConflux(uint256)"))[:10] +
                        encode_u256(n))
            tx = self.rpc.new_contract_tx(receiver=confluxContractAddr,
                                          data_hex=data_hex,
                                          nonce=cfx_next_nonce,
                                          sender=self.cfxAccount,
                                          priv_key=self.cfxPrivkey)
            cfx_next_nonce += 1
            cfx_tx_hashes.append(tx.hash_hex())
            return tx

        def emitBoth(n):
            nonlocal cfx_next_nonce, cfx_tx_hashes
            data_hex = encode_hex_0x(
                keccak(b"emitBoth(uint256,bytes20)"))[:10] + encode_u256(
                    n) + encode_bytes20(evmContractAddr.replace('0x', ''))
            tx = self.rpc.new_contract_tx(receiver=confluxContractAddr,
                                          data_hex=data_hex,
                                          nonce=cfx_next_nonce,
                                          sender=self.cfxAccount,
                                          priv_key=self.cfxPrivkey)
            cfx_next_nonce += 1
            cfx_tx_hashes.append(tx.hash_hex())
            return tx

        def emitEVM(n):
            nonlocal evm_next_nonce, evm_tx_hashes
            data_hex = (encode_hex_0x(keccak(b"emitEVM(uint256)"))[:10] +
                        encode_u256(n))
            tx, hash = self.construct_evm_tx(receiver=evmContractAddr,
                                             data_hex=data_hex,
                                             nonce=evm_next_nonce)
            evm_next_nonce += 1
            evm_tx_hashes.append(hash)
            return tx

        # generate ledger
        block_0 = self.rpc.block_by_epoch("latest_mined")['hash']

        block_a = self.rpc.generate_custom_block(parent_hash=block_0,
                                                 referee=[],
                                                 txs=[
                                                     emitConflux(11),
                                                     emitBoth(12),
                                                     emitEVM(13),
                                                 ])

        block_b = self.rpc.generate_custom_block(parent_hash=block_a,
                                                 referee=[],
                                                 txs=[
                                                     emitConflux(14),
                                                     emitBoth(15),
                                                     emitEVM(16),
                                                 ])

        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=[
                                                     emitConflux(21),
                                                     emitBoth(22),
                                                     emitEVM(23),
                                                 ])

        block_e = self.rpc.generate_custom_block(parent_hash=block_c,
                                                 referee=[block_d],
                                                 txs=[
                                                     emitConflux(24),
                                                     emitBoth(25),
                                                     emitEVM(26),
                                                 ])

        epoch_a = self.rpc.block_by_hash(block_a)['epochNumber']
        epoch_b = self.rpc.block_by_hash(block_b)['epochNumber']
        epoch_e = self.rpc.block_by_hash(block_e)['epochNumber']

        # 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

        for h in cfx_tx_hashes:
            receipt = self.rpc.get_transaction_receipt(h)
            assert_equal(receipt["outcomeStatus"], "0x0")

        for h in evm_tx_hashes:
            receipt = self.w3.eth.waitForTransactionReceipt(h)
            assert_equal(receipt["status"], 1)

        # check Conflux events
        filter = Filter(topics=[TEST_EVENT_TOPIC],
                        from_epoch=epoch_a,
                        to_epoch=epoch_e)
        logs = self.rpc.get_logs(filter)
        assert_equal(len(logs), 8)

        # --------------- 1 block per epoch ---------------
        # check EVM events
        # we expect 4 events: #12, #13, #15, #16
        filter = {
            "topics": [TEST_EVENT_TOPIC],
            "fromBlock": epoch_a,
            "toBlock": epoch_b
        }
        logs = self.nodes[0].eth_getLogs(filter)
        assert_equal(len(logs), 4)

        # emitBoth: TestEvent(12)
        assert_equal(logs[0]["data"], number_to_topic(12))
        assert_equal(logs[0]["address"], evmContractAddr.lower())
        assert_equal(logs[0]["blockHash"], block_a)
        assert_equal(logs[0]["blockNumber"], epoch_a)
        assert_equal(logs[0]["transactionHash"],
                     cfx_tx_hashes[1])  # TODO: should use phantom tx here
        # assert_equal(logs[0]["logIndex"], '0x0')
        # assert_equal(logs[0]["transactionIndex"], '0x0')
        # assert_equal(logs[0]["transactionLogIndex"], '0x0')
        assert_equal(logs[0]["removed"], False)

        # emitEVM: TestEvent(13)
        assert_equal(logs[1]["data"], number_to_topic(13))
        assert_equal(logs[1]["address"], evmContractAddr.lower())
        assert_equal(logs[1]["blockHash"], block_a)
        assert_equal(logs[1]["blockNumber"], epoch_a)
        assert_equal(logs[1]["transactionHash"], evm_tx_hashes[0].hex())
        # assert_equal(logs[1]["logIndex"], '0x1')
        # assert_equal(logs[1]["transactionIndex"], '0x1')
        assert_equal(logs[1]["transactionLogIndex"], '0x0')
        assert_equal(logs[1]["removed"], False)

        # emitBoth: TestEvent(15)
        assert_equal(logs[2]["data"], number_to_topic(15))
        assert_equal(logs[2]["address"], evmContractAddr.lower())
        assert_equal(logs[2]["blockHash"], block_b)
        assert_equal(logs[2]["blockNumber"], epoch_b)
        assert_equal(logs[2]["transactionHash"],
                     cfx_tx_hashes[3])  # TODO: should use phantom tx here
        # assert_equal(logs[2]["logIndex"], '0x0')
        # assert_equal(logs[2]["transactionIndex"], '0x0')
        # assert_equal(logs[2]["transactionLogIndex"], '0x0')
        assert_equal(logs[2]["removed"], False)

        # emitEVM: TestEvent(16)
        assert_equal(logs[3]["data"], number_to_topic(16))
        assert_equal(logs[3]["address"], evmContractAddr.lower())
        assert_equal(logs[3]["blockHash"], block_b)
        assert_equal(logs[3]["blockNumber"], epoch_b)
        assert_equal(logs[3]["transactionHash"], evm_tx_hashes[1].hex())
        # assert_equal(logs[3]["logIndex"], '0x1')
        # assert_equal(logs[3]["transactionIndex"], '0x1')
        assert_equal(logs[3]["transactionLogIndex"], '0x0')
        assert_equal(logs[3]["removed"], False)

        # --------------- 2 blocks per epoch ---------------
        # check EVM events
        # we expect 4 events: #22, #23, #25, #26
        filter = {
            "topics": [TEST_EVENT_TOPIC],
            "fromBlock": epoch_e,
            "toBlock": epoch_e
        }
        logs = self.nodes[0].eth_getLogs(filter)
        assert_equal(len(logs), 4)

        # emitBoth: TestEvent(22)
        assert_equal(logs[0]["data"], number_to_topic(22))
        assert_equal(logs[0]["address"], evmContractAddr.lower())
        assert_equal(logs[0]["blockHash"], block_e)
        assert_equal(logs[0]["blockNumber"], epoch_e)
        assert_equal(logs[0]["transactionHash"],
                     cfx_tx_hashes[5])  # TODO: should use phantom tx here
        # assert_equal(logs[0]["logIndex"], '0x0')
        # assert_equal(logs[0]["transactionIndex"], '0x0')
        # assert_equal(logs[0]["transactionLogIndex"], '0x0')
        assert_equal(logs[0]["removed"], False)

        # emitEVM: TestEvent(23)
        assert_equal(logs[1]["data"], number_to_topic(23))
        assert_equal(logs[1]["address"], evmContractAddr.lower())
        assert_equal(logs[1]["blockHash"], block_e)
        assert_equal(logs[1]["blockNumber"], epoch_e)
        assert_equal(logs[1]["transactionHash"], evm_tx_hashes[2].hex())
        # assert_equal(logs[1]["logIndex"], '0x1')
        # assert_equal(logs[1]["transactionIndex"], '0x1')
        assert_equal(logs[1]["transactionLogIndex"], '0x0')
        assert_equal(logs[1]["removed"], False)

        # emitBoth: TestEvent(25)
        assert_equal(logs[2]["data"], number_to_topic(25))
        assert_equal(logs[2]["address"], evmContractAddr.lower())
        assert_equal(logs[2]["blockHash"], block_e)
        assert_equal(logs[2]["blockNumber"], epoch_e)
        assert_equal(logs[2]["transactionHash"],
                     cfx_tx_hashes[7])  # TODO: should use phantom tx here
        # assert_equal(logs[2]["logIndex"], '0x2')
        # assert_equal(logs[2]["transactionIndex"], '0x2')
        # assert_equal(logs[2]["transactionLogIndex"], '0x0')
        assert_equal(logs[2]["removed"], False)

        # emitEVM: TestEvent(26)
        assert_equal(logs[3]["data"], number_to_topic(26))
        assert_equal(logs[3]["address"], evmContractAddr.lower())
        assert_equal(logs[3]["blockHash"], block_e)
        assert_equal(logs[3]["blockNumber"], epoch_e)
        assert_equal(logs[3]["transactionHash"], evm_tx_hashes[3].hex())
        # assert_equal(logs[3]["logIndex"], '0x3')
        # assert_equal(logs[3]["transactionIndex"], '0x3')
        assert_equal(logs[3]["transactionLogIndex"], '0x0')
        assert_equal(logs[3]["removed"], False)

        # --------------- other fields ---------------
        # filter by block hash
        filter = {"topics": [TEST_EVENT_TOPIC], "blockHash": block_c}
        logs_2 = self.nodes[0].eth_getLogs(filter)
        assert_equal(logs_2, [])

        filter = {
            "topics": [TEST_EVENT_TOPIC],
            "blockHash": block_d
        }  # from EVM perspective, D does not exist
        assert_raises_rpc_error(None, None, self.nodes[0].eth_getLogs, filter)

        filter = {"topics": [TEST_EVENT_TOPIC], "blockHash": block_e}
        logs_2 = self.nodes[0].eth_getLogs(filter)
        assert_equal(logs_2, logs)

        # filter limit
        filter = {
            "topics": [TEST_EVENT_TOPIC],
            "blockHash": block_e,
            "limit": 1
        }
        logs_2 = self.nodes[0].eth_getLogs(filter)
        assert_equal(logs_2, [logs[-1]])

        # "earliest", "latest"
        filter = {
            "topics": [TEST_EVENT_TOPIC],
            "fromBlock": "earliest",
            "toBlock": "latest"
        }
        logs_2 = self.nodes[0].eth_getLogs(filter)
        assert_equal(len(logs_2), 8)

        filter = {
            "topics": [TEST_EVENT_TOPIC],
            "fromBlock": "earliest",
            "toBlock": "latest",
            "limit": 4
        }
        logs_2 = self.nodes[0].eth_getLogs(filter)
        assert_equal(logs_2, logs)

        # address
        filter = {"address": confluxContractAddr}
        logs_2 = self.nodes[0].eth_getLogs(filter)
        assert_equal(logs_2, [])

        filter = {"address": evmContractAddr}
        logs_2 = self.nodes[0].eth_getLogs(filter)
        assert_equal(len(logs_2), 8)

        self.log.info("Pass")

    def cross_space_transfer(self, to, value):
        to = to.replace('0x', '')

        tx = self.rpc.new_tx(
            value=value,
            receiver="0x0888000000000000000000000000000000000006",
            data=decode_hex(f"0xda8d5daf{to}000000000000000000000000"),
            nonce=self.rpc.get_nonce(self.cfxAccount),
            gas=1000000,
        )

        self.rpc.send_tx(tx, True)

    def deploy_conflux_space(self, bytecode_path):
        bytecode_file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), bytecode_path)
        assert (os.path.isfile(bytecode_file))
        bytecode = open(bytecode_file).read()
        tx = self.rpc.new_contract_tx(receiver="",
                                      data_hex=bytecode,
                                      sender=self.cfxAccount,
                                      priv_key=self.cfxPrivkey,
                                      storage_limit=20000)
        assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex())
        receipt = self.rpc.get_transaction_receipt(tx.hash_hex())
        assert_equal(receipt["outcomeStatus"], "0x0")
        addr = receipt["contractCreated"]
        assert_is_hex_string(addr)
        return addr

    def deploy_evm_space(self, bytecode_path):
        bytecode_file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), bytecode_path)
        assert (os.path.isfile(bytecode_file))
        bytecode = open(bytecode_file).read()

        nonce = self.w3.eth.getTransactionCount(self.evmAccount.address)

        signed = self.evmAccount.signTransaction({
            "to": None,
            "value": 0,
            "gasPrice": 1,
            "gas": 210000,
            "nonce": nonce,
            "chainId": 10,
            "data": bytecode,
        })

        tx_hash = signed["hash"]
        return_tx_hash = self.w3.eth.sendRawTransaction(
            signed["rawTransaction"])
        assert_equal(tx_hash, return_tx_hash)

        self.rpc.generate_block(1)
        self.rpc.generate_blocks(20, 1)
        receipt = self.w3.eth.waitForTransactionReceipt(tx_hash)
        assert_equal(receipt["status"], 1)
        addr = receipt["contractAddress"]
        return addr

    def construct_evm_tx(self, receiver, data_hex, nonce):
        signed = self.evmAccount.signTransaction({
            "to": receiver,
            "value": 0,
            "gasPrice": 1,
            "gas": 150000,
            "nonce": nonce,
            "chainId": 10,
            "data": data_hex,
        })

        tx = [
            nonce, 1, 150000,
            bytes.fromhex(receiver.replace('0x', '')), 0,
            bytes.fromhex(data_hex.replace('0x', '')), signed["v"],
            signed["r"], signed["s"]
        ]
        return tx, signed["hash"]
示例#7
0
    def run_test(self):
        sponsor_whitelist_contract_addr = Web3.toChecksumAddress(
            "0888000000000000000000000000000000000001")
        bytes_per_key = 64
        collateral_per_storage_key = COLLATERAL_UNIT_IN_DRIP * 64
        # change upper tx gas limit to (GENESIS_GAS_LIMIT/2 - 1); -1 because below gas is set to upper_bound + 1
        tx_gas_upper_bound = int(default_config["GENESIS_GAS_LIMIT"] / 2 - 1)

        file_dir = os.path.dirname(os.path.realpath(__file__))

        control_contract_file_path = os.path.join(
            file_dir, "..", "internal_contract", "metadata",
            "SponsorWhitelistControl.json")
        control_contract_dict = json.loads(
            open(control_contract_file_path, "r").read())

        control_contract = get_contract_instance(
            contract_dict=control_contract_dict)

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

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = self.genesis_priv_key
        genesis_addr = encode_hex_0x(self.genesis_addr)
        self.log.info("genesis_addr={}".format(genesis_addr))
        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(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)
        (addr1, priv_key1) = client.rand_account()
        (addr2, priv_key2) = client.rand_account()
        (addr3, priv_key3) = client.rand_account()
        (addr4, priv_key4) = client.rand_account()
        tx = client.new_tx(sender=genesis_addr,
                           priv_key=genesis_key,
                           value=10**18,
                           nonce=self.get_nonce(self.genesis_addr),
                           receiver=addr1)
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr1), 10**18)
        tx = client.new_tx(sender=genesis_addr,
                           priv_key=genesis_key,
                           value=10**18,
                           nonce=self.get_nonce(self.genesis_addr),
                           receiver=addr2)
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr2), 10**18)
        tx = client.new_tx(sender=genesis_addr,
                           priv_key=genesis_key,
                           value=3 * 10**18,
                           nonce=self.get_nonce(self.genesis_addr),
                           receiver=addr3)
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr3), 3 * 10**18)

        # setup contract
        transaction = self.call_contract_function(
            contract=test_contract,
            name="constructor",
            args=[],
            sender_key=self.genesis_priv_key,
            storage_limit=1536)
        contract_addr = self.wait_for_tx([transaction],
                                         True)[0]['contractCreated']
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(client.get_balance(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     1536 * COLLATERAL_UNIT_IN_DRIP)

        # sponsor the contract failed due to sponsor_balance < 1000 * upper_bound
        b0 = client.get_balance(genesis_addr)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForGas",
            args=[Web3.toChecksumAddress(contract_addr), tx_gas_upper_bound],
            value=tx_gas_upper_bound * 1000 - 1,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 0)
        assert_equal(client.get_sponsor_for_gas(contract_addr),
                     "0x0000000000000000000000000000000000000000")
        assert_equal(client.get_sponsor_gas_bound(contract_addr), 0)
        assert_equal(client.get_balance(genesis_addr), b0 - gas)

        # sponsor the contract succeed
        b0 = client.get_balance(genesis_addr)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForGas",
            args=[Web3.toChecksumAddress(contract_addr), tx_gas_upper_bound],
            value=10**18,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18)
        assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr)
        assert_equal(client.get_sponsor_gas_bound(contract_addr),
                     tx_gas_upper_bound)
        assert_equal(client.get_balance(genesis_addr),
                     b0 - 10**18 - charged_of_huge_gas(gas))

        check_info = client.check_balance_against_transaction(addr1,
                                                              contract_addr,
                                                              gas,
                                                              gas_price,
                                                              storage_limit=0)
        assert_equal(check_info['willPayTxFee'], True)
        assert_equal(check_info['willPayCollateral'], True)
        assert_equal(check_info['isBalanceEnough'], True)

        check_info = client.check_balance_against_transaction(addr4,
                                                              contract_addr,
                                                              gas,
                                                              gas_price,
                                                              storage_limit=0)
        assert_equal(check_info['willPayTxFee'], True)
        assert_equal(check_info['willPayCollateral'], True)
        assert_equal(check_info['isBalanceEnough'], False)

        # set privilege for addr4
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="add",
                                    args=[Web3.toChecksumAddress(addr4)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True,
                                    storage_limit=64)
        assert_equal(
            client.get_balance(genesis_addr),
            b0 - charged_of_huge_gas(gas) - collateral_per_storage_key)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + collateral_per_storage_key)

        check_info = client.check_balance_against_transaction(addr4,
                                                              contract_addr,
                                                              gas,
                                                              gas_price,
                                                              storage_limit=0)
        assert_equal(check_info['willPayTxFee'], False)
        assert_equal(check_info['willPayCollateral'], True)
        assert_equal(check_info['isBalanceEnough'], True)

        # remove privilege for addr4
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="remove",
                                    args=[Web3.toChecksumAddress(addr4)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 - collateral_per_storage_key)
        assert_equal(
            client.get_balance(genesis_addr),
            b0 - charged_of_huge_gas(gas) + collateral_per_storage_key)

        # set privilege for addr1
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="add",
                                    args=[Web3.toChecksumAddress(addr1)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True,
                                    storage_limit=64)
        assert_equal(
            client.get_balance(genesis_addr),
            b0 - charged_of_huge_gas(gas) - collateral_per_storage_key)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + collateral_per_storage_key)

        # addr1 call contract with privilege
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_balance(addr1), b1)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sb - charged_of_huge_gas(gas))

        # addr1 call contract with privilege and large tx fee
        b1 = client.get_balance(addr1)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True,
                                    gas=tx_gas_upper_bound + 1)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_balance(addr1),
                     b1 - charged_of_huge_gas(tx_gas_upper_bound + 1))

        # addr2 call contract without privilege
        b2 = client.get_balance(addr2)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_balance(addr2), b2 - charged_of_huge_gas(gas))

        # set privilege for addr2
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="add",
                                    args=[Web3.toChecksumAddress(addr2)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True,
                                    storage_limit=64)
        assert_equal(
            client.get_balance(genesis_addr),
            b0 - charged_of_huge_gas(gas) - collateral_per_storage_key)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + collateral_per_storage_key)

        # now, addr2 call contract with privilege
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sb - charged_of_huge_gas(gas))
        assert_equal(client.get_balance(addr2), b2)

        # remove privilege for addr1
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="remove",
                                    args=[Web3.toChecksumAddress(addr1)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 - collateral_per_storage_key)
        assert_equal(
            client.get_balance(genesis_addr),
            b0 - charged_of_huge_gas(gas) + collateral_per_storage_key)

        # addr1 call contract without privilege
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_balance(addr1), b1 - charged_of_huge_gas(gas))

        # new sponsor failed due to small sponsor_balance
        b3 = client.get_balance(addr3)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForGas",
            args=[Web3.toChecksumAddress(contract_addr), tx_gas_upper_bound],
            value=5 * 10**17,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr)
        assert_equal(client.get_balance(addr3), b3 - gas)

        # new sponsor failed due to small upper bound
        b3 = client.get_balance(addr3)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForGas",
            args=[
                Web3.toChecksumAddress(contract_addr), tx_gas_upper_bound - 1
            ],
            value=10**18,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr)
        assert_equal(client.get_balance(addr3), b3 - gas)

        # new sponsor succeed
        b0 = client.get_balance(genesis_addr)
        b3 = client.get_balance(addr3)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForGas",
            args=[
                Web3.toChecksumAddress(contract_addr), tx_gas_upper_bound + 1
            ],
            value=10**18,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18)
        assert_equal(client.get_sponsor_gas_bound(contract_addr),
                     tx_gas_upper_bound + 1)
        assert_equal(client.get_sponsor_for_gas(contract_addr), addr3)
        assert_equal(client.get_balance(addr3),
                     b3 - 10**18 - charged_of_huge_gas(gas))
        assert_equal(client.get_balance(genesis_addr), b0 + sb)

        # sponsor the contract for collateral failed due to zero sponsor balance
        b3 = client.get_balance(addr3)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForCollateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=0,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     0)
        assert_equal(client.get_sponsor_for_collateral(contract_addr),
                     "0x0000000000000000000000000000000000000000")
        assert_equal(client.get_balance(addr3), b3 - gas)

        # sponsor the contract for collateral succeed
        b3 = client.get_balance(addr3)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForCollateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=10**18 - 1,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     10**18 - 1)
        assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3)
        assert_equal(client.get_balance(addr3),
                     b3 - charged_of_huge_gas(gas) - 10**18 + 1)

        check_info = client.check_balance_against_transaction(addr1,
                                                              contract_addr,
                                                              gas,
                                                              gas_price,
                                                              storage_limit=0)
        assert_equal(check_info['willPayTxFee'], True)
        assert_equal(check_info['willPayCollateral'], True)
        assert_equal(check_info['isBalanceEnough'], True)

        # addr1 create 2 keys without privilege, and storage limit is 1, should failed
        b1 = client.get_balance(addr1)
        assert_equal(client.get_collateral_for_storage(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(addr1), 0)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[0, 2],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key)
        assert_equal(client.get_collateral_for_storage(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(addr1), 0)
        assert_equal(client.get_balance(addr1), b1 - gas)

        # addr1 create 2 keys without privilege, and storage limit is 2, should succeed
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[0, 2],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 2)
        assert_equal(client.get_collateral_for_storage(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(addr1),
                     collateral_per_storage_key * 2)
        assert_equal(
            client.get_balance(addr1),
            b1 - charged_of_huge_gas(gas) - collateral_per_storage_key * 2)

        # remove 1 key create by addr1
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="par_del",
                                    args=[0, 1],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 2)
        assert_equal(client.get_collateral_for_storage(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(addr1),
                     collateral_per_storage_key)
        assert_equal(
            client.get_balance(addr1),
            b1 - charged_of_huge_gas(gas) + collateral_per_storage_key)

        check_info = client.check_balance_against_transaction(
            addr2, contract_addr, gas, gas_price, storage_limit=bytes_per_key)
        assert_equal(check_info['willPayTxFee'], False)
        assert_equal(check_info['willPayCollateral'], False)
        assert_equal(check_info['isBalanceEnough'], True)

        check_info = client.check_balance_against_transaction(
            addr2, contract_addr, gas, gas_price, storage_limit=10**18)
        assert_equal(check_info['willPayTxFee'], False)
        assert_equal(check_info['willPayCollateral'], True)
        assert_equal(check_info['isBalanceEnough'], False)

        # addr2 create 2 keys with privilege, and storage limit is 1, should succeed
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[2, 4],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 2)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc - collateral_per_storage_key * 2)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - charged_of_huge_gas(gas))
        assert_equal(client.get_collateral_for_storage(addr2), 0)
        assert_equal(client.get_balance(addr2), b2)

        # addr2 create 13 keys with privilege, and storage limit is 0, should succeed
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[4, 17],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=0)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 15)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc - collateral_per_storage_key * 13)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - charged_of_huge_gas(gas))
        assert_equal(client.get_collateral_for_storage(addr2), 0)
        assert_equal(client.get_balance(addr2), b2)

        # now sponsor_balance is unable to pay collateral for storage
        # the balance of addr2 is able to pay 15 collateral for storage, but not 16
        assert_greater_than(
            collateral_per_storage_key,
            client.get_sponsor_balance_for_collateral(contract_addr))
        assert_greater_than(collateral_per_storage_key * 16,
                            client.get_balance(addr2))
        assert_greater_than(client.get_balance(addr2),
                            collateral_per_storage_key * 15)

        # addr2 create 1 keys with privilege, and storage limit is 0, should failed
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[17, 18],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=0)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 15)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - gas)
        assert_equal(client.get_collateral_for_storage(addr2), 0)
        assert_equal(client.get_balance(addr2), b2)

        # addr2 create 1 keys with privilege, and storage limit is 2, should succeed
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[17, 18],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 2)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 15)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - charged_of_huge_gas(gas))
        assert_equal(client.get_collateral_for_storage(addr2),
                     collateral_per_storage_key)
        assert_equal(client.get_balance(addr2),
                     b2 - collateral_per_storage_key)

        # addr2 del 10 keys with privilege
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_del",
                                    args=[2, 12],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 5)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc + collateral_per_storage_key * 10)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - charged_of_huge_gas(gas))
        assert_equal(client.get_collateral_for_storage(addr2),
                     collateral_per_storage_key)
        assert_equal(client.get_balance(addr2), b2)

        # addr3 sponsor more, treat as transfer
        b3 = client.get_balance(addr3)
        sb = client.get_sponsor_balance_for_collateral(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForCollateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=sb,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sb * 2)
        assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3)
        assert_equal(client.get_balance(addr3),
                     b3 - charged_of_huge_gas(gas) - sb)

        # genesis sponsor with sponsor balance, should failed
        b0 = client.get_balance(genesis_addr)
        sb = client.get_sponsor_balance_for_collateral(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForCollateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=sb + 1,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sb)
        assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3)
        assert_equal(client.get_balance(genesis_addr), b0 - gas)

        # genesis sponsor with sponsor balance and collateral_for_storage, should succeed
        b0 = client.get_balance(genesis_addr)
        b3 = client.get_balance(addr3)
        cfs = client.get_collateral_for_storage(contract_addr)
        sb = client.get_sponsor_balance_for_collateral(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForCollateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=sb + cfs + 1,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_collateral_for_storage(contract_addr), cfs)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sb + 1)
        assert_equal(client.get_sponsor_for_collateral(contract_addr),
                     genesis_addr)
        assert_equal(client.get_balance(genesis_addr),
                     b0 - charged_of_huge_gas(gas) - sb - cfs - 1)
        assert_equal(client.get_balance(addr3), b3 + sb + cfs)

        # storage change test
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="par",
                                    args=[10, 20, 30, 41],
                                    sender_key=self.genesis_priv_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 30)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + 11 * collateral_per_storage_key)

        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="par_add_del",
                                    args=[110, 120, 110, 120],
                                    sender_key=self.genesis_priv_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 30)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + 10 * collateral_per_storage_key)

        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="par_add_del",
                                    args=[210, 220, 215, 220],
                                    sender_key=self.genesis_priv_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 30)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + 5 * collateral_per_storage_key)

        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="par_add_del",
                                    args=[310, 320, 320, 330],
                                    sender_key=self.genesis_priv_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 30)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + 10 * collateral_per_storage_key)

        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="par_add_del",
                                    args=[410, 420, 409, 430],
                                    sender_key=self.genesis_priv_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 300)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + 21 * collateral_per_storage_key)

        # test recurrence
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="rec",
                                    args=[510, 520, 3],
                                    sender_key=self.genesis_priv_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 30)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + 4 * collateral_per_storage_key)

        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="par_del",
                                    args=[510, 520],
                                    sender_key=self.genesis_priv_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 30)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 - 4 * collateral_per_storage_key)

        self.log.info("Pass")
示例#8
0
 def run_test(self):
     client = RpcClient(self.nodes[0])
     self.test_throttled(client)
     self.test_recharged(client)
def new_client(rpc_url):
    return RpcClient(node=get_simple_rpc_proxy(rpc_url, timeout=10))
示例#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=3382)
        client = RpcClient(self.nodes[0])
        c0 = client.get_collateral_for_storage(genesis_addr)
        client.send_tx(tx_create, True)
        receipt = client.get_transaction_receipt(tx_create.hash_hex())
        c1 = client.get_collateral_for_storage(genesis_addr)
        assert_equal(c1 - c0, 3382 * 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, nonce),
                         balance_map[sk])
        c2 = 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")
示例#11
0
    def run_test(self):
        file_dir = os.path.dirname(os.path.realpath(__file__))

        pay_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/pay_abi.json"),
            bytecode_file=os.path.join(file_dir, "contracts/pay_bytecode.dat"),
        )

        control_contract_file_path = os.path.join(
            file_dir, "../internal_contract/metadata/AdminControl.json")
        control_contract_dict = json.loads(
            open(control_contract_file_path, "r").read())

        admin_control_contract = get_contract_instance(
            contract_dict=control_contract_dict)

        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 = 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
        }

        # 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(client.get_balance(addr), 5000000000000000000)

        (addr2, priv_key2) = client.rand_account()
        self.log.info("addr2=%s priv_key2=%s", addr2, priv_key2)
        tx = client.new_tx(value=5 * 10**18,
                           receiver=addr2,
                           nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr2), 5000000000000000000)

        # deploy pay contract
        tx = self.call_contract_function(contract=pay_contract,
                                         name="constructor",
                                         args=[],
                                         sender_key=priv_key,
                                         storage_limit=512)
        contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated']
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(client.get_collateral_for_storage(addr),
                     512 * 976562500000000)
        assert_equal(client.get_balance(contract_addr), 0)

        # deposit 10**18
        b0 = client.get_balance(addr)
        tx = self.call_contract_function(contract=pay_contract,
                                         name="recharge",
                                         args=[],
                                         sender_key=priv_key,
                                         contract_addr=contract_addr,
                                         value=10**18,
                                         wait=True,
                                         check_status=True)
        assert_equal(client.get_balance(contract_addr), 10**18)
        assert_equal(client.get_balance(addr),
                     b0 - 10**18 - charged_of_huge_gas(gas))
        assert_equal(client.get_admin(contract_addr), addr)

        # transfer admin (fail)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="setAdmin",
            args=[
                Web3.toChecksumAddress(contract_addr),
                Web3.toChecksumAddress(addr2)
            ],
            sender_key=priv_key2,
            contract_addr=Web3.toChecksumAddress(
                "0x0888000000000000000000000000000000000000"),
            wait=True,
            check_status=True)
        assert_equal(client.get_admin(contract_addr), addr)
        assert_equal(client.get_balance(addr2),
                     5 * 10**18 - charged_of_huge_gas(gas))

        # transfer admin (success)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="setAdmin",
            args=[
                Web3.toChecksumAddress(contract_addr),
                Web3.toChecksumAddress(addr2)
            ],
            sender_key=priv_key,
            contract_addr=Web3.toChecksumAddress(
                "0x0888000000000000000000000000000000000000"),
            wait=True,
            check_status=True)
        assert_equal(client.get_admin(contract_addr), addr2)

        # destroy
        b0 = client.get_balance(addr)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="destroy",
            args=[Web3.toChecksumAddress(contract_addr)],
            sender_key=priv_key2,
            contract_addr=Web3.toChecksumAddress(
                "0x0888000000000000000000000000000000000000"),
            wait=True,
            check_status=True)
        assert_equal(client.get_balance(contract_addr), 0)
        assert_equal(client.get_balance(addr2),
                     6 * 10**18 - charged_of_huge_gas(gas) * 2)
        assert_equal(client.get_collateral_for_storage(addr), 0)
        assert_equal(client.get_balance(addr), b0 + 512 * 976562500000000)

        self.log.info("Pass")
示例#12
0
def new_client(rpc_url):
    return RpcClient(node=get_rpc_proxy(rpc_url, 3))
示例#13
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")
示例#14
0
class ContractBenchTest(SmartContractBenchBase):
    def set_test_params(self):
        self.setup_clean_chain = True
        self.num_nodes = 1

    def setup_network(self):
        self.setup_nodes()

    def testEventContract(self):
        CONTRACT_PATH = "contracts/event_bytecode_new.dat"
        logs = self.rpc.get_logs(self.filter)
        l = len(logs)
        # 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().strip()
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, bytecode)
        contractAddr = Web3.toChecksumAddress(contractAddr)
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 1)

        # construct contract object
        solc = Solc()
        file_dir = os.path.dirname(os.path.realpath(__file__))
        contract = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/event_abi_new.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )
        self.tx_conf["to"] = contractAddr

        # interact with foo()
        data = contract.functions.foo().buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 2)
        assert_equal(logs[-1]["topics"][1], self.address_to_topic(self.sender))
        assert_equal(logs[-1]["topics"][2], self.number_to_topic(1))

        # interact with goo(10), will pass modifier, emit new event
        data = contract.functions.goo(10).buildTransaction(
            self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 3)
        assert_equal(logs[-1]["topics"][1], self.address_to_topic(self.sender))
        assert_equal(logs[-1]["topics"][2], self.number_to_topic(11))

        # interact with goo(10), will not pass modifier, no event emitted
        data = contract.functions.goo(10).buildTransaction(
            self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 3)

        # call const function hoo()
        data = contract.functions.hoo().buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert_equal(result, self.number_to_topic(11))

        # call const function byte32oo(solution)
        data = contract.functions.byte32oo(self.solution).buildTransaction(
            self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert_equal(result, self.solution)

        # call const function getSha256(solution)
        data = contract.functions.getSha256(self.solution).buildTransaction(
            self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert_equal(result, self.problem)

    def testBallotContract(self):
        CONTRACT_PATH = "contracts/ballot_bytecode.dat"
        logs = self.rpc.get_logs(self.filter)
        l = len(logs)

        # construct contract object
        solc = Solc()
        file_dir = os.path.dirname(os.path.realpath(__file__))
        contract = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/ballot_abi.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )

        # deploy contract
        data = contract.constructor(10).buildTransaction(self.tx_conf)["data"]
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, data)
        contractAddr = Web3.toChecksumAddress(contractAddr)
        self.tx_conf["to"] = contractAddr

        # interact with vote()
        data = contract.functions.vote(5).buildTransaction(
            self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 1)
        assert_equal(logs[-1]["data"], self.number_to_topic(5))

        # call const function winningProposal()
        data = contract.functions.winningProposal().buildTransaction(
            self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert_equal(result, self.number_to_topic(5))

    def testHTLCContract(self):
        CONTRACT_PATH = "contracts/htlc_bytecode_new.dat"
        logs = self.rpc.get_logs(self.filter)
        l = len(logs)

        # construct contract object
        solc = Solc()
        file_dir = os.path.dirname(os.path.realpath(__file__))
        contract = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/htlc_abi_new.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )

        # deploy contract
        data = contract.constructor().buildTransaction(self.tx_conf)["data"]
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, data)
        tx_hash = receipt['transactionHash']
        contractAddr = Web3.toChecksumAddress(contractAddr)
        self.tx_conf["to"] = contractAddr
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 1)
        assert_equal(logs[-1]["topics"][1], self.address_to_topic(self.sender))
        assert_equal(logs[-1]["topics"][2], self.number_to_topic(16))

        # call getNow()
        data = contract.functions.getNow().buildTransaction(
            self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert (int(result, 0) - int(time.time()) < 5)

        b0 = self.rpc.get_balance(self.sender)
        fee = 10000000
        # interact with newContract(), sender send conflux to himself
        time_lock = int(time.time()) + 7200
        data = contract.functions.newContract(
            self.sender_checksum, self.problem,
            time_lock).buildTransaction(self.tx_conf)["data"]
        cost = 5000000000000000000
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data, cost)
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 2)
        assert_equal(self.rpc.get_balance(contractAddr), cost)
        assert_greater_than_or_equal(self.rpc.get_balance(self.sender),
                                     b0 - cost - fee)
        contract_id = logs[-1]["topics"][1]

        # call getContract
        cid0 = contract_id
        data = contract.functions.getContract(contract_id).buildTransaction(
            self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        result = result[2:]
        res = ['0x' + result[i * 64:(i + 1) * 64] for i in range(8)]
        assert_equal(res[0][-20:], self.sender[-20:])
        assert_equal(res[1][-20:], self.sender[-20:])
        assert_equal(int(res[2], 0), cost)
        assert_equal(res[3], self.problem)
        assert_equal(int(res[4], 0), time_lock)
        assert_equal(int(res[5], 0), 0)
        assert_equal(int(res[6], 0), 0)
        assert_equal(int(res[7], 0), 0)

        # interact with withdraw()
        data = contract.functions.withdraw(
            contract_id, self.solution).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        assert_equal(self.rpc.get_balance(contractAddr), 0)
        assert_greater_than_or_equal(self.rpc.get_balance(self.sender),
                                     b0 - fee * 2)
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 3)

        # call getContract
        data = contract.functions.getContract(contract_id).buildTransaction(
            self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        result = result[2:]
        res = ['0x' + result[i * 64:(i + 1) * 64] for i in range(8)]
        assert_equal(res[0][-20:], self.sender[-20:])
        assert_equal(res[1][-20:], self.sender[-20:])
        assert_equal(int(res[2], 0), cost)
        assert_equal(res[3], self.problem)
        assert_equal(int(res[4], 0), time_lock)
        assert_equal(int(res[5], 0), 1)
        assert_equal(int(res[6], 0), 0)
        assert_equal(res[7], self.solution)
        receipt = self.rpc.get_transaction_receipt(tx_hash)

    def testPayContract(self):
        CONTRACT_PATH = "contracts/pay_bytecode.dat"
        logs = self.rpc.get_logs(self.filter)
        l = len(logs)

        # construct contract object
        solc = Solc()
        file_dir = os.path.dirname(os.path.realpath(__file__))
        contract = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/pay_abi.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )

        # deploy contract
        data = contract.constructor().buildTransaction(self.tx_conf)["data"]
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, data)
        contractAddr = Web3.toChecksumAddress(contractAddr)
        self.tx_conf["to"] = contractAddr
        logs = self.rpc.get_logs(self.filter)
        l = len(logs)

        b0 = self.rpc.get_balance(self.sender)
        # interact with recharge()
        data = contract.functions.recharge().buildTransaction(
            self.tx_conf)["data"]
        cost = 5000000000000000000
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data, cost)
        b1 = self.rpc.get_balance(self.sender)
        bc = self.rpc.get_balance(contractAddr)
        assert_equal(bc, cost)

        #interact with withdraw
        data = contract.functions.withdraw(
            self.sender_checksum).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data, 0)
        b2 = self.rpc.get_balance(self.sender)
        bc = self.rpc.get_balance(contractAddr)
        logs = self.rpc.get_logs(self.filter)
        assert_equal(bc, 0)

    def testMappingContract(self):
        CONTRACT_PATH = "contracts/mapping_bytecode.dat"
        logs = self.rpc.get_logs(self.filter)
        l = len(logs)

        # construct contract object
        solc = Solc()
        file_dir = os.path.dirname(os.path.realpath(__file__))
        contract = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/mapping_abi.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )

        # deploy contract
        data = contract.constructor(1).buildTransaction(self.tx_conf)["data"]
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, data)
        tx_hash = receipt['transactionHash']
        contractAddr = Web3.toChecksumAddress(contractAddr)
        self.tx_conf["to"] = contractAddr

        c = "0x81f3521d71990945b99e1c592750d7157f2b545f"

        def check_wards(x, y, z):
            data = contract.functions.wards(Web3.toChecksumAddress(
                self.pub[0])).buildTransaction(self.tx_conf)["data"]
            result = self.rpc.call(contractAddr, data)
            A = int(result, 0)
            assert (A == x)
            data = contract.functions.wards(
                self.sender_checksum).buildTransaction(self.tx_conf)["data"]
            result = self.rpc.call(contractAddr, data)
            B = int(result, 0)
            assert (B == y)
            data = contract.functions.wards(
                Web3.toChecksumAddress(c)).buildTransaction(
                    self.tx_conf)["data"]
            result = self.rpc.call(contractAddr, data)
            C = int(result, 0)
            assert (C == z)

        # deny pub[0]
        check_wards(0, 2, 0)
        data = contract.functions.set1(
            Web3.toChecksumAddress(c)).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        check_wards(0, 2, 1)
        data = contract.functions.set2(Web3.toChecksumAddress(
            self.pub[0])).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        check_wards(2, 2, 1)
        data = contract.functions.set0(
            Web3.toChecksumAddress(c)).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        check_wards(2, 2, 0)
        data = contract.functions.set0(Web3.toChecksumAddress(
            self.pub[0])).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        check_wards(0, 2, 0)

    def testDaiContract(self):
        CONTRACT_PATH = "contracts/Dai_bytecode.dat"
        logs = self.rpc.get_logs(self.filter)
        l = len(logs)

        # construct contract object
        solc = Solc()
        file_dir = os.path.dirname(os.path.realpath(__file__))
        contract = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/Dai_abi.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )

        # deploy contract
        data = contract.constructor(1).buildTransaction(self.tx_conf)["data"]
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, data)
        tx_hash = receipt['transactionHash']
        contractAddr = Web3.toChecksumAddress(contractAddr)
        self.tx_conf["to"] = contractAddr

        # rely [0,5)
        for i in range(5):
            data = contract.functions.rely(Web3.toChecksumAddress(
                self.pub[i])).buildTransaction(self.tx_conf)["data"]
            result = self.call_contract(self.sender, self.priv_key,
                                        contractAddr, data, 0)
            assert_equal(result["outcomeStatus"], 0)

        # deny 1, 3
        for i in range(5):
            if (i % 2 == 1):
                data = contract.functions.deny(
                    Web3.toChecksumAddress(self.pub[i])).buildTransaction(
                        self.tx_conf)["data"]
                result = self.call_contract(self.pub[i - 1], self.pri[i - 1],
                                            contractAddr, data, 0)
                assert_equal(result["outcomeStatus"], 0)

        # check wards
        for i in range(5):
            data = contract.functions.wards(Web3.toChecksumAddress(
                self.pub[i])).buildTransaction(self.tx_conf)["data"]
            result = self.rpc.call(contractAddr, data)
            assert_equal(int(result, 0), int(i % 2 == 0))

        # mint tokens
        data = contract.functions.mint(Web3.toChecksumAddress(
            self.pub[0]), 100000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data, 0)
        logs = self.rpc.get_logs(self.filter)

        # check balance
        data = contract.functions.balanceOf(Web3.toChecksumAddress(
            self.pub[0])).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert (int(result, 0) == 100000)

        # approve
        data = contract.functions.approve(
            self.sender_checksum, 50000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.pub[0], self.pri[0], contractAddr,
                                    data)
        logs = self.rpc.get_logs(self.filter)

        # check allowance
        data = contract.functions.allowance(
            Web3.toChecksumAddress(self.pub[0]),
            self.sender_checksum).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert (int(result, 0) == 50000)

        # insufficient balance
        data = contract.functions.transfer(self.sender_checksum,
                                           200000).buildTransaction(
                                               self.tx_conf)["data"]
        result = self.call_contract(self.pub[0], self.pri[0], contractAddr,
                                    data)
        assert (result["outcomeStatus"] != 0)

        # insuffcient allowance
        data = contract.functions.transferFrom(
            Web3.toChecksumAddress(self.pub[0]), self.sender_checksum,
            10000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.pub[1], self.pri[1], contractAddr,
                                    data)
        assert (result["outcomeStatus"] != 0)

        # transfer 50000 use allowance
        data = contract.functions.transferFrom(
            Web3.toChecksumAddress(self.pub[0]),
            Web3.toChecksumAddress(self.pub[1]),
            50000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, contractAddr,
                                    data)
        assert (result["outcomeStatus"] == 0)

        # get digest and sign it
        ts = int(time.time()) + 7200
        data = contract.functions.getHash(Web3.toChecksumAddress(self.pub[0]),
                                          Web3.toChecksumAddress(self.pub[1]),
                                          0, ts, True).buildTransaction(
                                              self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        v, r, s = ecsign(bytes.fromhex(result[2:]), self.pri[0])
        r = self.fixto64(hex(r))
        s = self.fixto64(hex(s))
        assert (len(r) == 66)
        assert (len(s) == 66)

        # premit
        data = contract.functions.permit(
            Web3.toChecksumAddress(self.pub[0]),
            Web3.toChecksumAddress(self.pub[1]), 0, ts, True, v, r,
            s).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.pub[5], self.pri[5], contractAddr,
                                    data)
        assert (result["outcomeStatus"] == 0)

        # check allowance
        data = contract.functions.allowance(
            Web3.toChecksumAddress(self.pub[0]),
            self.sender_checksum).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert (int(result, 0) == 0)
        data = contract.functions.allowance(
            Web3.toChecksumAddress(self.pub[0]),
            Web3.toChecksumAddress(self.pub[1])).buildTransaction(
                self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert (
            result ==
            '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
        )

        # burn pub[0]
        data = contract.functions.burn(Web3.toChecksumAddress(
            self.pub[0]), 50000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.pub[1], self.pri[1], contractAddr,
                                    data)
        assert (result["outcomeStatus"] == 0)

        # check balance
        data = contract.functions.balanceOf(Web3.toChecksumAddress(
            self.pub[0])).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert (int(result, 0) == 0)
        data = contract.functions.balanceOf(Web3.toChecksumAddress(
            self.pub[1])).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert (int(result, 0) == 50000)
        data = contract.functions.totalSupply().buildTransaction(
            self.tx_conf)["data"]
        result = self.rpc.call(contractAddr, data)
        assert (int(result, 0) == 50000)

    def testDaiJoinContract(self):
        solc = Solc()
        CONTRACT_PATH = "contracts/Dai_bytecode.dat"
        file_dir = os.path.dirname(os.path.realpath(__file__))
        dai = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/Dai_abi.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )
        data = dai.constructor(1).buildTransaction(self.tx_conf)["data"]
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, data)
        dai_addr = Web3.toChecksumAddress(contractAddr)

        CONTRACT_PATH = "contracts/Vat_bytecode.dat"
        file_dir = os.path.dirname(os.path.realpath(__file__))
        vat = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/Vat_abi.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )
        data = vat.constructor().buildTransaction(self.tx_conf)["data"]
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, data)
        vat_addr = Web3.toChecksumAddress(contractAddr)

        CONTRACT_PATH = "contracts/DaiJoin_bytecode.dat"
        file_dir = os.path.dirname(os.path.realpath(__file__))
        dai_join = solc.get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/DaiJoin_abi.json"),
            bytecode_file=os.path.join(file_dir, CONTRACT_PATH),
        )
        data = dai_join.constructor(vat_addr, dai_addr).buildTransaction(
            self.tx_conf)["data"]
        receipt, contractAddr = self.deploy_contract(self.sender,
                                                     self.priv_key, data)
        dai_join_addr = Web3.toChecksumAddress(contractAddr)

        # mint dai tokens & give approval
        self.tx_conf["to"] = dai_addr
        data = dai.functions.mint(Web3.toChecksumAddress(
            self.pub[0]), 100000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, dai_addr, data,
                                    0)
        assert (result["outcomeStatus"] == 0)
        data = dai.functions.approve(dai_join_addr, 100000).buildTransaction(
            self.tx_conf)["data"]
        result = self.call_contract(self.pub[0], self.pri[0], dai_addr, data,
                                    0)
        assert (result["outcomeStatus"] == 0)
        data = dai.functions.allowance(Web3.toChecksumAddress(
            self.pub[0]), dai_join_addr).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(dai_addr, data)
        assert_equal(int(result, 0), 100000)
        data = dai.functions.rely(dai_join_addr).buildTransaction(
            self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, dai_addr, data,
                                    0)
        assert (result["outcomeStatus"] == 0)

        # mint dai tokens for join_addr in vat & add approval
        self.tx_conf["to"] = vat_addr
        data = vat.functions.mint(
            dai_join_addr, 100000000000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender, self.priv_key, vat_addr, data,
                                    0)
        assert (result["outcomeStatus"] == 0)
        data = vat.functions.hope(dai_join_addr).buildTransaction(
            self.tx_conf)["data"]
        result = self.call_contract(self.pub[0], self.pri[0], vat_addr, data,
                                    0)
        assert (result["outcomeStatus"] == 0)
        data = vat.functions.balanceOf(dai_join_addr).buildTransaction(
            self.tx_conf)["data"]
        result = self.rpc.call(vat_addr, data)
        assert_equal(int(result, 0), 100000000000)

        # join
        self.tx_conf["to"] = dai_join_addr
        data = dai_join.functions.join(Web3.toChecksumAddress(
            self.pub[0]), 50000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.pub[0], self.pri[0], dai_join_addr,
                                    data, 0)
        assert (result["outcomeStatus"] == 0)

        # check
        self.tx_conf["to"] = dai_addr
        data = dai.functions.balanceOf(Web3.toChecksumAddress(
            self.pub[0])).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(dai_addr, data)
        assert_equal(int(result, 0), 50000)

        self.tx_conf["to"] = vat_addr
        data = vat.functions.can(dai_join_addr,
                                 Web3.toChecksumAddress(
                                     self.pub[0])).buildTransaction(
                                         self.tx_conf)["data"]
        result = self.rpc.call(vat_addr, data)
        assert_equal(int(result, 0), 1)

        data = vat.functions.dai(Web3.toChecksumAddress(
            self.pub[0])).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(vat_addr, data)
        assert_equal(int(result, 0), 50000000000000000000000000000000)

        # exit
        self.tx_conf["to"] = dai_join_addr
        data = dai_join.functions.exit(Web3.toChecksumAddress(
            self.pub[0]), 50000).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.pub[0], self.pri[0], dai_join_addr,
                                    data, 0)
        assert (result["outcomeStatus"] == 0)

        # check
        self.tx_conf["to"] = dai_addr
        data = dai.functions.balanceOf(Web3.toChecksumAddress(
            self.pub[0])).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(dai_addr, data)
        assert_equal(int(result, 0), 100000)

        self.tx_conf["to"] = vat_addr
        data = vat.functions.can(dai_join_addr,
                                 Web3.toChecksumAddress(
                                     self.pub[0])).buildTransaction(
                                         self.tx_conf)["data"]
        result = self.rpc.call(vat_addr, data)
        assert_equal(int(result, 0), 0)

        data = vat.functions.dai(Web3.toChecksumAddress(
            self.pub[0])).buildTransaction(self.tx_conf)["data"]
        result = self.rpc.call(vat_addr, data)
        assert_equal(int(result, 0), 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")

    def address_to_topic(self, address):
        return "0x" + address[2:].zfill(64)

    def number_to_topic(self, number):
        return "0x" + ("%x" % number).zfill(64)

    def deploy_contract(self, sender, priv_key, data_hex):
        tx = self.rpc.new_contract_tx(receiver="",
                                      data_hex=data_hex,
                                      sender=sender,
                                      priv_key=priv_key)
        assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex())
        receipt = self.rpc.get_transaction_receipt(tx.hash_hex())
        address = receipt["contractCreated"]
        assert_is_hex_string(address)
        return receipt, address

    def call_contract(self, sender, priv_key, contract, data_hex, value=0):
        tx = self.rpc.new_contract_tx(receiver=contract,
                                      data_hex=data_hex,
                                      sender=sender,
                                      priv_key=priv_key,
                                      value=value)
        assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex())
        receipt = self.rpc.get_transaction_receipt(tx.hash_hex())
        return receipt

    def fixto64(self, x):
        return '0x' + ('0' * (66 - len(x))) + x[2:]
示例#15
0
    def run_test(self):
        start_p2p_connection(self.nodes)
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()

        file_dir = os.path.dirname(os.path.realpath(__file__))

        self.log.info("Initializing contract")
       
        self.buggy_contract = get_contract_instance(
            source=os.path.join(file_dir, "contracts/reentrancy.sol"),
            contract_name="Reentrance")
        self.exploit_contract = get_contract_instance(
            source=os.path.join(file_dir, "contracts/reentrancy_exploit.sol"),
            contract_name="ReentranceExploit")

        user1, _ = ec_random_keys()
        user1_addr = priv_to_addr(user1)
        user1_addr_hex = eth_utils.encode_hex(user1_addr)
        user2, _ = ec_random_keys()
        user2_addr = priv_to_addr(user2)
        user2_addr_hex = eth_utils.encode_hex(user2_addr)

        # setup balance
        value = (10 ** 15 + 2000) * 10 ** 18 + ReentrancyTest.REQUEST_BASE['gas']
        tx = create_transaction(
            pri_key=self.genesis_priv_key,
            receiver=user1_addr,
            value=value,
            nonce=self.get_nonce(self.genesis_addr),
            gas_price=ReentrancyTest.REQUEST_BASE['gas'])
        self.send_transaction(tx, True, False)

        tx = create_transaction(
            pri_key=self.genesis_priv_key,
            receiver=user2_addr,
            value=value,
            nonce=self.get_nonce(self.genesis_addr),
            gas_price=ReentrancyTest.REQUEST_BASE['gas'])
        self.send_transaction(tx, True, False)

        user1_balance = parse_as_int(self.nodes[0].cfx_getBalance(user1_addr_hex))
        assert_equal(user1_balance, value)
        user2_balance_before_contract_construction = parse_as_int(self.nodes[0].cfx_getBalance(user2_addr_hex))
        assert_equal(user2_balance_before_contract_construction, value)

        transaction = self.call_contract_function(self.buggy_contract, "constructor", [], self.genesis_priv_key, storage_limit=20000)
        contract_addr = self.wait_for_tx([transaction], True)[0]['contractCreated']

        transaction = self.call_contract_function(self.exploit_contract, "constructor", [], user2, storage_limit=200000)
        exploit_addr = self.wait_for_tx([transaction], True)[0]['contractCreated']
        user2_balance_after_contract_construction = parse_as_int(self.nodes[0].cfx_getBalance(user2_addr_hex))
        self.log.debug("user2 balance contract created %s" % user2_balance_after_contract_construction)
        assert_greater_than_or_equal(user2_balance_before_contract_construction, user2_balance_after_contract_construction)
        user2_refund_upper_bound = \
            user2_balance_before_contract_construction - \
            user2_balance_after_contract_construction

        transaction = self.call_contract_function(self.buggy_contract, "addBalance", [], user1, 10 ** 18,
                                                  contract_addr, True, True, storage_limit=128)
        transaction = self.call_contract_function(self.exploit_contract, "deposit", [Web3.toChecksumAddress(contract_addr)], user2, 10 ** 18,
                                                  exploit_addr, True, True, storage_limit=128)

        user1_balance = parse_as_int(self.nodes[0].cfx_getBalance(user1_addr_hex))
        assert_greater_than_or_equal(user1_balance, 899999999999999999999999950000000)
        user2_balance_after_deposit = parse_as_int(self.nodes[0].cfx_getBalance(user2_addr_hex))
        # User2 paid storage collateral `vulnerable_contract` in deposit call.
        user2_refund_upper_bound += 10 ** 18 // 16
        self.log.debug("user2 balance after deposit %s" % user2_balance_after_deposit)
        assert_greater_than_or_equal(user2_balance_after_contract_construction, user2_balance_after_deposit + 10 ** 18)
        assert_greater_than_or_equal(user2_balance_after_deposit, 899999999999999999999999900000000)
        contract_balance = parse_as_int(self.nodes[0].cfx_getBalance(contract_addr))
        assert_equal(contract_balance, 2 * 10 ** 18)
        user2_balance_in_contract = RpcClient(self.nodes[0]).call(
            contract_addr,
            self.buggy_contract.functions.balanceOf(Web3.toChecksumAddress(exploit_addr)).buildTransaction(
                {"from":user2_addr_hex, "to":contract_addr, "gas":int_to_hex(CONTRACT_DEFAULT_GAS), "gasPrice":int_to_hex(1), "chainId":0}
            )["data"])
        assert_equal(parse_as_int(user2_balance_in_contract), 10 ** 18)

        transaction = self.call_contract_function(self.exploit_contract, "launch_attack", [], user2, 0,
                                                  exploit_addr, True, True, storage_limit=128)
        transaction = self.call_contract_function(self.exploit_contract, "get_money", [], user2, 0,
                                                  exploit_addr, True, True, storage_limit=128)

        user1_balance = parse_as_int(self.nodes[0].cfx_getBalance(user1_addr_hex))
        assert_greater_than_or_equal(user1_balance, 899999999999999999999999950000000)
        contract_balance = parse_as_int(self.nodes[0].cfx_getBalance(contract_addr))
        assert_equal(contract_balance, 1 * 10 ** 18)

        user2_balance_in_contract = RpcClient(self.nodes[0]).call(
            contract_addr,
            self.buggy_contract.functions.balanceOf(Web3.toChecksumAddress(exploit_addr)).buildTransaction(
                {"from":user2_addr_hex, "to":contract_addr, "gas":int_to_hex(CONTRACT_DEFAULT_GAS), "gasPrice":int_to_hex(1), "chainId":0}
            )["data"])

        assert_equal(parse_as_int(user2_balance_in_contract), 0)
        self.log.debug("user2 balance in contract %s" % user2_balance_in_contract)
        user2_balance_after_contract_destruct = parse_as_int(self.nodes[0].cfx_getBalance(user2_addr_hex))
        self.log.debug("user2 balance after contract destruct %s" % user2_balance_after_contract_destruct)
        assert_greater_than_or_equal(
            user2_balance_after_contract_destruct,
            user2_balance_after_deposit + user2_refund_upper_bound + 10 ** 18
            )

        block_gen_thread.stop()
        block_gen_thread.join()
示例#16
0
    def run_test(self):
        file_dir = os.path.dirname(os.path.realpath(__file__))

        storage_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/simple_storage.abi"),
            bytecode_file=os.path.join(file_dir,
                                       "contracts/simple_storage.dat"),
        )

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_addr = self.genesis_addr
        self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr)))

        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()

        client = RpcClient(self.nodes[0])
        client1 = RpcClient(self.nodes[1])

        tx = client.new_tx(value=int(0.625 * CFX) + GDrip,
                           receiver=self.eth_hex_addr,
                           nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(client.get_balance(self.eth_hex_addr),
                     int(0.625 * CFX) + GDrip)

        # deploy pay contract
        block_gen_thread.stop(
        )  # stop the block generation to test transaction relay.
        time.sleep(3)
        self.log.info("Deploying contract")
        tx = self.call_contract_function(
            contract=storage_contract,
            name="constructor",
            args=[],
            sender_key=self.eth_priv_key,
            eth_tx=True,
        )
        assert_equal(tx["epoch_height"], 0xffff_ffff_ffff_ffff)
        wait_until(lambda: self.nodes[1].tx_inspect(tx.hash_hex())['exist'],
                   timeout=5)
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()

        receipt = self.wait_for_tx([tx], True)[0]
        assert_equal(int(receipt["storageCollateralized"], 0), 640)

        contract_addr = receipt['contractCreated']
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(client.get_collateral_for_storage(self.eth_hex_addr),
                     int(0.625 * CFX))
        assert_greater_than(GDrip, client.get_balance(self.eth_hex_addr))

        storage_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/simple_storage.abi"),
            bytecode_file=os.path.join(file_dir,
                                       "contracts/simple_storage.dat"),
        )

        # Should fail because of not enough balance for storage.
        self.log.info("Sending transaction without enough collateral")
        tx = self.call_contract_function(
            contract=storage_contract,
            contract_addr=contract_addr,
            name="setFresh",
            args=[],
            sender_key=self.eth_priv_key,
            eth_tx=True,
        )
        receipt = self.wait_for_tx([tx])[0]
        assert_equal(int(receipt["outcomeStatus"], 0), 1)

        sponsor_whitelist_contract_addr = Web3.toChecksumAddress(
            "0888000000000000000000000000000000000001")
        file_dir = os.path.dirname(os.path.realpath(__file__))
        control_contract_file_path = os.path.join(
            file_dir, "..", "internal_contract", "metadata",
            "SponsorWhitelistControl.json")
        control_contract_dict = json.loads(
            open(control_contract_file_path, "r").read())
        control_contract = get_contract_instance(
            contract_dict=control_contract_dict)
        self.log.info("Setting sponsor for collateral")
        self.call_contract_function(
            contract=control_contract,
            name="setSponsorForCollateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=1 * CFX,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True,
            check_status=True)
        self.log.info("Sending balance to eth_like tx")
        tx = client.new_tx(value=int(0.0625 * CFX),
                           receiver=self.eth_hex_addr,
                           nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        self.log.info("Setting whitelist for all")
        self.call_contract_function(
            contract=control_contract,
            name="addPrivilegeByAdmin",
            args=[
                Web3.toChecksumAddress(contract_addr),
                [Web3.toChecksumAddress("0x" + "0" * 40)]
            ],
            sender_key=self.eth_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            eth_tx=True,
            wait=True,
            check_status=True)

        # Should not fail because of sponsored
        self.log.info("Sending transaction when sponsored")
        time.sleep(3)
        block_gen_thread.stop(
        )  # stop the block generation to test transaction relay in sponsorship

        tx = self.call_contract_function(
            contract=storage_contract,
            contract_addr=contract_addr,
            name="setFresh",
            args=[],
            sender_key=self.eth_priv_key,
            eth_tx=True,
        )

        wait_until(lambda: self.nodes[1].tx_inspect(tx.hash_hex())['exist'],
                   timeout=5)
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()

        receipt = self.wait_for_tx([tx])[0]
        assert_equal(receipt["storageCoveredBySponsor"], True)
        assert_equal(int(receipt["storageCollateralized"], 0), 64)

        wait_until(lambda: checktx(self.nodes[1], tx.hash_hex()), timeout=20)

        self.log.info("Pass")
示例#17
0
 def check_packed():
     client = RpcClient(self.nodes[0])
     client.generate_block(1)
     return checktx(self.nodes[0], tx.hash_hex())
示例#18
0
    def run_test(self):
        time.sleep(3)

        ip = self.nodes[0].ip
        port = self.nodes[0].ethrpcport
        self.w3 = Web3(Web3.HTTPProvider(f'http://{ip}:{port}/'))

        assert_equal(self.w3.isConnected(), True)
        account = self.w3.eth.account.privateKeyToAccount(
            '0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709'
        )

        sender = account.address

        self.cross_space_transfer(sender, 1 * 10**18)
        assert_equal(1 * 10**18, self.w3.eth.get_balance(sender))

        self.test_deploy_1820()

        # Send eip-155 transaction
        receiver = Web3.toChecksumAddress(
            "10000000000000000000000000000000000000aa")
        signed = account.signTransaction({
            "to": receiver,
            "value": 1 * 10**17,
            "gasPrice": 1,
            "gas": 21000,
            "nonce": 0,
            "chainId": 10
        })
        tx_hash = signed["hash"]
        return_tx_hash = self.w3.eth.sendRawTransaction(
            signed["rawTransaction"])
        assert_equal(tx_hash, return_tx_hash)

        client = RpcClient(self.nodes[0])
        client.generate_block(1)
        client.generate_blocks(10)
        receipt = self.w3.eth.waitForTransactionReceipt(tx_hash)
        assert_equal(receipt["status"], 1)

        # Send pre eip-155 transaction
        signed = account.signTransaction({
            "to": receiver,
            "value": 1 * 10**17,
            "gasPrice": 1,
            "gas": 21000,
            "nonce": 1
        })
        tx_hash = signed["hash"]
        return_tx_hash = self.w3.eth.sendRawTransaction(
            signed["rawTransaction"])
        assert_equal(tx_hash, return_tx_hash)

        client.generate_block(1)
        client.generate_blocks(10)
        receipt = self.w3.eth.waitForTransactionReceipt(tx_hash)
        assert_equal(receipt["status"], 1)

        assert_equal(2 * 10**17, self.w3.eth.get_balance(receiver))
        assert_equal(8 * 10**17 - 42000, self.w3.eth.get_balance(sender))

        # Send to transaction
        mapped_sender = keccak_256(self.genesis_addr).digest()[-20:]
        receiver = Web3.toChecksumAddress(mapped_sender.hex())
        signed = account.signTransaction({
            "to": receiver,
            "value": 2 * 10**17,
            "gasPrice": 1,
            "gas": 21000,
            "nonce": 2
        })
        self.w3.eth.sendRawTransaction(signed["rawTransaction"])

        client = RpcClient(self.nodes[0])
        client.generate_block(1)
        client.generate_blocks(10)
        receipt = self.w3.eth.waitForTransactionReceipt(tx_hash)
        assert_equal(receipt["status"], 1)

        assert_equal(2 * 10**17, self.w3.eth.get_balance(mapped_sender))

        # Withdraw transaction
        self.cross_space_withdraw(1 * 10**17)

        assert_equal(1 * 10**17, self.w3.eth.get_balance(mapped_sender))

        # Send transaction with large chain-id, should not panic.
        signed = account.signTransaction({
            "to": receiver,
            "value": 1 * 10**17,
            "gasPrice": 1,
            "gas": 21000,
            "nonce": 3,
            "chainId": 2**33
        })
        assert_raises(ValueError, self.w3.eth.sendRawTransaction,
                      signed["rawTransaction"])

        self.nodes[0].stop()
示例#19
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")
示例#20
0
    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 = 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}

        # 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)
        # code collateral + key value
        storage_limit = 512 * 11 + 64
        tx = self.call_contract_function(
            contract=test_contract,
            name="constructor",
            args=[],
            sender_key=priv_key,
            storage_limit=storage_limit)
        contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated']
        c1 = client.get_collateral_for_storage(addr)
        assert_equal(c1 - c0, storage_limit * COLLATERAL_UNIT_IN_DRIP)
        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")
    def run_test(self):
        sponsor_whitelist_contract_addr = Web3.toChecksumAddress(
            "8ad036480160591706c831f0da19d1a424e39469")
        bytes_per_key = 64
        collateral_per_storage_key = 10**18 // 16
        upper_bound = 5 * 10**7

        file_dir = os.path.dirname(os.path.realpath(__file__))

        control_contract_file_path = os.path.dirname(
            os.path.realpath(__file__)).split("/")
        control_contract_file_path.pop(-1)
        control_contract_file_path.extend(
            ["internal_contract", "metadata", "SponsorWhitelistControl.json"])
        control_contract_file_path = "/".join(control_contract_file_path)
        control_contract_dict = json.loads(
            open(os.path.join(control_contract_file_path), "r").read())

        control_contract = get_contract_instance(
            contract_dict=control_contract_dict)

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

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_key = self.genesis_priv_key
        genesis_addr = encode_hex(self.genesis_addr)
        self.log.info("genesis_addr={}".format(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(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)
        (addr1, priv_key1) = client.rand_account()
        (addr2, priv_key2) = client.rand_account()
        (addr3, priv_key3) = client.rand_account()
        tx = client.new_tx(sender=genesis_addr,
                           priv_key=genesis_key,
                           value=10**18,
                           nonce=self.get_nonce(self.genesis_addr),
                           receiver=addr1)
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr1), 10**18)
        tx = client.new_tx(sender=genesis_addr,
                           priv_key=genesis_key,
                           value=10**18,
                           nonce=self.get_nonce(self.genesis_addr),
                           receiver=addr2)
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr2), 10**18)
        tx = client.new_tx(sender=genesis_addr,
                           priv_key=genesis_key,
                           value=3 * 10**18,
                           nonce=self.get_nonce(self.genesis_addr),
                           receiver=addr3)
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr3), 3 * 10**18)

        # setup contract
        transaction = self.call_contract_function(
            contract=test_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(client.get_balance(contract_addr), 0)

        # sponsor the contract failed due to sponsor_balance < 1000 * upper_bound
        b0 = client.get_balance(genesis_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_gas",
            args=[Web3.toChecksumAddress(contract_addr), upper_bound],
            value=upper_bound * 1000 - 1,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 0)
        assert_equal(client.get_sponsor_for_gas(contract_addr),
                     "0x0000000000000000000000000000000000000000")
        assert_equal(client.get_sponsor_gas_bound(contract_addr), 0)
        assert_equal(client.get_balance(genesis_addr), b0 - gas)

        # sponsor the contract succeed
        b0 = client.get_balance(genesis_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_gas",
            args=[Web3.toChecksumAddress(contract_addr), upper_bound],
            value=10**18,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18)
        assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr)
        assert_equal(client.get_sponsor_gas_bound(contract_addr), upper_bound)
        assert_equal(client.get_balance(genesis_addr),
                     b0 - 10**18 - gas + 12500000)

        # set privilege for addr1
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="add",
                                    args=[Web3.toChecksumAddress(addr1)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_balance(genesis_addr),
                     b0 - gas + 12500000 - collateral_per_storage_key)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + collateral_per_storage_key)

        # addr1 call contract with privilege
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_balance(addr1), b1)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sb - gas + 12500000)

        # addr1 call contract with privilege and large tx fee
        b1 = client.get_balance(addr1)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True,
                                    gas=upper_bound + 1)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_balance(addr1),
                     b1 - upper_bound + upper_bound // 4 - 1)

        # addr2 call contract without privilege
        b2 = client.get_balance(addr2)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_balance(addr2), b2 - gas + 12500000)

        # set privilege for addr2
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="add",
                                    args=[Web3.toChecksumAddress(addr2)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_balance(genesis_addr),
                     b0 - gas + 12500000 - collateral_per_storage_key)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 + collateral_per_storage_key)

        # now, addr2 call contract with privilege
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sb - gas + 12500000)
        assert_equal(client.get_balance(addr2), b2)

        # remove privilege for addr1
        b0 = client.get_balance(genesis_addr)
        c0 = client.get_collateral_for_storage(genesis_addr)
        self.call_contract_function(contract=test_contract,
                                    name="remove",
                                    args=[Web3.toChecksumAddress(addr1)],
                                    sender_key=genesis_key,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_collateral_for_storage(genesis_addr),
                     c0 - collateral_per_storage_key)
        assert_equal(client.get_balance(genesis_addr),
                     b0 - gas + 12500000 + collateral_per_storage_key)

        # addr1 call contract without privilege
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="foo",
                                    args=[],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    check_status=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_balance(addr1), b1 - gas + 12500000)

        # new sponsor failed due to small sponsor_balance
        b3 = client.get_balance(addr3)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_gas",
            args=[Web3.toChecksumAddress(contract_addr), upper_bound + 1],
            value=5 * 10**17,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr)
        assert_equal(client.get_balance(addr3), b3 - gas)

        # new sponsor failed due to small upper bound
        b3 = client.get_balance(addr3)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_gas",
            args=[Web3.toChecksumAddress(contract_addr), upper_bound],
            value=10**18,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), sb)
        assert_equal(client.get_sponsor_for_gas(contract_addr), genesis_addr)
        assert_equal(client.get_balance(addr3), b3 - gas)

        # new sponsor succeed
        b0 = client.get_balance(genesis_addr)
        b3 = client.get_balance(addr3)
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_gas",
            args=[Web3.toChecksumAddress(contract_addr), upper_bound + 1],
            value=10**18,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr), 10**18)
        assert_equal(client.get_sponsor_gas_bound(contract_addr),
                     upper_bound + 1)
        assert_equal(client.get_sponsor_for_gas(contract_addr), addr3)
        assert_equal(client.get_balance(addr3), b3 - 10**18 - gas + 12500000)
        assert_equal(client.get_balance(genesis_addr), b0 + sb)

        # sponsor the contract for collateral failed due to zero sponsor balance
        b3 = client.get_balance(addr3)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_collateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=0,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     0)
        assert_equal(client.get_sponsor_for_collateral(contract_addr),
                     "0x0000000000000000000000000000000000000000")
        assert_equal(client.get_balance(addr3), b3 - gas)

        # sponsor the contract for collateral succeed
        b3 = client.get_balance(addr3)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_collateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=10**18 - 1,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     10**18 - 1)
        assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3)
        assert_equal(client.get_balance(addr3),
                     b3 - gas + 12500000 - 10**18 + 1)

        # addr1 create 2 keys without privilege, and storage limit is 1, should failed
        b1 = client.get_balance(addr1)
        assert_equal(client.get_collateral_for_storage(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(addr1), 0)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[0, 2],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key)
        assert_equal(client.get_collateral_for_storage(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(addr1), 0)
        assert_equal(client.get_balance(addr1), b1 - gas)

        # addr1 create 2 keys without privilege, and storage limit is 2, should succeed
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[0, 2],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 2)
        assert_equal(client.get_collateral_for_storage(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(addr1),
                     collateral_per_storage_key * 2)
        assert_equal(client.get_balance(addr1),
                     b1 - gas + 12500000 - collateral_per_storage_key * 2)

        # remove 1 key create by addr1
        b1 = client.get_balance(addr1)
        self.call_contract_function(contract=test_contract,
                                    name="par_del",
                                    args=[0, 1],
                                    sender_key=priv_key1,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 2)
        assert_equal(client.get_collateral_for_storage(contract_addr), 0)
        assert_equal(client.get_collateral_for_storage(addr1),
                     collateral_per_storage_key)
        assert_equal(client.get_balance(addr1),
                     b1 - gas + 12500000 + collateral_per_storage_key)

        # addr2 create 2 keys with privilege, and storage limit is 1, should succeed
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[2, 4],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 2)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc - collateral_per_storage_key * 2)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - gas + 12500000)
        assert_equal(client.get_collateral_for_storage(addr2), 0)
        assert_equal(client.get_balance(addr2), b2)

        # addr2 create 13 keys with privilege, and storage limit is 0, should succeed
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[4, 17],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=0)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 15)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc - collateral_per_storage_key * 13)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - gas + 12500000)
        assert_equal(client.get_collateral_for_storage(addr2), 0)
        assert_equal(client.get_balance(addr2), b2)

        # now sponsor_balance is unable to pay collateral for storage
        # the balance of addr2 is able to pay 15 collateral for storage, but not 16
        assert_greater_than(
            collateral_per_storage_key,
            client.get_sponsor_balance_for_collateral(contract_addr))
        assert_greater_than(collateral_per_storage_key * 16,
                            client.get_balance(addr2))
        assert_greater_than(client.get_balance(addr2),
                            collateral_per_storage_key * 15)

        # addr2 create 1 keys with privilege, and storage limit is 0, should failed
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[17, 18],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=0)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 15)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - gas)
        assert_equal(client.get_collateral_for_storage(addr2), 0)
        assert_equal(client.get_balance(addr2), b2)

        # addr2 create 1 keys with privilege, and storage limit is 2, should succeed
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_add",
                                    args=[17, 18],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key * 2)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 15)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - gas + 12500000)
        assert_equal(client.get_collateral_for_storage(addr2),
                     collateral_per_storage_key)
        assert_equal(client.get_balance(addr2),
                     b2 - collateral_per_storage_key)

        # addr2 del 10 keys with privilege
        sbc = client.get_sponsor_balance_for_collateral(contract_addr)
        sbg = client.get_sponsor_balance_for_gas(contract_addr)
        b2 = client.get_balance(addr2)
        self.call_contract_function(contract=test_contract,
                                    name="par_del",
                                    args=[2, 12],
                                    sender_key=priv_key2,
                                    contract_addr=contract_addr,
                                    wait=True,
                                    storage_limit=bytes_per_key)
        assert_equal(client.get_collateral_for_storage(contract_addr),
                     collateral_per_storage_key * 5)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sbc + collateral_per_storage_key * 10)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sbg - gas + 12500000)
        assert_equal(client.get_collateral_for_storage(addr2),
                     collateral_per_storage_key)
        assert_equal(client.get_balance(addr2), b2)

        # addr3 sponsor more, treat as transfer
        b3 = client.get_balance(addr3)
        sb = client.get_sponsor_balance_for_collateral(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_collateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=sb,
            sender_key=priv_key3,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sb * 2)
        assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3)
        assert_equal(client.get_balance(addr3), b3 - gas + 12500000 - sb)

        # genesis sponsor with sponsor balance, should failed
        b0 = client.get_balance(genesis_addr)
        sb = client.get_sponsor_balance_for_collateral(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_collateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=sb + 1,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sb)
        assert_equal(client.get_sponsor_for_collateral(contract_addr), addr3)
        assert_equal(client.get_balance(genesis_addr), b0 - gas)

        # genesis sponsor with sponsor balance and collateral_for_storage, should succeed
        b0 = client.get_balance(genesis_addr)
        b3 = client.get_balance(addr3)
        cfs = client.get_collateral_for_storage(contract_addr)
        sb = client.get_sponsor_balance_for_collateral(contract_addr)
        self.call_contract_function(
            contract=control_contract,
            name="set_sponsor_for_collateral",
            args=[Web3.toChecksumAddress(contract_addr)],
            value=sb + cfs + 1,
            sender_key=self.genesis_priv_key,
            contract_addr=sponsor_whitelist_contract_addr,
            wait=True)
        assert_equal(client.get_collateral_for_storage(contract_addr), cfs)
        assert_equal(client.get_sponsor_balance_for_collateral(contract_addr),
                     sb + cfs + 1)
        assert_equal(client.get_sponsor_for_collateral(contract_addr),
                     genesis_addr)
        assert_equal(client.get_balance(genesis_addr),
                     b0 - gas + 12500000 - sb - cfs - 1)
        assert_equal(client.get_balance(addr3), b3 + sb + cfs)

        self.log.info("Pass")
示例#22
0
 def run_test(self):
     client = RpcClient(self.nodes[0])
     # wait for the first epoch to end
     wait_until(lambda: client.pos_status()["latestVoted"] is not None)
     print(client.pos_status())
     wait_until(lambda: int(client.pos_status()["latestCommitted"], 0) == 8)
     self.log.info("wait for empty rounds")
     self.stop_node(2)
     self.stop_node(3)
     time.sleep(5)
     self.start_node(2)
     self.start_node(3)
     self.log.info("restarts")
     print(client.pos_status())
     # wait for the next epoch
     wait_until(lambda: int(client.pos_status()["epoch"], 0) == 2)
     parent = client.pos_get_block(2)["hash"]
     for v in range(3, 11):
         print(v)
         b = client.pos_get_block(v)
         assert_equal(b["parentHash"], parent)
         parent = b["hash"]
     wait_until(lambda: int(client.pos_status()["epoch"], 0) == 3)
     parent = client.pos_get_block(11)["hash"]
     for v in range(12, 21):
         print(v)
         b = client.pos_get_block(v)
         assert_equal(b["parentHash"], parent)
         parent = b["hash"]
     wait_until(lambda: client.pos_get_block(21) is not None)
     assert_equal(int(client.pos_get_block(21)["epoch"], 0), 3)
示例#23
0
    def run_test(self):
        block_number = 10

        for i in range(1, block_number):
            chosen_peer = random.randint(0, self.num_nodes - 1)
            block_hash = self.nodes[chosen_peer].generate_empty_blocks(1)
            self.log.info("generate block %s", block_hash)
        wait_for_block_count(self.nodes[0], block_number, timeout=30)
        sync_blocks(self.nodes, timeout=30)
        self.log.info("generated blocks received by all")

        self.stop_node(0, kill=True)
        self.log.info("node 0 stopped")
        block_hash = self.nodes[-1].generate_empty_blocks(1)
        self.log.info("generate block %s", block_hash)
        wait_for_block_count(self.nodes[1], block_number + 1)
        sync_blocks(self.nodes[1:], timeout=30)
        self.log.info("blocks sync success among running nodes")
        self.start_node(0)
        sync_blocks(self.nodes, timeout=30)
        self.log.info("Pass 1")

        for i in range(1, self.num_nodes):
            self.stop_node(i, kill=True)
        genesis = self.nodes[0].cfx_getBlockByEpochNumber("0x0", False)["hash"]
        self.nodes[0].add_p2p_connection(P2PInterface(genesis))
        network_thread_start()
        self.nodes[0].p2p.wait_for_status()
        client = RpcClient(self.nodes[0])
        gas_price = 1
        value = 1
        receiver_sk, _ = ec_random_keys()
        sender_key = default_config["GENESIS_PRI_KEY"]
        tx = create_transaction(pri_key=sender_key,
                                receiver=priv_to_addr(receiver_sk),
                                value=value,
                                nonce=0,
                                gas_price=gas_price)
        self.nodes[0].p2p.send_protocol_msg(Transactions(transactions=[tx]))
        self.log.debug("New tx %s: %s send value %d to %s",
                       encode_hex(tx.hash),
                       eth_utils.encode_hex(priv_to_addr(sender_key))[-4:],
                       value,
                       eth_utils.encode_hex(priv_to_addr(receiver_sk))[-4:])

        def check_packed():
            client.generate_block(1)
            return checktx(self.nodes[0], tx.hash_hex())

        wait_until(lambda: check_packed())
        sender_addr = eth_utils.encode_hex(priv_to_addr(sender_key))
        receiver_addr = eth_utils.encode_hex(priv_to_addr(receiver_sk))
        sender_balance = default_config[
            "TOTAL_COIN"] - value - gas_price * 21000
        # Generate 2 * CACHE_INDEX_STRIDE to start evicting anticone cache
        self.nodes[0].generate_empty_blocks(2000)
        assert_equal(client.get_balance(sender_addr), sender_balance)
        assert_equal(client.get_balance(receiver_addr), value)
        time.sleep(1)
        self.stop_node(0)
        self.start_node(0)
        self.log.info("Wait for node 0 to recover from crash")
        wait_until(lambda: client.get_balance(sender_addr) == sender_balance)
        wait_until(lambda: client.get_balance(receiver_addr) == value)
        self.log.info("Pass 2")
    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(
            "0888000000000000000000000000000000000002")
        # 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")
示例#25
0
    def run_test(self):
        file_dir = os.path.dirname(os.path.realpath(__file__))

        pay_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/pay_abi.json"),
            bytecode_file=os.path.join(file_dir, "contracts/pay_bytecode.dat"),
        )

        admin_control_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/admin_control_abi.json"),
            bytecode_file=os.path.join(file_dir, "contracts/admin_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(client.get_balance(addr), 5000000000000000000)

        (addr2, priv_key2) = client.rand_account()
        self.log.info("addr2=%s priv_key2=%s", addr2, priv_key2)
        tx = client.new_tx(value=5 * 10 ** 18, receiver=addr2, nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr2), 5000000000000000000)

        # deploy pay contract
        tx = self.call_contract_function(
            contract=pay_contract,
            name="constructor",
            args=[],
            sender_key=priv_key)
        contract_addr = self.wait_for_tx([tx], True)[0]['contractCreated']
        self.log.info("contract_addr={}".format(contract_addr))
        assert_equal(client.get_balance(contract_addr), 0)

        # deposit 10**18
        b0 = int(node.cfx_getBalance(addr), 16)
        tx = self.call_contract_function(
            contract=pay_contract,
            name="recharge",
            args=[],
            sender_key=priv_key,
            contract_addr=contract_addr,
            value=10 ** 18,
            wait=True,
            check_status=True)
        assert_equal(client.get_balance(contract_addr), 10 ** 18)
        assert_equal(client.get_balance(addr), b0 - 10 ** 18 - gas + gas // 4)
        assert_equal(client.get_admin(contract_addr), addr)

        # transfer admin (fail)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="set_admin",
            args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)],
            sender_key=priv_key2,
            contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"),
            wait=True,
            check_status=True)
        assert_equal(client.get_admin(contract_addr), addr)

        # transfer admin (success)
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="set_admin",
            args=[Web3.toChecksumAddress(contract_addr), Web3.toChecksumAddress(addr2)],
            sender_key=priv_key,
            contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"),
            wait=True,
            check_status=True)
        assert_equal(client.get_admin(contract_addr), addr2)

        # destroy
        tx = self.call_contract_function(
            contract=admin_control_contract,
            name="destroy",
            args=[Web3.toChecksumAddress(contract_addr)],
            sender_key=priv_key2,
            contract_addr=Web3.toChecksumAddress("0x6060de9e1568e69811c4a398f92c3d10949dc891"),
            wait=True,
            check_status=True)
        assert_equal(client.get_balance(contract_addr), 0)
        assert_equal(client.get_balance(addr2), 5999999999912500000 + gas // 4)

        self.log.info("Pass")
示例#26
0
    def wait_for_txs(self, node, txs):
        client = RpcClient(node)

        for tx_hash in txs:
            while client.get_tx(tx_hash) is None:
                time.sleep(0.3)
示例#27
0
class LogFilteringTest(ConfluxTestFramework):
    def set_test_params(self):
        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(priv_to_addr(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))
        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_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()")),
                               storage_limit=0)

        # apply filter, we expect NUM_CALLS log entries with inreasing uint32 fields
        filter = Filter(from_epoch="earliest", to_epoch="latest_mined")
        logs = self.rpc.get_logs(filter)

        self.assert_response_format_correct(logs)
        assert_equal(len(logs), NUM_CALLS)

        for ii in range(2, NUM_CALLS):
            assert_equal(len(logs[ii]["topics"]), 3)
            assert_equal(logs[ii]["topics"][0], CALLED_TOPIC)
            assert (logs[ii]["topics"][1] == self.address_to_topic(sender))
            assert_equal(logs[ii]["topics"][2], self.number_to_topic(ii))

        # apply filter for specific topics
        filter = Filter(topics=[CONSTRUCTED_TOPIC])
        logs = self.rpc.get_logs(filter)
        self.assert_response_format_correct(logs)
        assert_equal(len(logs), 1)

        filter = Filter(topics=[CALLED_TOPIC])
        logs = self.rpc.get_logs(filter)
        self.assert_response_format_correct(logs)
        assert_equal(len(logs), NUM_CALLS - 1)

        filter = Filter(topics=[None, self.address_to_topic(sender)])
        logs = self.rpc.get_logs(filter)
        self.assert_response_format_correct(logs)
        assert_equal(len(logs), NUM_CALLS)

        # find logs with `CALLED_TOPIC` as 1st topic and `3` or `4` as 3rd topic
        filter = Filter(topics=[
            CALLED_TOPIC, None,
            [self.number_to_topic(3),
             self.number_to_topic(4)]
        ])
        logs = self.rpc.get_logs(filter)
        self.assert_response_format_correct(logs)
        assert_equal(len(logs), 2)

        # apply filter with limit
        filter = Filter(limit=("0x%x" % (NUM_CALLS // 2)))
        logs = self.rpc.get_logs(filter)

        self.assert_response_format_correct(logs)
        assert_equal(len(logs), NUM_CALLS // 2)

        # apply filter for specific contract address
        _, contractAddr2 = self.deploy_contract(sender, priv_key, bytecode)

        filter = Filter(address=[contractAddr])
        logs = self.rpc.get_logs(filter)
        self.assert_response_format_correct(logs)
        assert_equal(len(logs), NUM_CALLS)

        filter = Filter(address=[contractAddr2])
        logs = self.rpc.get_logs(filter)
        self.assert_response_format_correct(logs)
        assert_equal(len(logs), 1)

        # apply filter to very first epoch, we expect no logs
        filter = Filter(from_epoch="0x0", to_epoch="0x0")
        result = self.rpc.get_logs(filter)
        assert_equal(result, [])

        self.log.info("Pass")

    def address_to_topic(self, address):
        return "0x" + address[2:].zfill(64)

    def number_to_topic(self, number):
        return "0x" + ("%x" % number).zfill(64)

    def deploy_contract(self, sender, priv_key, data_hex):
        c0 = self.rpc.get_collateral_for_storage(sender)
        tx = self.rpc.new_contract_tx(receiver="",
                                      data_hex=data_hex,
                                      sender=sender,
                                      priv_key=priv_key,
                                      storage_limit=253)
        assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex())
        receipt = self.rpc.get_transaction_receipt(tx.hash_hex())
        assert_equal(receipt["outcomeStatus"], 0)
        address = receipt["contractCreated"]
        c1 = self.rpc.get_collateral_for_storage(sender)
        assert_equal(c1 - c0, 253 * 10**18 // 1024)
        assert_is_hex_string(address)
        return receipt, address

    def call_contract(self, sender, priv_key, contract, data_hex,
                      storage_limit):
        c0 = self.rpc.get_collateral_for_storage(sender)
        tx = self.rpc.new_contract_tx(receiver=contract,
                                      data_hex=data_hex,
                                      sender=sender,
                                      priv_key=priv_key,
                                      storage_limit=storage_limit)
        assert_equal(self.rpc.send_tx(tx, True), tx.hash_hex())
        receipt = self.rpc.get_transaction_receipt(tx.hash_hex())
        assert_equal(receipt["outcomeStatus"], 0)
        c1 = self.rpc.get_collateral_for_storage(sender)
        assert_equal(c1 - c0, storage_limit * 10**18 // 1024)
        return receipt

    def assert_response_format_correct(self, response):
        assert_equal(type(response), list)
        for log in response:
            self.assert_log_format_correct(log)

    def assert_log_format_correct(self, log):
        assert_is_hex_string(log["address"])
        assert_is_hex_string(log["epochNumber"])
        assert_is_hex_string(log["logIndex"])
        assert_is_hex_string(log["transactionIndex"])
        assert_is_hex_string(log["transactionLogIndex"])

        assert_is_hash_string(log["blockHash"])
        assert_is_hash_string(log["transactionHash"])

        assert_equal(type(log["topics"]), list)
示例#28
0
    def run_test(self):
        num_nodes = len(self.nodes)

        if self.tx_propagation_enabled:
            # Setup balance for each node
            client = RpcClient(self.nodes[0])
            for i in range(num_nodes):
                pub_key = self.nodes[i].key
                addr = self.nodes[i].addr
                self.log.info("%d has addr=%s pubkey=%s", i, encode_hex(addr), pub_key)
                tx = client.new_tx(value=int(default_config["TOTAL_COIN"]/(num_nodes + 1)) - 21000, receiver=encode_hex(addr), nonce=i)
                client.send_tx(tx)

        # setup monitor to report the current block count periodically
        cur_block_count = self.nodes[0].getblockcount()
        # The monitor will check the block_count of nodes[0]
        monitor_thread = threading.Thread(target=self.monitor, args=(cur_block_count, 100), daemon=True)
        monitor_thread.start()

        # generate blocks
        threads = {}
        rpc_times = []
        for i in range(1, self.options.num_blocks + 1):
            wait_sec = random.expovariate(1000 / self.options.generation_period_ms)
            start = time.time()
            
            # find an idle node to generate block
            p = random.randint(0, num_nodes - 1)
            retry = 0
            while retry < 10:
                pre_thread = threads.get(p)
                if pre_thread is not None and pre_thread.is_alive():
                    p = random.randint(0, num_nodes - 1)
                    retry += 1
                    time.sleep(0.01)
                else:
                    break

            if retry >= 10:
                self.log.warn("too many nodes are busy to generate block, stop to analyze logs.")
                break

            if self.tx_propagation_enabled:
                # Generate a block with the transactions in the node's local tx pool
                thread = SimpleGenerateThread(self.nodes, p, self.options.txs_per_block, self.options.generate_tx_data_len, self.log, rpc_times)
            else:
                # Generate a fixed-size block with fake tx
                thread = GenerateThread(self.nodes, p, self.options.txs_per_block, self.options.generate_tx_data_len, self.log, rpc_times)
            thread.start()
            threads[p] = thread

            if i % self.options.block_sync_step == 0:
                self.log.info("[PROGRESS] %d blocks generated async", i)

            elapsed = time.time() - start
            if elapsed < wait_sec:
                self.log.debug("%d generating block %.2f", p, elapsed)
                time.sleep(wait_sec - elapsed)
            else:
                self.log.warn("%d generating block slowly %.2f", p, elapsed)

        monitor_thread.join()
        self.sync_blocks()

        self.log.info("generateoneblock RPC latency: {}".format(Statistics(rpc_times, 3).__dict__))
        self.log.info("Best block: {}".format(RpcClient(self.nodes[0]).best_block_hash()))
示例#29
0
    def run_test(self):
        file_dir = os.path.dirname(os.path.realpath(__file__))

        storage_contract = get_contract_instance(
            abi_file=os.path.join(file_dir, "contracts/simple_storage.abi"),
            bytecode_file=os.path.join(file_dir, "contracts/simple_storage.dat"),
        )

        start_p2p_connection(self.nodes)

        self.log.info("Initializing contract")
        genesis_addr = self.genesis_addr
        self.log.info("genesis_addr={}".format(encode_hex_0x(genesis_addr)))

        block_gen_thread = BlockGenThread(self.nodes, self.log, interval_fixed=1)
        block_gen_thread.start()

        client = RpcClient(self.nodes[0])

        tx = client.new_tx(value=int(0.625 * CFX) + GDrip, receiver=self.eth_hex_addr,
                           nonce=self.get_nonce(genesis_addr))
        client.send_tx(tx, True)
        assert_equal(client.get_balance(self.eth_hex_addr), int(0.625 * CFX) + GDrip)

        # deploy contract
        self.log.info("Deploying contract")
        tx = self.call_contract_function(
            contract=storage_contract,
            name="constructor",
            args=[],
            sender_key=self.eth_priv_key,
            eth_tx=True,
        )

        wait_until(lambda: self.nodes[1].txpool_txWithPoolInfo(tx.hash_hex())['exist'], timeout=10)
        block_gen_thread.stop()

        client.generate_blocks(40)
        block_hash = client.generate_custom_block(client.best_block_hash(), [], [tx])
        wait_until(lambda: client.best_block_hash()==block_hash, timeout=10)
        client.generate_blocks(40)

        BlockGenThread(self.nodes, self.log, interval_fixed=1).start()

        receipt = self.wait_for_tx([tx])[0]

        assert_greater_than_or_equal(int(receipt['epochNumber'], 0), 80)

        self.log.info("All test done")
    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")