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")
    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")
Exemple #3
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")
Exemple #4
0
    def run_test(self):
        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}
        block_gen_thread = BlockGenThread(self.nodes, self.log, interval_base=0.2)
        block_gen_thread.start()

        '''Check if transaction from uncommitted new address can be accepted'''
        tx_n = 5
        new_keys = set()
        gas_price = 1
        for i in range(tx_n):
            sender_key = genesis_key
            receiver_sk, _ = ec_random_keys()
            new_keys.add(receiver_sk)
            value = int((balance_map[sender_key] - ((tx_n - i) * 21000 * gas_price)) * random.random())
            balance_map[receiver_sk] = value
            nonce = nonce_map[sender_key]
            receiver_addr = priv_to_addr(receiver_sk)
            tx = create_transaction(pri_key=sender_key, receiver=receiver_addr, value=value, nonce=nonce,
                                    gas_price=gas_price)
            r = random.randint(0, self.num_nodes - 1)
            r = 0
            self.nodes[r].p2p.send_protocol_msg(Transactions(transactions=[tx]))
            nonce_map[sender_key] = nonce + 1
            balance_map[sender_key] -= value + gas_price * 21000
            self.log.debug("New tx %s: %s send value %d to %s, sender balance:%d, receiver balance:%d", 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:], balance_map[sender_key], balance_map[receiver_sk])
            self.log.debug("Send Transaction %s to node %d", encode_hex(tx.hash), r)
        for k in balance_map:
            self.log.info("Check account sk:%s addr:%s", bytes_to_int(k), eth_utils.encode_hex(priv_to_addr(k)))
            wait_until(lambda: self.check_account(k, balance_map))
        self.log.info("Pass 1")

        '''Test Random Transactions'''
        wait_for_account_stable()
        for key in new_keys:
            nonce_map[key] = wait_for_initial_nonce_for_privkey(self.nodes[0], key)
        all_txs = []
        tx_n = 1000
        self.log.info("start to generate %d transactions with about %d seconds", tx_n, tx_n/100/2)
        for i in range(tx_n):
            sender_key = random.choice(list(balance_map))
            nonce = nonce_map[sender_key]
            data = b''
            rand_n = random.random()
            gas = 21000
            storage_limit = 0
            if rand_n > 0.9 and balance_map[sender_key] > 21000 * 4 * tx_n:
                value = 0
                receiver = b''
                data = bytes([96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 16, 87, 96, 0, 128, 253, 91, 80, 96, 5, 96, 0, 129, 144, 85, 80, 96, 230, 128, 97, 0, 39, 96, 0, 57, 96, 0, 243, 254, 96, 128, 96, 64, 82, 96, 4, 54, 16, 96, 67, 87, 96, 0, 53, 124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 4, 128, 99, 96, 254, 71, 177, 20, 96, 72, 87, 128, 99, 109, 76, 230, 60, 20, 96, 127, 87, 91, 96, 0, 128, 253, 91, 52, 128, 21, 96, 83, 87, 96, 0, 128, 253, 91, 80, 96, 125, 96, 4, 128, 54, 3, 96, 32, 129, 16, 21, 96, 104, 87, 96, 0, 128, 253, 91, 129, 1, 144, 128, 128, 53, 144, 96, 32, 1, 144, 146, 145, 144, 80, 80, 80, 96, 167, 86, 91, 0, 91, 52, 128, 21, 96, 138, 87, 96, 0, 128, 253, 91, 80, 96, 145, 96, 177, 86, 91, 96, 64, 81, 128, 130, 129, 82, 96, 32, 1, 145, 80, 80, 96, 64, 81, 128, 145, 3, 144, 243, 91, 128, 96, 0, 129, 144, 85, 80, 80, 86, 91, 96, 0, 128, 84, 144, 80, 144, 86, 254, 161, 101, 98, 122, 122, 114, 48, 88, 32, 181, 24, 13, 149, 253, 195, 129, 48, 40, 237, 71, 246, 44, 124, 223, 112, 139, 118, 192, 219, 9, 64, 67, 245, 51, 180, 42, 67, 13, 49, 62, 21, 0, 41])
                gas = CONTRACT_DEFAULT_GAS
                is_payment = False
                storage_limit = 200000
            else:
                value = 1
                receiver_sk = random.choice(list(balance_map))
                receiver = priv_to_addr(receiver_sk)
                balance_map[receiver_sk] += value
                is_payment = True
            # 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=receiver, value=value, nonce=nonce,
                                    gas_price=gas_price, data=data, gas=gas, storage_limit=storage_limit)
            r = random.randint(0, self.num_nodes - 1)
            r = 0
            self.nodes[r].p2p.send_protocol_msg(Transactions(transactions=[tx]))
            all_txs.append(tx)
            nonce_map[sender_key] = nonce + 1
            if is_payment:
                balance_map[sender_key] -= value + gas_price * gas
            else:
                balance_map[sender_key] -= value + gas_price * charged_of_huge_gas(gas)
            self.log.debug("Send Transaction %s to node %d", encode_hex(tx.hash), r)
            time.sleep(random.random() / 100)
        for k in balance_map:
            self.log.info("Account %s with balance:%s", bytes_to_int(k), balance_map[k])
        for tx in all_txs:
            self.log.debug("Wait for tx to confirm %s", tx.hash_hex())
            for i in range(3):
                try:
                    retry = True
                    while retry:
                        try:
                            wait_until(lambda: checktx(self.nodes[0], tx.hash_hex()), timeout=120)
                            retry = False
                        except CannotSendRequest:
                            time.sleep(0.01)
                    break
                except AssertionError as _:
                    self.nodes[0].p2p.send_protocol_msg(Transactions(transactions=[tx]))
                if i == 2:
                    raise AssertionError("Tx {} not confirmed after 30 seconds".format(tx.hash_hex()))

        for k in balance_map:
            self.log.info("Check account sk:%s addr:%s", bytes_to_int(k), eth_utils.encode_hex(priv_to_addr(k)))
            wait_until(lambda: self.check_account(k, balance_map))
        block_gen_thread.stop()
        block_gen_thread.join()
        sync_blocks(self.nodes)
        self.log.info("Pass")
    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")
Exemple #6
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")
Exemple #7
0
    def testHTLCContract(self):
        CONTRACT_PATH = "contracts/htlc_bytecode_new.dat"
        logs = self.rpc.get_logs(self.filter)
        l = len(logs)

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

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

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

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

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

        # interact with withdraw()
        data = contract.functions.withdraw(
            contract_id, self.solution).buildTransaction(self.tx_conf)["data"]
        result = self.call_contract(self.sender,
                                    self.priv_key,
                                    contractAddr,
                                    data,
                                    storage_limit=128)
        assert_equal(self.rpc.get_balance(contractAddr), 0)
        c2 = self.rpc.get_collateral_for_storage(self.sender)
        assert_equal(c2 - c1, 125000000000000000)
        assert_equal(self.rpc.get_balance(self.sender),
                     b0 - charged_of_huge_gas(gas) * 2 - (c2 - c0))
        logs = self.rpc.get_logs(self.filter)
        assert_equal(len(logs), l + 3)

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