Exemplo n.º 1
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)
        self.nodes[0].add_p2p_connection(P2PInterface())
        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")
Exemplo n.º 2
0
    def test(self, num_senders, num_receivers, num_txs):
        self.log.debug("Initializing {} senders".format(num_senders))
        senders = self.init_senders(num_senders)

        self.log.debug("Initializing {} receivers".format(num_receivers))
        receivers = self.init_receivers(num_receivers)

        self.log.info(
            "begin to send {} txs to nodes and generate blocks ...".format(
                num_txs))
        txs = self.send_txs_async(senders, receivers, num_txs)

        # generate blocks to pack txs
        self.log.info(
            "continue to generate blocks to pack all transactions ...")
        client = RpcClient(self.nodes[0])
        retry = num_txs
        for sender in senders:
            while True:
                receipt = client.get_receipt(sender.last_tx_hash)
                if receipt is not None:
                    break

                assert retry > 0, "some tx not stated yet even after {} retries".format(
                    num_txs)
                retry -= 1

                self.generate_block(num_txs)
                time.sleep(0.5)

        self.log.info("sync up blocks among nodes ...")
        sync_blocks(self.nodes)

        # check DAG
        self.log.info("begin to validate DAG for all nodes ...")
        self.check_with_rpc(client.epoch_number)
        self.check_with_rpc(client.best_block_hash)
        self.check_with_rpc(client.gas_price)
        self.check_with_rpc(client.chain, True)

        # check receipt
        self.log.info("begin to validate transaction receipts ...")
        for idx in range(self.num_nodes):
            node_client = RpcClient(self.nodes[idx])

            for tx_hash in [sent_tx.hash_hex() for sent_tx in txs]:
                receipt = node_client.get_receipt(tx_hash)
                assert_equal(receipt is None, False)

        # check balance and nonce for all accounts
        self.log.info("begin to validate balance and nonce ...")
        all_accounts = list(senders)
        all_accounts.extend(receivers)
        for account in all_accounts:
            for idx in range(self.num_nodes):
                node_client = RpcClient(self.nodes[idx])
                assert_equal(node_client.get_balance(account.address),
                             account.balance)
                assert_equal(node_client.get_nonce(account.address),
                             account.nonce)
Exemplo n.º 3
0
    def run_test(self):
        num_blocks = 200
        checkpoint_epoch = 100

        # Generate checkpoint on node[0]
        client = RpcClient(self.nodes[0])
        genesis_nonce = client.get_nonce(client.GENESIS_ADDR)
        for _ in range(num_blocks):
            tx = client.new_tx(nonce=genesis_nonce)
            tx_hash = client.send_tx(tx)
            assert tx_hash == tx.hash_hex()
            genesis_nonce += 1
            client.generate_block(100)

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

        # FIXME full node issue that hang at phase CatchUpRecoverBlockFromDbPhase
        self.nodes[1].wait_for_phase(["CatchUpRecoverBlockFromDbPhase", "NormalSyncPhase"])

        sync_blocks(self.nodes)

        client = RpcClient(self.nodes[1])
        
        # FIXME conflux panics
        # At epoch 1, block header exists while body not synchronized
        # print(client.block_by_epoch(client.EPOCH_NUM(1)))

        # There is no state from epoch 1 to checkpoint_epoch
        # Note, state of genesis epoch always exists
        assert client.epoch_number() >= checkpoint_epoch
        for i in range(1, checkpoint_epoch):
            try:
                client.get_balance(client.GENESIS_ADDR, client.EPOCH_NUM(i))
                raise AssertionError("should be not 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

        # State should exist at checkpoint
        client.get_balance(client.GENESIS_ADDR, client.EPOCH_NUM(checkpoint_epoch))
    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].tx_inspect(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")
Exemplo n.º 5
0
 def run_test(self):
     client = RpcClient(self.nodes[0])
     genesis_address = "0x" + encode_hex(
         priv_to_addr(default_config['GENESIS_PRI_KEY']))
     genesis_balance = default_config["TOTAL_COIN"]
     client.generate_empty_blocks(ERA_EPOCH_COUNT * 10)
     print(client.epoch_number("latest_checkpoint"))
     assert client.epoch_number("latest_checkpoint") > 0
     # Just assert we can still get the balance
     assert_equal(client.get_balance(genesis_address, client.EPOCH_NUM(1)),
                  genesis_balance)
Exemplo n.º 6
0
    def run_test(self):
        num_blocks = 200
        checkpoint_epoch = 100

        # Generate checkpoint on node[0]
        client = RpcClient(self.nodes[0])
        self.genesis_nonce = client.get_nonce(client.GENESIS_ADDR)
        for _ in range(num_blocks):
            txs = self._generate_txs(0, random.randint(5, 10))
            client.generate_block_with_fake_txs(txs)

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

        # FIXME full node issue that hang at phase CatchUpRecoverBlockFromDbPhase
        self.nodes[1].wait_for_phase(["NormalSyncPhase"], wait_time=30)

        sync_blocks(self.nodes, sync_count=False)

        client = RpcClient(self.nodes[1])

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

        # There is no state from epoch 1 to checkpoint_epoch
        # Note, state of genesis epoch always exists
        assert client.epoch_number() >= checkpoint_epoch
        # FIXME: we minus REWARD_EPOCH_COUNT here as a workaround.
        # FIXME: after the state boundary is implemented in consensus,
        # FIXME: this workaround should be removed.
        for i in range(1, checkpoint_epoch - 11):
            try:
                client.get_balance(client.GENESIS_ADDR, 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

        # State should exist at checkpoint
        client.get_balance(client.GENESIS_ADDR,
                           client.EPOCH_NUM(checkpoint_epoch))

        # There should be states after checkpoint
        for i in range(checkpoint_epoch, client.epoch_number() - 3):
            client.get_balance(client.GENESIS_ADDR, client.EPOCH_NUM(i))
Exemplo n.º 7
0
 def check_account(self, k, balance_map):
     addr = eth_utils.encode_hex(priv_to_addr(k))
     client = RpcClient(self.nodes[0])
     try:
         balance = client.get_balance(addr)
         staking_balance = client.get_staking_balance(addr)
         collateral_for_storage = client.get_collateral_for_storage(addr)
     except Exception as e:
         self.log.info("Fail to get balance, error=%s", str(e))
         return False
     if balance + staking_balance + collateral_for_storage == balance_map[
             k]:
         return True
     else:
         self.log.info("Remote balance:%d, local balance:%d",
                       balance + staking_balance + collateral_for_storage,
                       balance_map[k])
         time.sleep(1)
         return False
Exemplo n.º 8
0
    def run_test(self):
        sponsor_whitelist_contract_addr = Web3.toChecksumAddress(
            "0888000000000000000000000000000000000001")
        bytes_per_key = 64
        collateral_per_byte = 10**18 // 1024
        collateral_per_storage_key = 10**18 // 16
        # block gas limit (GENESIS_GAS_LIMIT); -1 because below gas is set to upper_bound + 1
        upper_bound = default_config["GENESIS_GAS_LIMIT"] - 1

        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()
        (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=2723)
        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),
                     2723 * collateral_per_byte)

        # 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 - 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=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(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="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 - 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="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 - 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'], True)

        # 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="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 - 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="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 + 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")
Exemplo n.º 9
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(client.get_balance(addr), 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(client.get_balance(contract_addr), 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")
Exemplo n.º 11
0
    def run_test(self):
        sponsor_whitelist_contract_addr = Web3.toChecksumAddress(
            "0888000000000000000000000000000000000001")
        collateral_per_storage_key = COLLATERAL_UNIT_IN_DRIP * 64
        upper_bound = 5 * 10**7

        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()
        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="setSponsorForGas",
            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)
        transaction = 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)
        assert_equal(
            self.wait_for_tx([transaction], True)[0]['gasCoveredBySponsor'],
            False)

        # 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)
        transaction = 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))
        assert_equal(
            self.wait_for_tx([transaction], True)[0]['gasCoveredBySponsor'],
            True)

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

        # addr1 call contract with privilege without enough cfx for storage
        sb = client.get_sponsor_balance_for_gas(contract_addr)
        b1 = client.get_balance(addr1)
        transaction = self.call_contract_function(contract=test_contract,
                                                  name="foo",
                                                  args=[],
                                                  sender_key=priv_key1,
                                                  contract_addr=contract_addr,
                                                  wait=True,
                                                  check_status=True,
                                                  storage_limit=1024)
        assert_equal(client.get_balance(addr1), b1)
        assert_equal(client.get_sponsor_balance_for_gas(contract_addr),
                     sb - charged_of_huge_gas(gas))
        assert_equal(
            self.wait_for_tx([transaction],
                             True)[0]['storageCoveredBySponsor'], True)

        # addr1 call with larger storage limit, should not packed
        transaction = self.call_contract_function(contract=test_contract,
                                                  name="foo",
                                                  args=[],
                                                  sender_key=priv_key1,
                                                  contract_addr=contract_addr,
                                                  storage_limit=1025)
        for _ in range(10):
            client.generate_block()

        tx_info = self.nodes[0].txpool_txWithPoolInfo(transaction.hash_hex())
        assert_equal(int(tx_info['local_nonce'], 16), 2)
        assert_equal(tx_info['local_balance_enough'], False)
        assert_equal(tx_info['packed'], False)

        # send 1025 * 10 ** 18 // 1024 CFX to addr1
        tx = client.new_tx(sender=genesis_addr,
                           priv_key=genesis_key,
                           value=1025 * 10**18 // 1024,
                           nonce=self.get_nonce(self.genesis_addr),
                           receiver=addr1)
        client.send_tx(tx, True)
        assert_equal(client.get_balance(addr1), 10**6 + 1025 * 10**18 // 1024)
        for _ in range(10):
            client.generate_block()
        tx_info = self.nodes[0].txpool_txWithPoolInfo(transaction.hash_hex())
        # Now addr1 pays for storage collateral by itself.
        assert_equal(
            self.wait_for_tx([transaction],
                             True)[0]['storageCoveredBySponsor'], False)
        assert_equal(int(tx_info['local_nonce'], 16), 3)
        assert_equal(tx_info['packed'], True)

        self.log.info("Pass")
Exemplo n.º 12
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")
class MessageTest(ConfluxTestFramework):
    def set_test_params(self):
        self.num_nodes = 0
        self.conf_parameters = {"log_level":"\"error\""}

    def setup_network(self):
        self.setup_nodes()

    def run_test(self):

        # Start mininode connection
        default_node = DefaultNode()
        self.node = default_node
        kwargs = {}
        args = {}
        kwargs['dstport'] = 32323
        kwargs['dstaddr'] = '127.0.0.1'
        default_node.peer_connect(*args, **kwargs)
        network_thread_start()
        default_node.wait_for_status()

        # Start rpc connection
        self.rpc_client = RpcClient(get_simple_rpc_proxy(
            "http://127.0.0.1:12537"))
        node_id = self.rpc_client.get_node_id()
        self.log.info("get nodeid %s", eth_utils.encode_hex(node_id))

        block_gen_thread = BlockGenThread([self.rpc_client.node], self.log, num_txs = 100, interval_fixed=0.2)
        block_gen_thread.start()
        genesis_key = default_config["GENESIS_PRI_KEY"]
        balance_map = {genesis_key: default_config["TOTAL_COIN"]}
        self.log.info("Initial State: (sk:%d, addr:%s, balance:%d)", bytes_to_int(genesis_key),
                      eth_utils.encode_hex(priv_to_addr(genesis_key)), balance_map[genesis_key])
        nonce_map = {genesis_key: 0}
        '''Test Random Transactions'''
        all_txs = []
        tx_n = 10000
        gas_price = 1
        self.log.info("start to generate %d transactions with about %d seconds", tx_n, tx_n/10/2)
        for i in range(tx_n):
            if i % 1000 == 0:
                self.log.info("generated %d tx", i)
            sender_key = random.choice(list(balance_map))
            nonce = nonce_map[sender_key]
            if random.random() < 0.1 and balance_map[sender_key] > 21000 * 4 * tx_n:
                value = int(balance_map[sender_key] * 0.5)
                receiver_sk, _ = ec_random_keys()
                nonce_map[receiver_sk] = 0
                balance_map[receiver_sk] = value
            else:
                value = 1
                receiver_sk = random.choice(list(balance_map))
                balance_map[receiver_sk] += value
            # not enough transaction fee (gas_price * gas_limit) should not happen for now
            assert balance_map[sender_key] >= value + gas_price * 21000
            tx = create_transaction(pri_key=sender_key, receiver=priv_to_addr(receiver_sk), value=value, nonce=nonce,
                                    gas_price=gas_price)
            all_txs.append(tx)
            nonce_map[sender_key] = nonce + 1
            balance_map[sender_key] -= value + gas_price * 21000
        i = 0
        for tx in all_txs:
            i += 1
            if i % 1000 == 0:
                self.log.info("Sent %d tx", i)
            self.node.send_protocol_msg(Transactions(transactions=[tx]))
        for k in balance_map:
            wait_until(lambda: self.check_account(k, balance_map))
        block_gen_thread.stop()
        block_gen_thread.join()
        self.log.info("Pass")
        while True:
            pass

    def send_msg(self, msg):
        self.node.send_protocol_msg(msg)

    def check_account(self, k, balance_map):
        addr = eth_utils.encode_hex(priv_to_addr(k))
        try:
            balance = self.rpc_client.get_balance(addr)
        except Exception as e:
            self.log.info("Fail to get balance, error=%s", str(e))
            return False
        if balance == balance_map[k]:
            return True
        else:
            self.log.info("Remote balance:%d, local balance:%d", balance, balance_map[k])
            time.sleep(1)
            return False
Exemplo n.º 14
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)
Exemplo n.º 15
0
    def run_test(self):
        start_p2p_connection(self.nodes)
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        client = RpcClient(self.nodes[0])

        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 = client.get_balance(user1_addr_hex)
        assert_equal(user1_balance, value)
        user2_balance_before_contract_construction = client.get_balance(
            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 = client.get_balance(
            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 = client.get_balance(user1_addr_hex)
        assert_greater_than_or_equal(user1_balance,
                                     899999999999999999999999950000000)
        user2_balance_after_deposit = client.get_balance(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 = client.get_balance(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 = client.get_balance(user1_addr_hex)
        assert_greater_than_or_equal(user1_balance,
                                     899999999999999999999999950000000)
        contract_balance = client.get_balance(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 = client.get_balance(
            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()
    def run_test(self):
        file_dir = os.path.dirname(os.path.realpath(__file__))
        file_path = os.path.join(file_dir, "..", "internal_contract", "metadata", "Staking.json")
        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")
Exemplo n.º 17
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].txpool_txWithPoolInfo(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].txpool_txWithPoolInfo(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")
Exemplo n.º 18
0
class StorageMaintenanceTest(ConfluxTestFramework):
    def set_test_params(self):
        self.num_nodes = 1
        self.setup_clean_chain = True
        self.mining_author = "0x10000000000000000000000000000000000000aa"
        self.conf_parameters = {
            "mining_author": "\"10000000000000000000000000000000000000aa\"",
            "mining_type": "'disable'"
        }
        self.gasPrice = 1

    def setup_network(self):
        self.log.info("setup nodes ...")
        self.setup_nodes()

    def run_test(self):
        self.rpc = RpcClient(self.nodes[0])
        priv_key = default_config["GENESIS_PRI_KEY"]
        sender = eth_utils.encode_hex(priv_to_addr(priv_key))
        # 7000000000000000000 plus genesis collateral_for_storage for PoS genesis accounts.
        block_reward = 7000000000118911719

        # deploy storage test contract
        bytecode_file = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), CONTRACT_PATH)
        assert (os.path.isfile(bytecode_file))
        bytecode = open(bytecode_file).read()

        # 1. Produce an empty block
        self.rpc.generate_block()

        # 2. Deploy a contract: this will create 6 blocks and the first block contains 'create contract' transaction,
        # the other 5 blocks are empty.
        receipt, _ = self.deploy_contract(sender, priv_key, bytecode)

        # 3. Produce 10 empty blocks, and the miner's reward for the first block will be updated to world-state
        for _ in range(10):
            self.rpc.generate_block()
        balance = self.rpc.get_balance(self.mining_author)
        count = self.rpc.get_block_count()
        expected = block_reward
        self.log.info("block count: %d, balance: %d, expected: %d", count,
                      balance, expected)
        assert_equal(balance, expected)

        # 4. Produce 1 empty block, and the miner will receive reward for the second block. This block reward should
        # contains transaction fee.
        self.rpc.generate_blocks(1)
        balance = self.rpc.get_balance(self.mining_author)
        count = self.nodes[0].getblockcount()
        transaction_fee = parse_as_int(receipt['gasFee'])
        expected += block_reward + transaction_fee
        self.log.info(
            "block count: %d, balance: %d, expected: %d, transaction_fee: %d",
            count, balance, expected, transaction_fee)
        assert_equal(balance, expected)

        # TODO(lpl): Temp fix storage collateral precision issue.
        expected += 1
        # 5. Produce 1 empty block, and the miner will receive reward for the third empty block. This block reward
        # should contains storage maintenance fee.
        self.rpc.generate_blocks(1)
        balance = self.rpc.get_balance(self.mining_author)
        count = self.nodes[0].getblockcount()
        collateral_for_storage = self.rpc.get_collateral_for_storage(sender)
        storage_fee = collateral_for_storage * 4 // 100 // 63072000
        expected += block_reward + storage_fee
        self.log.info(
            "block count: %d, balance: %d, expected: %d, collateral_for_storage: %d, storage_fee: %d",
            count, balance, expected, collateral_for_storage, storage_fee)
        assert_equal(balance, expected)

        expected += 1
        # 6. Produce 1 empty block, and the miner will receive reward for the forth empty block. This block reward
        # should contains storage maintenance fee.
        self.rpc.generate_blocks(1)
        balance = self.rpc.get_balance(self.mining_author)
        count = self.nodes[0].getblockcount()
        collateral_for_storage = self.rpc.get_collateral_for_storage(sender)
        storage_fee = collateral_for_storage * 4 // 100 // 63072000
        expected += storage_fee + block_reward
        self.log.info(
            "block count: %d, balance: %d, expected: %d, collateral_for_storage: %d, storage_fee: %d",
            count, balance, expected, collateral_for_storage, storage_fee)

        assert_equal(balance, expected)

    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,
                                      nonce=None,
                                      gas_price=self.gasPrice,
                                      storage_limit=20000)
        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
Exemplo n.º 19
0
    def run_test(self):
        # Pos contract enabled, stake and register in the first hard-fork phase.
        client = RpcClient(self.nodes[self.num_nodes - 1])
        client.generate_empty_blocks(300)
        sync_blocks(self.nodes)
        for node in self.nodes[:-1]:
            client = RpcClient(node)
            pos_identifier, _ = client.wait_for_pos_register()
            sync_blocks(self.nodes)
        client = RpcClient(self.nodes[self.num_nodes - 1])

        # generate blocks until we are after pos initialization and before pos start.
        best_epoch = client.epoch_number()
        client.generate_empty_blocks(600 - best_epoch)
        sync_blocks(self.nodes)

        voting_power_map = {}
        pub_keys_map = {}
        logs = client.get_logs(filter=Filter(from_epoch="earliest", to_epoch="latest_state", address=["0x0888000000000000000000000000000000000005"]))
        for log in logs:
            pos_identifier = log["topics"][1]
            if log["topics"][0] == REGISTER_TOPIC:
                bls_pub_key, vrf_pub_key = eth_abi.decode_abi(["bytes", "bytes"], decode_hex(log["data"]))
                pub_keys_map[pos_identifier] = (encode_hex_0x(bls_pub_key), encode_hex_0x(vrf_pub_key))
            elif log["topics"][0] == INCREASE_STAKE_TOPIC:
                assert pos_identifier in pub_keys_map
                voting_power_map[pos_identifier] = parse_as_int(log["data"])
        with open(os.path.join(self.options.tmpdir, "public_keys"), "w") as f:
            for pos_identifier in pub_keys_map.keys():
                f.write(",".join([pub_keys_map[pos_identifier][0][2:], pub_keys_map[pos_identifier][1][2:], str(voting_power_map[pos_identifier])]) + "\n")
        initialize_tg_config(self.options.tmpdir, len(self.nodes), len(self.nodes), DEFAULT_PY_TEST_CHAIN_ID, pkfile="public_keys")

        # generate blocks until pos start
        self.nodes[0].generate_empty_blocks(500)
        sync_blocks(self.nodes)
        pos_identifier, _ = client.wait_for_pos_register()
        client.generate_empty_blocks(400)
        sync_blocks(self.nodes)
        time.sleep(2)

        latest_pos_ref = self.latest_pos_ref()
        for i in range(55):
            print(i)
            if i == 10:
                self.stop_node(5, clean=True)
                self.start_node(5, phase_to_wait=None)
                self.nodes[5].wait_for_recovery(["NormalSyncPhase"], 30)
            if i == 12:
                self.maybe_restart_node(5, 1, 0)
            if i == 15:
                assert_equal(int(client.pos_get_account(pos_identifier)["status"]["availableVotes"], 0), 2000)
                client.pos_retire_self()
            if i == 30:
                self.maybe_restart_node(5, 1, 1)
            # Retire node 3 after 5 min.
            # Generate enough PoW block for PoS to progress
            self.nodes[0].generate_empty_blocks(60)
            # Leave some time for PoS to reach consensus
            time.sleep(3)
            self.nodes[0].generate_empty_blocks(1)
            new_pos_ref = self.latest_pos_ref()
            if i >= 10:
                assert_ne(latest_pos_ref, new_pos_ref)

        client.wait_for_unstake(client.node.pow_sk)
        assert client.get_balance(eth_utils.encode_hex(priv_to_addr(client.node.pow_sk))) > 10000 * 10**18
        assert_equal(int(client.pos_get_account(pos_identifier)["status"]["availableVotes"], 0), 0)
    def run_test(self):
        start_p2p_connection(self.nodes)
        block_gen_thread = BlockGenThread(self.nodes, self.log)
        block_gen_thread.start()
        client = RpcClient(self.nodes[0])

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

        reentrancy_config_addr = Web3.toChecksumAddress(
            "0888000000000000000000000000000000000003")
        file_dir = os.path.dirname(os.path.realpath(__file__))
        control_contract_file_path = os.path.join(file_dir, "..",
                                                  "internal_contract",
                                                  "metadata",
                                                  "ReentrancyConfig.json")
        control_contract_dict = json.loads(
            open(control_contract_file_path, "r").read())
        control_contract = get_contract_instance(
            contract_dict=control_contract_dict)

        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 = client.get_balance(user1_addr_hex)
        assert_equal(user1_balance, value)
        user2_balance_before_contract_construction = client.get_balance(
            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)
        buggy_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']

        if self.mode == NO_PROTECTION:
            self.log.info("Disabling anti-reentrancy")
            self.call_contract_function(
                contract=control_contract,
                name="allowReentrancyByAdmin",
                args=[Web3.toChecksumAddress(buggy_addr), True],
                sender_key=self.genesis_priv_key,
                contract_addr=reentrancy_config_addr,
                storage_limit=64,
                wait=True,
                check_status=True)
            self.call_contract_function(
                contract=control_contract,
                name="allowReentrancyByAdmin",
                args=[Web3.toChecksumAddress(exploit_addr), True],
                sender_key=user2,
                contract_addr=reentrancy_config_addr,
                storage_limit=64,
                wait=True,
                check_status=True)

        user2_balance_after_contract_construction = client.get_balance(
            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,
                                                  buggy_addr,
                                                  True,
                                                  True,
                                                  storage_limit=128)
        transaction = self.call_contract_function(
            self.exploit_contract,
            "deposit", [Web3.toChecksumAddress(buggy_addr)],
            user2,
            10**18,
            exploit_addr,
            True,
            True,
            storage_limit=128)

        user1_balance = client.get_balance(user1_addr_hex)
        assert_greater_than_or_equal(user1_balance,
                                     899999999999999999999999950000000)
        user2_balance_after_deposit = client.get_balance(user2_addr_hex)
        # User2 paid storage collateral `vulnerable_contract` in deposit call.
        user2_refund_upper_bound += 3 * 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 = client.get_balance(buggy_addr)
        assert_equal(contract_balance, 2 * 10**18)
        user2_balance_in_contract = RpcClient(self.nodes[0]).call(
            buggy_addr,
            self.buggy_contract.functions.balanceOf(
                Web3.toChecksumAddress(exploit_addr)).buildTransaction({
                    "from":
                    user2_addr_hex,
                    "to":
                    buggy_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 = client.get_balance(user1_addr_hex)
        assert_greater_than_or_equal(user1_balance,
                                     899999999999999999999999950000000)
        contract_balance = client.get_balance(buggy_addr)
        attack_benefit = 0
        if self.mode == OLD_MODE:
            # In the old mode, the second withdraw_balance will fail.
            rest_balance, attacker_rest = 1 * CFX, 0
        elif self.mode == NEW_MODE:
            # In the new mode, the protection is closed.
            rest_balance, attacker_rest = 0, 0
            attack_benefit = 1 * CFX
        else:
            raise Exception("Unrecognized reentrancy test mode")
        assert_equal(contract_balance, rest_balance)

        user2_balance_in_contract = RpcClient(self.nodes[0]).call(
            buggy_addr,
            self.buggy_contract.functions.balanceOf(
                Web3.toChecksumAddress(exploit_addr)).buildTransaction({
                    "from":
                    user2_addr_hex,
                    "to":
                    buggy_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), attacker_rest)
        self.log.debug("user2 balance in contract %s" %
                       user2_balance_in_contract)
        user2_balance_after_contract_destruct = client.get_balance(
            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_deposit + user2_refund_upper_bound + 10**18 -
            attacker_rest + attack_benefit,
            user2_balance_after_contract_destruct,
        )

        block_gen_thread.stop()
        block_gen_thread.join()
Exemplo n.º 21
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 = 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 - 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")
Exemplo n.º 22
0
    def run_test(self):
        sponsor_whitelist_contract_addr = Web3.toChecksumAddress(
            "0888000000000000000000000000000000000001")
        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")
Exemplo n.º 23
0
    def run_test(self):
        genesis_key = default_config["GENESIS_PRI_KEY"]
        receiver_sk, _ = ec_random_keys()
        receiver_addr = priv_to_addr(receiver_sk)
        client = RpcClient(self.nodes[0])

        value = 100000000
        tx = create_transaction(pri_key=genesis_key,
                                receiver=receiver_addr,
                                value=value,
                                nonce=0,
                                gas_price=1,
                                epoch_height=0)
        client.send_tx(tx)
        block_gen_thread = BlockGenThread(self.nodes,
                                          self.log,
                                          interval_base=0.1)
        block_gen_thread.start()
        self.log.info(
            "Wait for the first transaction to go through with epoch_height = 0..."
        )
        wait_until(lambda: client.get_balance(
            eth_utils.encode_hex(receiver_addr)) == value)
        self.log.info("Wait for generating more than 50 epochs")
        wait_until(lambda: parse_as_int(
            client.block_by_hash(client.best_block_hash())['height']) > 50)
        block_gen_thread.stop()
        self.log.info("Now block count:%d", self.nodes[0].getblockcount())

        tx = create_transaction(pri_key=genesis_key,
                                receiver=receiver_addr,
                                value=value,
                                nonce=1,
                                gas_price=1,
                                epoch_height=0)
        try:
            client.send_tx(tx)
            self.log.info("Bad transaction not rejected!")
            assert (False)
        except ReceivedErrorResponseError:
            self.log.info("Bad transaction rejected.")
        except:
            self.log.info("Unexpected error!")
            assert (False)
        assert (client.get_balance(
            eth_utils.encode_hex(receiver_addr)) == value)

        epoch_height = parse_as_int(
            client.block_by_hash(client.best_block_hash())['height'])
        tx = create_transaction(pri_key=genesis_key,
                                receiver=receiver_addr,
                                value=value,
                                nonce=1,
                                gas_price=1,
                                epoch_height=epoch_height)
        client.send_tx(tx)
        block_gen_thread = BlockGenThread(self.nodes,
                                          self.log,
                                          interval_base=0.1)
        block_gen_thread.start()
        self.log.info(
            "Wait for the first transaction to go through with epoch_height = "
            + str(epoch_height) + "...")
        wait_until(lambda: client.get_balance(
            eth_utils.encode_hex(receiver_addr)) == 2 * value)
        block_gen_thread.stop()
        self.log.info("Now block count:%d", self.nodes[0].getblockcount())
        self.log.info("Pass!")