예제 #1
0
    def test_same_amount_cycle(self):
        """
        质押相等的金额,按照时间先早排序
        """
        self.auto = AutoDeployPlaton()
        self.auto.start_all_node(self.node_yml_path)
        log.info("转账每个钱包")
        for to_account in self.account_list:
            self.transaction(self.w3_list[0],
                             self.address,
                             to_address=to_account)

        log.info("质押节点4金额200eth")
        self.ppos_noconsensus_4.createStaking(0, self.account_list[3],
                                              self.nodeid_list2[3],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount + 200,
                                              self.programVersion)
        log.info("质押节点5金额200eth")
        self.ppos_noconsensus_5.createStaking(0, self.account_list[4],
                                              self.nodeid_list2[4],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount + 200,
                                              self.programVersion)
        log.info("进入到下个结算周期")
        get_block_number(self.w3_list[0])

        node_list = getVerifierList()
        log.info(node_list)
        log.info(self.nodeid_list2[3])
        log.info(self.nodeid_list2[4])
        assert node_list[0] == self.nodeid_list2[3]
        assert node_list[1] == self.nodeid_list2[4]
예제 #2
0
 def test_init_token(self):
     self.auto = AutoDeployPlaton(cbft=self.cbft_json_path)
     self.auto.start_all_node(self.node_yml_path)
     proportion = {
         'FOUNDATION': 0.001,
         'DEVELOPERS': 0.001,
         'INCENTIVEPOOL': 0.001,
         'RESERVED': 0.001
     }
     FOUNDATION = self.platon_ppos.eth.getBalance(conf.FOUNDATIONADDRESS)
     DEVELOPERS = self.platon_ppos.eth.getBalance(conf.DEVELOPERSADDRESS)
     INCENTIVEPOOL = self.platon_ppos.eth.getBalance(
         conf.INCENTIVEPOOLADDRESS)
     RESERVED = self.platon_ppos.eth.getBalance(conf.RESERVEDADDRESS)
     FOUNDATIONLOCKUP = self.platon_dpos1.eth.getBalance(
         conf.FOUNDATIONLOCKUPADDRESS)
     token_init_total = conf.TOKENTOTAL
     assert (token_init_total *
             proportion['FOUNDATION']) == (FOUNDATION + FOUNDATIONLOCKUP)
     assert (token_init_total * proportion['DEVELOPERS']) == DEVELOPERS
     assert (token_init_total *
             proportion['INCENTIVEPOOL']) == INCENTIVEPOOL
     assert (token_init_total * proportion['RESERVED']) == RESERVED
     assert token_init_total == (FOUNDATION + FOUNDATIONLOCKUP +
                                 DEVELOPERS + INCENTIVEPOOL + RESERVED)
예제 #3
0
 def test_block_out_of_each_node_window(self):
     """
     用例id:73
     测试 N 个节点每个窗口期都在出块
     """
     log.info("更新cbft文件")
     self.get_cbft_json_data(period=1, duration=10)
     auto = AutoDeployPlaton(cbft=self.cbft_path)
     auto.start_all_node(self.node_yml)
     log.info("跟所有节点建立连接")
     w3_list = [connect_web3(url) for url in self.url_list]
     w3 = w3_list[0]
     start_block = w3.eth.blockNumber
     time.sleep(self.n * 10 + 5)
     block_number = w3.eth.blockNumber
     if block_number > 0:
         log.info("正在出块,块高:{}".format(block_number))
     node_id_dict = {}
     log.info("获取1至{}块的nodeID".format(block_number))
     for block in range(start_block, block_number + 1):
         node_id = get_pub_key(self.url_list[0], block)
         if node_id not in node_id_dict.keys():
             node_id_dict[node_id] = 1
         else:
             node_id_dict[node_id] += 1
     log.info("nodeID对应的出块数{}".format(node_id_dict))
     assert self.n == len(node_id_dict), "出块节点数少于共识节点数"
     for k, v in node_id_dict.items():
         assert 0 <= v <= 20, "节点{}出块周期约为10个块,实际为{}".format(k, v)
예제 #4
0
 def test_block_time_period(self, period, duration):
     '''
     用例id 1,2,3,4,5
     测试period的不同值,观察查看时间
     根据5种场景,分别出块时间约为1,3,5,10,1s
     '''
     log.info("更新cbft.json")
     self.get_cbft_json_data(period, duration)
     auto = AutoDeployPlaton(cbft=self.cbft_path)
     auto.start_all_node(self.node_yml)
     time.sleep(duration + 5)
     log.info("跟所有节点建立连接")
     w3_list = [connect_web3(url) for url in self.url_list]
     w3 = w3_list[0]
     block_number = w3.eth.blockNumber
     assert block_number > 1, "没有正常出块"
     log.info(block_number)
     start_time = w3.eth.getBlock(1).get("timestamp")
     end_time = w3.eth.getBlock(block_number).get("timestamp")
     use_time = end_time - start_time
     average_time = int(use_time / (block_number - 1))
     log.info("平均出块时间{}".format(average_time))
     if period == 0:
         period = 1
     deviation = int(period * 1000 * 0.5)
     assert period * 1000 - deviation < average_time < period * \
         1000 + deviation, "出块间隔过大或过小"
예제 #5
0
 def setup_class(self):
     self.auto = AutoDeployPlaton()
     self.auto.start_all_node(self.node_yml_path)
     self.genesis_dict = LoadFile(self.genesis_path).get_data()
     self.chainid = int(self.genesis_dict["config"]["chainId"])
     self.ppos_link = Ppos(self.rpc_list[0], self.address, self.chainid)
     self.w3_list = [connect_web3(url) for url in self.rpc_list]
     """用新的钱包地址和未质押过的节点id封装对象"""
     self.ppos_noconsensus_1 = Ppos(self.rpc_list[0],
                                    self.account_list[0],
                                    self.chainid,
                                    privatekey=self.privatekey_list[0])
     self.ppos_noconsensus_2 = Ppos(self.rpc_list[0],
                                    self.account_list[1],
                                    self.chainid,
                                    privatekey=self.privatekey_list[1])
     self.ppos_noconsensus_3 = Ppos(self.rpc_list[0],
                                    self.account_list[2],
                                    self.chainid,
                                    privatekey=self.privatekey_list[2])
     self.ppos_noconsensus_4 = Ppos(self.rpc_list[0],
                                    self.account_list[3],
                                    self.chainid,
                                    privatekey=self.privatekey_list[3])
     self.ppos_noconsensus_5 = Ppos(self.rpc_list[0],
                                    self.account_list[4],
                                    self.chainid,
                                    privatekey=self.privatekey_list[4])
     self.ppos_noconsensus_6 = Ppos(self.rpc_list[0],
                                    self.account_list[5],
                                    self.chainid,
                                    privatekey=self.privatekey_list[5])
     self.eth = Eth(self.w3_list[0])
예제 #6
0
    def test_ranking(self):
        """
        测试根据金额排名,从高到低排名
        """
        self.auto = AutoDeployPlaton()
        self.auto.start_all_node(self.node_yml_path)
        log.info("转账每个钱包")
        for to_account in self.account_list:
            self.transaction(self.w3_list[0],
                             self.address,
                             to_address=to_account)

        self.ppos_noconsensus_1.createStaking(0, self.account_list[0],
                                              self.nodeid_list2[0],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount + 50,
                                              self.programVersion)
        self.ppos_noconsensus_2.createStaking(0, self.account_list[1],
                                              self.nodeid_list2[1],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount + 40,
                                              self.programVersion)
        self.ppos_noconsensus_3.createStaking(0, self.account_list[2],
                                              self.nodeid_list2[2],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount + 30,
                                              self.programVersion)
        self.ppos_noconsensus_4.createStaking(0, self.account_list[3],
                                              self.nodeid_list2[3],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount + 20,
                                              self.programVersion)
        self.ppos_noconsensus_5.createStaking(0, self.account_list[4],
                                              self.nodeid_list2[4],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount + 10,
                                              self.programVersion)
        self.ppos_noconsensus_6.createStaking(0, self.account_list[5],
                                              self.nodeid_list2[5],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount, self.programVersion)
        log.info("进入下个周期")
        get_block_number(self.w3_list[0])
        node_list = getVerifierList()
        log.info(node_list)
        """根据config配置验证人数"""
        # assert self.nodeid_list2[5] not in node_list
        assert node_list[0] == self.nodeid_list2[0]
        assert node_list[1] == self.nodeid_list2[1]
        assert node_list[2] == self.nodeid_list2[2]
        assert node_list[3] == self.nodeid_list2[3]
        assert node_list[4] == self.nodeid_list2[4]
        assert node_list[5] == self.nodeid_list2[-1]
예제 #7
0
def setup(node_yml=None):
    if node_yml:
        conf.NODE_YML = abspath(node_yml)
    auto = AutoDeployPlaton(is_metrics=True)
    # auto.check_node_yml(conf.NODE_YML)
    # auto.booms(conf.NODE_YML)
    # auto.deploy_default_yml(conf.NODE_YML)
    auto.kill_of_yaml(conf.NODE_YML)
 def start_init(self):
     #修改config参数
     CommonMethod.update_config(self,'EconomicModel','Common','ExpectedMinutes',3)
     CommonMethod.update_config(self,'EconomicModel','Common','PerRoundBlocks',10)
     CommonMethod.update_config(self,'EconomicModel','Common','ValidatorCount',5)
     CommonMethod.update_config(self,'EconomicModel','Staking','ElectionDistance',20)
     CommonMethod.update_config(self,'EconomicModel','Staking','StakeThreshold',1000)
     #启动节点
     self.auto = AutoDeployPlaton ()
     self.auto.start_all_node (self.node_yml_path)
예제 #9
0
 def test_build_one_node_privatechain(self):
     '''
     部署单节点私链
     '''
     auto = AutoDeployPlaton(genesis=conf.GENESIS_TEMPLATE2)
     auto.start_of_list(self.nocollusion_list[0:1],
                        genesis_path=conf.GENESIS_TMP_OTHER)
     time.sleep(2)
     w3 = connect_web3(self.one_collusion_url)
     start_block = w3.eth.blockNumber
     log.info("start block number:{}".format(start_block))
     time.sleep(10)
     end_block = w3.eth.blockNumber
     log.info("end block number:{}".format(end_block))
     assert start_block < end_block, "区块高度没有增长"
예제 #10
0
 def test_punishment_income(self):
     '''
     验证低出块率验证节点的处罚金自动转账到激励池
     :return:
     '''
     #随机获取其中一个正在出块的节点信息
     node_info = get_node_list(conf.TWENTY_FIVENODE_YML)
     node_info_length = len(node_info) - 1
     index = random.randint(0, node_info_length)
     node_data = node_info[0][index]
     print(node_data)
     platon_ppos = Ppos('http://10.10.8.157:6789',
                        self.address,
                        chainid=102,
                        privatekey=conf.PRIVATE_KEY)
     # platon_ppos = self.ppos_link ()
     incentive_pool_balance_befor = platon_ppos.eth.getBalance(
         conf.INCENTIVEPOOLADDRESS)
     log.info('处罚之前激励池查询余额:{}'.format(incentive_pool_balance_befor))
     #停止其中一个正在出块的节点信息
     try:
         self.auto = AutoDeployPlaton(cbft=self.cbft_json_path)
         self.auto.kill(node_data)
         platon_ppos = self.ppos_link(node_data['url'])
         if not platon_ppos.web3.isConnected():
             platon_ppos = self.ppos_link()
             current_block = platon_ppos.eth.blockNumber()
             waiting_time = 250 - (current_block % 250)
             time.sleep(waiting_time + 1)
             incentive_pool_balance_after = platon_ppos.eth.getBalance(
                 conf.INCENTIVEPOOLADDRESS)
             log.info('处罚之后激励池查询余额:{}'.format(incentive_pool_balance_after))
             punishment_CandidateInfo = platon_ppos.getCandidateInfo(
                 node_data['id'])
             if punishment_CandidateInfo['Status'] == 'True':
                 punishment_amount = punishment_CandidateInfo['Data'][
                     'Shares'] * (20 / 100)
                 assert incentive_pool_balance_after == incentive_pool_balance_befor + punishment_amount
             else:
                 log.info("查询处罚节点:{}质押信息失败".format(node_data['host']))
         else:
             log.info("当前质押节点:{}链接正常".format(node_data['host']))
     except:
         status = 1
         assert status == 0, '停止节点:{}失败'.format(node_data['host'])
예제 #11
0
def restart_node(node_list, platon_dpos):
    auto = AutoDeployPlaton()
    del node_list[0]
    del node_list[9]
    del node_list[0]
    while True:
        time.sleep(random.randrange(100, 5000))
        verfier_info_list = platon_dpos.GetVerifiersList()
        num = len(verfier_info_list)
        if num <= 1:
            f = 1
        else:
            f = int((num - 1) / 3) + 1
        stop_node_list = random.sample(node_list, random.randrange(1, f + 1))
        q.put(1)
        log.info("重启节点:{}".format(stop_node_list))
        auto.restart_list(stop_node_list)
        q.get()
예제 #12
0
 def test_syncmode(self):
     """
     同步
     :return:
     """
     auto = AutoDeployPlaton(syncmode="fast")
     auto.start_of_list(self.nocollusion_list[0:1],
                        genesis_file=self.genesis_file)
     time.sleep(2)
     w3 = connect_web3(self.one_collusion_url)
     w3.admin.addPeer(self.enode_list[0])
     time.sleep(5)
     collusion_w3 = self.w3_list[0]
     if collusion_w3.eth.blockNumber < 250:
         log.info("sleep,非共识节点需要229个块之后才会开始同步")
         time.sleep(250 - collusion_w3.eth.blockNumber)
     assert w3.net.peerCount > 0, "加入链失败"
     assert w3.eth.blockNumber >= 200, "区块同步失败,当前块高{}".format(
         w3.eth.blockNumber)
예제 #13
0
    def test_punishment_income(self):
        '''
        验证低出块率验证节点的处罚金自动转账到激励池
        :return:
        '''
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        incentive_pool_balance_befor = platon_ppos.eth.getBalance(
            conf.INCENTIVEPOOLADDRESS)
        log.info('处罚之前激励池查询余额:{}'.format(incentive_pool_balance_befor))

        #获取节点内置质押节点信息
        nodeId = CommonMethod.read_out_nodeId(self, 'collusion')
        log.info("节点ID:{}".format(nodeId))
        con_node, no_node = get_node_list(self.node_yml_path)
        nodes = con_node + no_node
        for node in nodes:
            if nodeId in node.values():
                node_data = node

        #获取节点质押金额
        punishment_CandidateInfo = platon_ppos.getCandidateInfo(nodeId)
        assert punishment_CandidateInfo['Status'] == True, "查询锁仓信息失败"
        pledge_amount1 = punishment_CandidateInfo['Data']['Released']
        log.info("质押节点质押金:{}".format(pledge_amount1))

        # 停止其中一个正在出块的节点信息
        self.auto = AutoDeployPlaton()
        self.auto.kill(node_data)
        platon_ppos1 = connect_web3(node_data['url'])
        assert not platon_ppos1.isConnected(), "节点:{} 连接异常".format(
            node_data['host'])
        CommonMethod.get_next_settlement_interval(self)
        punishment_CandidateInfo = platon_ppos.getCandidateInfo(nodeId)
        pledge_amount3 = punishment_CandidateInfo['Data']['Released']
        log.info("节点低出块率后节点质押金:{}".format(pledge_amount3))
        incentive_pool_balance_after = platon_ppos.eth.getBalance(
            conf.INCENTIVEPOOLADDRESS)
        log.info('处罚之后激励池查询余额:{}'.format(incentive_pool_balance_after))
        assert incentive_pool_balance_after == incentive_pool_balance_befor + (
            pledge_amount1 - pledge_amount3)
예제 #14
0
 def setup_class(self):
     self.auto = AutoDeployPlaton(cbft=self.cbft_json_path)
     self.auto.start_all_node(self.node_yml_path)
     self.platon_dpos1 = PlatonDpos(
         self.rpc_list[0], self.address, self.pwd, abi=self.abi)
     self.w3_list = [connect_web3(url) for url in self.rpc_list]
     self.new_address = Web3.toChecksumAddress(
         self.platon_dpos1.web3.personal.newAccount(self.pwd))
     self.send_data = {
         "to": self.new_address,
         "from": self.address,
         "gas": '9000',
         "gasPrice": '1000000000',
         "value": self.w3_list[0].toWei(100000, 'ether'),
     }
     tx_hash = self.platon_dpos1.eth.sendTransaction(self.send_data)
     self.platon_dpos1.eth.waitForTransactionReceipt(tx_hash)
     self.platon_dpos2 = PlatonDpos(
         self.rpc_list[0], self.new_address, self.pwd, abi=self.abi)
     self.fee = int(1000).to_bytes(4, 'big')
     self.extra = "Test"
예제 #15
0
파일: run.py 프로젝트: qiusese/PlatON-Tests
def setup(node_yml=None, collusion_number=0):
    if node_yml:
        conf.NODE_YML = abspath(node_yml)
    auto = AutoDeployPlaton()
    auto.check_node_yml(conf.NODE_YML)
    conf.NODE_NUMBER = collusion_number
    auto.start_all_node(conf.NODE_YML)
예제 #16
0
def stop_node(node_list, platon_dpos):
    auto = AutoDeployPlaton()
    del node_list[0]
    del node_list[9]
    del node_list[0]
    while True:
        time.sleep(random.randrange(100, 5000))
        verfier_info_list = platon_dpos.GetVerifiersList()
        num = len(verfier_info_list)
        if num <= 1:
            continue
        f = int((num - 1) / 3)
        if f < 2:
            continue
        stop_node_list = random.sample(node_list, random.randrange(1, f))
        q.put(1)
        log.info("关闭节点:{}".format(stop_node_list))
        number = platon_dpos.web3.eth.blockNumber
        sleep_time = get_sleep_time(number)
        auto.kill_of_list(stop_node_list)
        if sleep_time > 21:
            time.sleep(random.randrange(1, sleep_time - 20))
        log.info("恢复节点:{}".format(stop_node_list))
        auto.restart_list(stop_node_list)
        q.get()
예제 #17
0
 def test_testnet(self):
     """
     测试testnet连接
     :return:
     """
     if conf.IS_TEST_NET:
         auto = AutoDeployPlaton(net_type="testnet")
         auto.start_all_node(conf.TEST_NET_NODE,
                             is_need_init=False,
                             clean=True)
         collusion, nocollusion = get_node_list(conf.TEST_NET_NODE)
         time.sleep(10)
         block_list = []
         net_list = []
         for nodedict in collusion:
             url = nodedict["url"]
             w3 = connect_web3(url)
             block_list.append(w3.eth.blockNumber)
             net_list.append(w3.net.peerCount)
         log.info(block_list, net_list)
         assert min(block_list) > 0, "区块没有增长"
         for net in net_list:
             assert net >= len(collusion) - \
                 1, "共识节点连接节点数少于{}个".format(len(collusion) - 1)
         nocollusion_block_list = []
         nocollusion_net_list = []
         if max(block_list) < 250:
             time.sleep(250 - max(block_list) + 10)
         for nodedict in nocollusion:
             url = nodedict["url"]
             w3 = connect_web3(url)
             nocollusion_block_list.append(w3.eth.blockNumber)
             nocollusion_net_list.append(w3.net.peerCount)
         log.info(nocollusion_block_list, nocollusion_net_list)
         assert min(nocollusion_block_list) > 0, "区块没有增长"
         for net in nocollusion_net_list:
             assert net >= 1, "非共识节点没有连上测试网"
     else:
         pass
예제 #18
0
def monitor(node_yml):
    auto = AutoDeployPlaton()
    collusion, nocollusion = get_node_list(node_yml)
    node_list = collusion + nocollusion
    old_block = [0 * i for i in range(len(collusion))]
    t = 0
    while True:
        time.sleep(120)
        t += 120
        block_list = []
        url_list = []
        for node in node_list:
            try:
                w3 = connect_web3(node["url"])
                if not w3.isConnected():
                    raise Exception("有节点被关闭了")
                block = w3.eth.blockNumber
                block_list.append(block)
                url_list.append(node["url"])

            except:
                close_msg = "节点:{}:{}无法连接\n".format(node["host"], node["port"])
                log.warning(close_msg)
        msg = build_msg(url_list, block_list, old_block)
        if max(block_list) - min(block_list) >= 100:
            log.error("区块差距过大")
            auto.kill_of_yaml(node_yml)
            send_to_gap(block_list, msg, node_yml)
        if max(block_list) - min(old_block) == 0:
            log.error("不出块了")
            auto.kill_of_yaml(node_yml)
            send_to_block(msg, node_yml)
        if t >= 21600:
            t = 0
            send_email(EmailInfo, msg)
        old_block = block_list
예제 #19
0
def deploy(node_file):
    auto = AutoDeployPlaton()
    auto.deploy_default_yml(node_file)
예제 #20
0
class TestDposinit:
    address = conf.ADDRESS
    pwd = conf.PASSWORD
    abi = conf.DPOS_CONTRACT_ABI
    cbft_json_path = conf.CBFT2
    node_yml_path = conf.PPOS_NODE_TEST_YML
    file = conf.CASE_DICT
    privatekey = conf.PRIVATE_KEY
    base_gas_price = 60000000000000
    base_gas = 21000
    staking_gas = base_gas + 32000 + 6000 + 100000
    transfer_gasPrice = Web3.toWei(1, 'ether')
    transfer_gas = 210000000
    value = 1000
    chainid = 120
    ConsensusSize = 150
    time_interval = 10
    initial_amount = {
        'FOUNDATION': 905000000000000000000000000,
        'FOUNDATIONLOCKUP': 20000000000000000000000000,
        'STAKING': 25000000000000000000000000,
        'INCENTIVEPOOL': 45000000000000000000000000,
        'DEVELOPERS': 5000000000000000000000000
    }

    def start_init(self):
        # 修改config参数
        CommonMethod.update_config(self, 'EconomicModel', 'Common',
                                   'ExpectedMinutes', 3)
        CommonMethod.update_config(self, 'EconomicModel', 'Common',
                                   'PerRoundBlocks', 5)
        CommonMethod.update_config(self, 'EconomicModel', 'Common',
                                   'ValidatorCount', 10)
        CommonMethod.update_config(self, 'EconomicModel', 'Staking',
                                   'ElectionDistance', 10)
        CommonMethod.update_config(self, 'EconomicModel', 'Staking',
                                   'StakeThreshold', 1000)
        # 启动节点
        self.auto = AutoDeployPlaton()
        self.auto.start_all_node(self.node_yml_path)

    def test_init_token(self):
        '''
        验证链初始化后token各内置账户初始值
        :return:
        '''
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        FOUNDATION = platon_ppos.eth.getBalance(
            Web3.toChecksumAddress(conf.FOUNDATIONADDRESS))
        FOUNDATIONLOCKUP = platon_ppos.eth.getBalance(
            Web3.toChecksumAddress(conf.FOUNDATIONLOCKUPADDRESS))
        STAKING = platon_ppos.eth.getBalance(
            Web3.toChecksumAddress(conf.STAKINGADDRESS))
        INCENTIVEPOOL = platon_ppos.eth.getBalance(
            Web3.toChecksumAddress(conf.INCENTIVEPOOLADDRESS))
        DEVELOPERS = platon_ppos.eth.getBalance(
            Web3.toChecksumAddress(conf.DEVELOPERSADDRESS))
        token_init_total = conf.TOKENTOTAL
        if self.initial_amount['FOUNDATION'] != FOUNDATION:
            log.info("基金会初始金额:{}有误".format(FOUNDATION))
        elif self.initial_amount['FOUNDATIONLOCKUP'] != FOUNDATIONLOCKUP:
            log.info("基金会锁仓初始金额:{}有误".format(FOUNDATIONLOCKUP))
        elif self.initial_amount['STAKING'] != STAKING:
            log.info("质押账户初始金额:{}有误".format(STAKING))
        elif self.initial_amount['INCENTIVEPOOL'] != INCENTIVEPOOL:
            log.info("奖励池初始金额:{}有误".format(INCENTIVEPOOL))
        elif self.initial_amount['DEVELOPERS'] != DEVELOPERS:
            log.info("预留账户初始金额:{}有误".format(DEVELOPERS))
        reality_total = FOUNDATION + FOUNDATIONLOCKUP + STAKING + INCENTIVEPOOL + DEVELOPERS
        assert token_init_total == (
            reality_total), "初始化发行值{}有误".format(reality_total)

    def test_transfer_normal(self):
        '''
        验证初始化之后账户之间转账
        :return:
        '''
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list()
        # 签名转账
        result = platon_ppos.send_raw_transaction(
            '', Web3.toChecksumAddress(self.address),
            Web3.toChecksumAddress(address1), self.base_gas_price,
            self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt(result)
        assert return_info is not None, "转账:{}失败".format(self.value)
        balance = platon_ppos.eth.getBalance(address1)
        log.info("转账金额{}".format(balance))
        assert Web3.toWei(self.value,
                          'ether') == balance, "转账金额:{}失败".format(balance)

    def test_fee_income(self):
        '''
        1、验证初始化之后普通账户转账内置账户
        2、验证初始内置账户没有基金会Staking奖励和出块奖励只有手续费收益
        :return:
        '''
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        incentive_pool_balance_befor = platon_ppos.eth.getBalance(
            conf.INCENTIVEPOOLADDRESS)
        log.info('交易前激励池查询余额:{}'.format(incentive_pool_balance_befor))
        address1, private_key1 = CommonMethod.read_private_key_list()
        # 签名转账
        result = platon_ppos.send_raw_transaction(
            '', Web3.toChecksumAddress(self.address),
            Web3.toChecksumAddress(address1), self.base_gas_price,
            self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt(result)
        assert return_info is not None, "转账:{}失败".format(self.value)
        incentive_pool_balance_after = platon_ppos.eth.getBalance(
            conf.INCENTIVEPOOLADDRESS)
        log.info('交易后激励池查询余额:{}'.format(incentive_pool_balance_after))
        difference = incentive_pool_balance_after - incentive_pool_balance_befor
        log.info('手续费的金额:{}'.format(difference))
        assert difference == 1260000000000000000, "手续费{}有误".format(difference)

    def test_punishment_income(self):
        '''
        验证低出块率验证节点的处罚金自动转账到激励池
        :return:
        '''
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        incentive_pool_balance_befor = platon_ppos.eth.getBalance(
            conf.INCENTIVEPOOLADDRESS)
        log.info('处罚之前激励池查询余额:{}'.format(incentive_pool_balance_befor))

        #获取节点内置质押节点信息
        nodeId = CommonMethod.read_out_nodeId(self, 'collusion')
        log.info("节点ID:{}".format(nodeId))
        con_node, no_node = get_node_list(self.node_yml_path)
        nodes = con_node + no_node
        for node in nodes:
            if nodeId in node.values():
                node_data = node

        #获取节点质押金额
        punishment_CandidateInfo = platon_ppos.getCandidateInfo(nodeId)
        assert punishment_CandidateInfo['Status'] == True, "查询锁仓信息失败"
        pledge_amount1 = punishment_CandidateInfo['Data']['Released']
        log.info("质押节点质押金:{}".format(pledge_amount1))

        # 停止其中一个正在出块的节点信息
        self.auto = AutoDeployPlaton()
        self.auto.kill(node_data)
        platon_ppos1 = connect_web3(node_data['url'])
        assert not platon_ppos1.isConnected(), "节点:{} 连接异常".format(
            node_data['host'])
        CommonMethod.get_next_settlement_interval(self)
        punishment_CandidateInfo = platon_ppos.getCandidateInfo(nodeId)
        pledge_amount3 = punishment_CandidateInfo['Data']['Released']
        log.info("节点低出块率后节点质押金:{}".format(pledge_amount3))
        incentive_pool_balance_after = platon_ppos.eth.getBalance(
            conf.INCENTIVEPOOLADDRESS)
        log.info('处罚之后激励池查询余额:{}'.format(incentive_pool_balance_after))
        assert incentive_pool_balance_after == incentive_pool_balance_befor + (
            pledge_amount1 - pledge_amount3)
예제 #21
0
class TestDpos:
    node_yml_path = conf.NODE_YML
    cbft_json_path = conf.CBFT2
    node_info = get_node_info(node_yml_path)
    rpc_list, enode_list, nodeid_list, ip_list, port_list = node_info.get(
        'collusion')
    rpc_list2, enode_list2, nodeid_list2, ip_list2, port_list2 = node_info.get(
        'nocollusion')
    cbft_dict = LoadFile(cbft_json_path).get_data()
    address = Web3.toChecksumAddress(conf.ADDRESS)
    pwd = conf.PASSWORD
    ticket_price = Web3.fromWei(
        int(cbft_dict['ppos']['ticket']['ticketPrice']), 'ether')
    allowed = int(cbft_dict['ppos']['candidate']['allowed'])
    total_ticket = int(cbft_dict['ppos']['ticket']['maxCount'])
    rpc_list += rpc_list2
    enode_list += enode_list2
    nodeid_list += nodeid_list2
    ip_list += ip_list2
    port_list += port_list2
    key_list = ["node" + str(i) for i in range(1, 1 + len(rpc_list))]
    rpc_dict = dict(zip(key_list, rpc_list))
    enode_dict = dict(zip(key_list, enode_list))
    nodeid_dict = dict(zip(key_list, nodeid_list))
    ip_dict = dict(zip(key_list, ip_list))
    port_dict = dict(zip(key_list, port_list))
    abi = conf.DPOS_CONTRACT_ABI

    def setup_class(self):
        self.auto = AutoDeployPlaton(cbft=self.cbft_json_path)
        self.auto.start_all_node(self.node_yml_path)
        self.platon_dpos1 = PlatonDpos(
            self.rpc_list[0], self.address, self.pwd, abi=self.abi)
        self.w3_list = [connect_web3(url) for url in self.rpc_list]
        self.new_address = Web3.toChecksumAddress(
            self.platon_dpos1.web3.personal.newAccount(self.pwd))
        self.send_data = {
            "to": self.new_address,
            "from": self.address,
            "gas": '9000',
            "gasPrice": '1000000000',
            "value": self.w3_list[0].toWei(100000, 'ether'),
        }
        tx_hash = self.platon_dpos1.eth.sendTransaction(self.send_data)
        self.platon_dpos1.eth.waitForTransactionReceipt(tx_hash)
        self.platon_dpos2 = PlatonDpos(
            self.rpc_list[0], self.new_address, self.pwd, abi=self.abi)
        self.fee = int(1000).to_bytes(4, 'big')
        self.extra = "Test"

    # def teardown_class(self):
    #     self.auto.start_all_node(self.node_yml_path)

    def check_event(self, msg):
        event_data, func_name = msg
        func_name += "Event"
        assert func_name in event_data, "{}中不包含{}键".format(
            event_data, func_name)
        event = event_data[func_name][0]
        event = json.loads(event)
        assert event["Ret"], "质押结果状态错误"
        assert event["ErrMsg"] == "success", "质押结果msg错误"

    def test_candidate_deposit(self):
        '''
        @Description: 质押节点,使其成为候选人
        @param {type} @@@@
        @return: @@@@
        '''
        result = self.platon_dpos1.CandidateDeposit(self.nodeid_dict['node5'], self.new_address, self.fee,
                                                    self.ip_dict['node5'],
                                                    self.port_dict['node5'], self.extra, value=100)
        self.check_event(result)
        candidate_info = self.platon_dpos1.GetCandidateDetails(
            self.nodeid_dict['node5'])
        assert isinstance(candidate_info, dict), "返回结果错误{}".format(
            candidate_info)
        assert candidate_info["Deposit"] == self.platon_dpos1.web3.toWei(
            100, 'ether')
        assert candidate_info["Host"] == self.ip_dict["node5"], "质押ip与传输的ip不一致"
        assert candidate_info["CandidateId"] == self.nodeid_dict["node5"], "质押nodeid与传输的不一致"
        assert candidate_info["Port"] == self.port_dict['node5'], "质押端口与传输的不一致,获取port:{},实际质押port:{}".format(
            candidate_info["Port"], self.port_dict['node5'])
        assert self.platon_dpos1.web3.toChecksumAddress(
            candidate_info["Owner"]) == self.new_address, "质押地址不正确"
        candidate_list = self.platon_dpos2.GetCandidateList()
        # 校验candidate_list包含节点179
        assert candidate_info in candidate_list, "候选人列表不包含节点{}".format(
            self.ip_dict['node5'])

    # @pytest.mark.skip
    # def add_pledge(self):
    #     '''
    #     已不支持增加质押,用例暂不执行
    #     增加质押
    #     :return:
    #     '''
    #     result = self.platon_dpos1.CandidateDeposit(self.nodeid_dict['node5'], self.new_address, self.fee,
    #                                                 self.ip_dict['node5'],
    #                                                 self.port_dict['node5'], self.extra, value=10)
    #     self.check_event(result)
    #     candidate_info = self.platon_dpos1.GetCandidateDetails(
    #         self.nodeid_dict['node5'])
    #     # candidate_info为节点179的质押信息
    #     assert isinstance(candidate_info, dict), "返回结果错误{}".format(
    #         candidate_info)
    #     assert candidate_info["Deposit"] == self.platon_dpos1.web3.toWei(
    #         60, 'ether')

    # @pytest.mark.skip
    # def test_refund_10(self):
    #     '''
    #     已不支持部分退款,用例暂不执行
    #     @Description: 查询退款金额低于10%
    #     @param {type} @@@@
    #     @return: @@@@
    #     '''
    #     i = 500000000000000000
    #     status = 0
    #     try:
    #         self.platon_dpos2.CandidateApplyWithdraw(
    #             self.nodeid_dict['node5'], i)
    #     except:
    #         status = 1
    #     assert status == 1, "低于10%应不允许提取"

    def test_refund(self):
        '''
        @Description: 查询退款是否正常,是否退出候选人列表
        @param {type} @@@@
        @return: @@@@
        '''
        i = 50000000000000000000
        start_balance = self.platon_dpos2.eth.getBalance(self.new_address)
        result = self.platon_dpos2.CandidateDeposit(self.nodeid_dict['node6'], self.new_address, self.fee,
                                                    self.ip_dict['node6'],
                                                    self.port_dict['node6'], self.extra, value=50)
        candidate_info = self.platon_dpos1.GetCandidateDetails(
            self.nodeid_dict['node6'])
        self.check_event(result)
        result = self.platon_dpos2.CandidateApplyWithdraw(
            self.nodeid_dict['node6'], i)
        self.check_event(result)
        time.sleep(3)
        withdraw_list = self.platon_dpos2.GetCandidateWithdrawInfos(
            self.nodeid_dict['node6'])
        assert withdraw_list["Balance"] == i, "申请退款的金额与查询结果不一致"
        result = self.platon_dpos1.CandidateWithdraw(self.nodeid_dict["node6"])
        self.check_event(result)
        end_balance = self.platon_dpos1.eth.getBalance(self.new_address)
        assert end_balance - start_balance < 100000000000000000, "退款金额错误,退款前:{}|退款后:{}".format(
            self.platon_dpos1.web3.fromWei(start_balance, 'ether'), self.platon_dpos1.web3.fromWei(end_balance, 'ether'))
        candidate_list = self.platon_dpos1.GetCandidateList()
        assert candidate_info not in candidate_list, "node6还在候选人列表中"

    def test_candidate_sort(self):
        '''
        @Description: 候选人排序
        @param {type} @@@@
        @return: @@@@
        '''
        # result_1 = self.platon_dpos1.CandidateDeposit(self.nodeid_dict['node5'], self.new_address, self.fee,
        #                                               self.ip_dict['node5'],
        #                                               self.port_dict['node5'], self.extra, value=45)
        # self.check_event(result_1)
        result_2 = self.platon_dpos1.CandidateDeposit(self.nodeid_dict['node6'], self.new_address, self.fee,
                                                      self.ip_dict['node6'],
                                                      self.port_dict['node6'], self.extra, value=160)
        self.check_event(result_2)
        candidate_list = self.platon_dpos1.GetCandidateList()
        candidate_info = self.platon_dpos1.GetCandidateDetails(
            self.nodeid_dict['node6'])
        assert candidate_list[0] == candidate_info, "候选人列表排序错误"

    def test_candidate_cap(self):
        '''
        @Description: 候选人列表容量
        @param {type} @@@@
        @return: @@@@
        '''
        status = 0
        candidate_info = self.platon_dpos1.GetCandidateDetails(
            self.nodeid_dict['node5'])
        result_1 = self.platon_dpos1.CandidateDeposit(self.nodeid_dict['node1'], self.new_address, self.fee,
                                                      self.ip_dict['node1'],
                                                      self.port_dict['node1'], self.extra, value=131)
        self.check_event(result_1)
        result_2 = self.platon_dpos1.CandidateDeposit(self.nodeid_dict['node2'], self.new_address, self.fee,
                                                      self.ip_dict['node2'],
                                                      self.port_dict['node2'], self.extra, value=135)
        self.check_event(result_2)
        result_3 = self.platon_dpos1.CandidateDeposit(self.nodeid_dict['node3'], self.new_address, self.fee,
                                                      self.ip_dict['node3'],
                                                      self.port_dict['node3'], self.extra, value=135)
        self.check_event(result_3)
        result_4 = self.platon_dpos1.CandidateDeposit(self.nodeid_dict['node4'], self.new_address, self.fee,
                                                      self.ip_dict['node4'],
                                                      self.port_dict['node4'], self.extra, value=140)
        self.check_event(result_4)
        candidate_list = self.platon_dpos1.GetCandidateList()
        log.info("入围节点列表:{}".format(candidate_list))
        assert candidate_info not in candidate_list, "node5还在候选人列表中"

    def test_ticket_price(self):
        '''校验票价是否与配置文件中一致'''
        price = self.platon_dpos1.GetTicketPrice()
        config_price = Web3.toWei(self.ticket_price, 'ether')
        assert config_price == price, '实际票价:{},与配置文件中:{},不一致'.format(
            config_price, price)

    def test_vote_ticket(self):
        '''投票'''
        value = self.allowed * self.ticket_price
        vote_info, _ = self.platon_dpos1.VoteTicket(self.allowed, self.ticket_price, self.nodeid_dict['node6'],
                                                    self.new_address, value)
        self.platon_dpos1.VoteTicket(self.allowed, self.ticket_price, self.nodeid_dict['node1'],
                                     self.new_address, value)
        self.platon_dpos1.VoteTicket(self.allowed, self.ticket_price, self.nodeid_dict['node2'],
                                     self.new_address, value)
        self.platon_dpos1.VoteTicket(self.allowed, self.ticket_price, self.nodeid_dict['node3'],
                                     self.new_address, value)
        vote_info, _ = self.platon_dpos1.VoteTicket(self.allowed - 1, self.ticket_price, self.nodeid_dict['node4'],
                                     self.new_address, value - 1)
        assert 'success' in vote_info['VoteTicketEvent'][0], '投票失败,结果:{}'.format(
            vote_info)

    # @pytest.skip
    # def test_ticket_detail(self):
    #     '''
    #     接口已经删除,用例屏蔽
    #     验证节点下选票数量、选票的详细信息
    #     '''
    #     ticket_ids = self.platon_dpos1.GetCandidateTicketIds(self.nodeid_dict['node1'])
    #     ticket_num = len(ticket_ids)
    #     assert ticket_num == self.allowed, '节点选票数:{}与已投票数:{}不一致'.format(ticket_num, self.allowed)
    #     ticket_detail = self.platon_dpos1.GetTicketDetail(ticket_ids[0])
    #     owner = Web3.toChecksumAddress(ticket_detail[0]['Owner'])
    #     assert owner == self.new_address, '投票人:{}与投票时用的钱包地址:{}不一致'.format(owner, self.new_address)
    #     dposite = ticket_detail[0]['Deposit']
    #     price = Web3.toWei(self.ticket_price, 'ether')
    #     assert dposite == price, '投票金额:{}与票价:{}不一致'.format(dposite, price)
    #     candidateid = ticket_detail[0]['CandidateId']
    #     assert candidateid == self.nodeid_dict['node1'], '票详情中节点id:{},与投票时节点id不一致:{}'.format(candidateid,
    #                                                                                          self.nodeid_dict['node1'])

    # @pytest.skip
    # def test_batch_ticket_detail(self):
    #     '''
    #     接口已删除,用例屏蔽
    #     验证批量获取节点下选票数量、选票的详细信息
    #     '''
    #     batch_ticket_ids = self.platon_dpos1.GetBatchCandidateTicketIds(
    #         [self.nodeid_dict['node1'], self.nodeid_dict['node2']])
    #     print('batch_ticket_ids = ', batch_ticket_ids)
    #     ticket_ids = batch_ticket_ids[0].get(self.nodeid_dict['node1'])
    #     ticket_ids_one = self.platon_dpos1.GetCandidateTicketIds(self.nodeid_dict['node1'])
    #     assert ticket_ids == ticket_ids_one, '批量获取详情{}\n单独获取详情{}不一致'.format(ticket_ids, ticket_ids_one)
    #     node1_tickets = batch_ticket_ids[0].get(self.nodeid_dict['node1'])
    #     node2_tickets = batch_ticket_ids[0].get(self.nodeid_dict['node2'])
    #     ticket_details = self.platon_dpos1.GetBatchTicketDetail([node1_tickets[0], node2_tickets[0]])
    #     ticket_detail = ticket_details[0]
    #     ticket_detail_one = self.platon_dpos1.GetTicketDetail(ticket_details[0]['TicketId'])[0]
    #     assert ticket_detail == ticket_detail_one, '批量获取的票详情{}与单独查询票详情不一致{}'.format(ticket_detail, ticket_detail_one)
    #     assert len(ticket_details) == 2, '批量获取票详情数{}不等于请求数2'.format(len(ticket_details))

    def test_vote_undpos_node(self):
        '''向非备选池节点投票'''
        value = self.allowed * self.ticket_price
        status = 0
        try:
            self.platon_dpos1.VoteTicket(self.allowed, self.ticket_price, self.nodeid_dict['node5'],
                                         self.new_address, value)
        except:
            status = 1
        assert status, '不在备选池的节点不能投票成功'

    def test_ticket_pool_remainder(self):
        '''验证票池剩余数量'''
        remaind = self.platon_dpos1.GetPoolRemainder()
        should_remaind = self.total_ticket - (self.allowed * 5 - 1)
        assert remaind == should_remaind, '票池剩余票:{}与已消费后应剩余数:{}不一致'.format(
            remaind, should_remaind)

    # @pytest.skip
    # def test_get_candidate_epoch(self):
    #     '''
    #     获取票龄详情接口已删除,无法获取选票产生区块,用例无法验证
    #     该接口以后会去掉,用例暂不运行
    #     验证候选人票龄
    #     '''
    #     ticket_ids = self.platon_dpos1.GetCandidateTicketIds(self.nodeid_dict['node1'])
    #     vote_block_number = self.platon_dpos1.GetTicketDetail(ticket_ids[0])[0]['BlockNumber']
    #     should_epoch = (self.platon_dpos1.eth.blockNumber - vote_block_number + 1) * len(ticket_ids)
    #     epoch = self.platon_dpos1.GetCandidateEpoch(self.nodeid_dict['node1'])
    #     assert epoch == should_epoch, '候选人票龄计算结果:{},与预期结果:{}不一致'.format(epoch, should_epoch)

    def test_get_candidate_ticket_count(self):
        '''批量查询候选节点的有效选票数量'''
        ctc_dict = self.platon_dpos1.GetCandidateTicketCount(
            '{}:{}:{}:{}'.format(self.nodeid_dict['node1'], self.nodeid_dict['node2'], self.nodeid_dict['node3'],
                                 self.nodeid_dict['node4']))
        count1 = int(ctc_dict.get(self.nodeid_dict['node1']))
        count2 = int(ctc_dict.get(self.nodeid_dict['node2']))
        count3 = int(ctc_dict.get(self.nodeid_dict['node3']))
        count4 = int(ctc_dict.get(self.nodeid_dict['node4']))
        assert count1 == self.allowed, '候选节点有效选票数量{},与预期结果{}不一致'.format(
            count1, self.allowed)
        assert count2 == self.allowed, '候选节点有效选票数量{},与预期结果{}不一致'.format(
            count2, self.allowed)
        assert count3 == self.allowed, '候选节点有效选票数量{},与预期结果{}不一致'.format(
            count3, self.allowed)
        assert count4 == self.allowed - \
            1, '候选节点有效选票数量{},与预期结果{}不一致'.format(count4, self.allowed)

    # def test_get_ticket_count_by_tx_hash(self):
    #     '''批量查询交易的有效选票数量'''
    #     _, tx_hash1 = self.platon_dpos1.VoteTicket(
    #         self.allowed, 1, self.nodeid_dict['node1'], self.address, 10)
    #     _, tx_hash2 = self.platon_dpos1.VoteTicket(
    #         self.allowed, 1, self.nodeid_dict['node2'], self.address, 10)
    #     _, tx_hash3 = self.platon_dpos1.VoteTicket(
    #         self.allowed, 1, self.nodeid_dict['node3'], self.address, 10)
    #     _, tx_hash4 = self.platon_dpos1.VoteTicket(
    #         self.allowed, 1, self.nodeid_dict['node4'], self.address, 10)
    #     tc_dict = self.platon_dpos1.GetTicketCountByTxHash(
    #         '{}:{}:{}:{}'.format(tx_hash1, tx_hash2, tx_hash3, tx_hash4))
    #     assert tc_dict.get(tx_hash1) == self.allowed, '交易的有效选票数量{},与预期结果{}不一致'.format(tc_dict.get(tx_hash1),
    #                                                                                   self.allowed)
    #     assert tc_dict.get(tx_hash2) == self.allowed, '交易的有效选票数量{},与预期结果{}不一致'.format(tc_dict.get(tx_hash2),
    #                                                                                   self.allowed)
    #     assert tc_dict.get(tx_hash3) == self.allowed, '交易的有效选票数量{},与预期结果{}不一致'.format(tc_dict.get(tx_hash3),
    #                                                                                   self.allowed)
    #     assert tc_dict.get(tx_hash4) == self.allowed, '交易的有效选票数量{},与预期结果{}不一致'.format(tc_dict.get(tx_hash4),
    #                                                                                   self.allowed)

    def test_verifiers(self):
        '''
        @Description: 验证人为候选人列表的前四,幸运票奖励发放
        @param {type} @@@@
        @return: @@@@
        '''
        before_reward = self.platon_dpos1.eth.getBalance(self.new_address)
        candidate_list = self.platon_dpos1.GetCandidateList()
        log.info("新的的入围节点列表:{}".format(candidate_list))
        candidate_id = [i['CandidateId'] for i in candidate_list]
        block_number = self.platon_dpos1.eth.blockNumber
        sleep_time = get_sleep_time(block_number)
        time.sleep(sleep_time)
        verfier_info_list = self.platon_dpos1.GetVerifiersList()
        log.info("验证人列表:{}".format(verfier_info_list))
        assert len(verfier_info_list) > 0,"查询结果异常,验证人列表为空。"
        verfier_list = [info['CandidateId'] for info in verfier_info_list]
        assert verfier_list == candidate_id[:4], "验证人没有取候选人的前四,验证人id:{}\n候选人id:{}".format(verfier_list,
                                                                                            candidate_list[:4])
        status = 1
        for verfier in verfier_list:
            if self.nodeid_dict['node4'] in verfier:
                status = 0
        assert status, '投票不达到门槛不能成为见证人'
        # 校验幸运选票是否发放奖励
        after_reward = self.platon_dpos1.eth.getBalance(self.new_address)
        assert after_reward > before_reward, '见证人奖励未发放,发放前余额:{},发放后余额:{}'.format(
            before_reward, after_reward)

    def test_verify_transaction(self):
        '''
        @Description: 切换验证人后,测试交易是否成功,所有节点块高是否一致
        @param {type} @@@@
        @return: @@@@
        '''
        tx_hash = self.platon_dpos1.eth.sendTransaction(self.send_data)
        self.platon_dpos1.eth.waitForTransactionReceipt(tx_hash)
        block_list = []
        for w in self.w3_list:
            block_list.append(w.eth.blockNumber)
        assert min(block_list) > 60, "区块没有正常增加"
        assert max(block_list) - min(block_list) < 5, "各节点区块高度差距过高"
        time.sleep(60)
        w3 = Web3(Web3.HTTPProvider(self.rpc_dict["node6"]))
        assert w3.net.peerCount >= 3, "节点node6连接的节点数少于3个"
예제 #22
0
class TestVC:
    node_yml = abspath("deploy/node/vc_node.yml")
    auto = AutoDeployPlaton()

    def setup_class(self):
        self.auto.start_all_node(self.node_yml,
                                 genesis_file=conf.GENESIS_TMP,
                                 static_node_file=conf.STATIC_NODE_FILE)
        # 等一下,同步块高
        collusion, _ = get_node_list(conf.NODE_YML)
        collusion_w3 = connect_web3(collusion[0]["url"])
        collusion_block = collusion_w3.eth.blockNumber
        _, nocollusion = get_node_list(self.node_yml)
        self.url = nocollusion[0]['url']
        self.ip = nocollusion[0]["host"]
        self.wt = PlatonContractTransaction(self.url)
        self.password = conf.PASSWORD
        nocollusion_block = self.wt.eth.blockNumber
        if collusion_block - nocollusion_block >= 100:
            time.sleep(20)
        elif 100 > collusion_block - nocollusion_block >= 50:
            time.sleep(10)
        else:
            time.sleep(5)
        addrress = self.wt.w3.toChecksumAddress(conf.ADDRESS)
        self.wt.w3.personal.unlockAccount(addrress, self.password, 999999)
        """部署合约"""
        resp = self.wt.contract_deploy(
            get_byte_code(abspath('./data/contract/vccMain.wasm')),
            get_abi_bytes(abspath(r'./data/contract/vccMain.cpp.abi.json')),
            addrress)
        result = self.wt.eth.waitForTransactionReceipt(resp)
        self.contract_address = result['contractAddress']
        log.info(self.contract_address)
        if len(self.wt.eth.getCode(self.contract_address)) < 10:
            raise Exception("合约部署失败")
        node = nocollusion[0]
        ssh, sftp, t = connect_linux(node['host'],
                                     username=node['username'],
                                     password=node['password'])
        pwd_list = run_ssh(ssh, "pwd")
        pwd = pwd_list[0].strip("\r\n")
        account = 'UTC--2018-10-04T09-02-39.439063439Z--493301712671ada506ba6ca7891f436d29185821'
        self.wallet_path = '{}/{}/data16789/keystore/{}'.format(
            pwd, conf.DEPLOY_PATH, account)
        cmd = '''nohup java -jar ./vc_tool/vctool-1.0.jar  > ./vc_tool/nohup.out 2>&1 &'''
        run_ssh(ssh, cmd)
        self.get_url = 'http://{}:8112/test/getResult'.format(self.ip)

    def tearDown(self):
        self.auto.kill_of_yaml(self.node_yml)

    def get_transaction_hash(self, value, gas, gasPrice):
        '''
        :return:交易hash
        '''
        url = 'http://{}:8112/test/startVC'.format(self.ip)
        data = {
            'walletPath': self.wallet_path,
            'walletPass': self.password,
            'contractAddress': self.contract_address,
            'input': '20#30',
            'value': value,
            'gas': gas,
            'gasPrice': gasPrice
        }

        ret = requests.post(url=url, data=data)
        hash = ret.text
        assert hash is not None, '哈希预期返回成功{},实际失败'.format(hash)
        return hash

    def get_vc_taskid(self, value=4300000, gas=4300000, gasPrice=22000000000):
        '''
        :return:taskid vc任务号
        '''
        hash = self.get_transaction_hash(value, gas, gasPrice)
        url = 'http://{}:8112/test/getTaskIdForHash'.format(self.ip)
        data = {
            'walletPath': self.wallet_path,
            'walletPass': self.password,
            'contractAddress': self.contract_address,
            'hash': hash
        }
        ret = requests.post(url=url, data=data)
        taskid = ret.text
        assert taskid is not None, 'taskid预期返回成功{},实际失败'.format(taskid)
        return taskid

    def test_vc_result_add(self):
        '''
        获取VC合约add的值
        :return:
        '''
        taskid = self.get_vc_taskid()
        time.sleep(30)
        data = {
            'walletPath': self.wallet_path,
            'walletPass': self.password,
            'contractAddress': self.contract_address,
            'taskId': taskid
        }
        ret = requests.post(url=self.get_url, data=data)
        result = int(ret.text)
        assert result == 50, '预期结果为50,实际结果为{}'.format(result)
        assert ret.status_code == 200, '预期返回响应码为200,实际为{}'.format(
            str(ret.status_code))

    def test_value_outsize(self):
        '''
        value过大
        :return:
        '''
        taskid = self.get_vc_taskid(value=100000000000000000000000000)
        time.sleep(30)
        data = {
            'walletPath': self.wallet_path,
            'walletPass': self.password,
            'contractAddress': self.contract_address,
            'taskId': taskid
        }
        ret = requests.post(url=self.get_url, data=data)
        result = int(ret.text)
        assert result == 0, '预期结果为0,实际结果为{}'.format(result)

    def test_value_insuff(self):
        '''
        value为0
        :return:
        '''
        taskid = self.get_vc_taskid(value=0)
        time.sleep(30)
        data = {
            'walletPath': self.wallet_path,
            'walletPass': self.password,
            'contractAddress': self.contract_address,
            'taskId': taskid
        }
        ret = requests.post(url=self.get_url, data=data)
        result = int(ret.text)
        assert result == 50, '预期结果为50,实际结果为{}'.format(result)

    def test_gas_outsize(self):
        '''
        gas值超过范围内
        :return:
        '''
        taskid = self.get_vc_taskid(gas=1000000000000000000)
        time.sleep(30)
        data = {
            'walletPath': self.wallet_path,
            'walletPass': self.password,
            'contractAddress': self.contract_address,
            'taskId': taskid
        }

        status = 0
        try:
            ret = requests.post(url=self.get_url, data=data)
            assert ret.status_code != 200, '预期返回响应失败,实际为{}'.format(
                str(ret.status_code))
        except:
            status = 1
        assert status == 1, '预期gas过大,返回异常,实际返回成功'

    def test_gas_insuff(self):
        '''
        gas值过小
        :return:
        '''
        taskid = self.get_vc_taskid(gas=10)
        time.sleep(30)
        data = {
            'walletPath': self.wallet_path,
            'walletPass': self.password,
            'contractAddress': self.contract_address,
            'taskId': taskid
        }

        status = 0
        try:
            ret = requests.post(url=self.get_url, data=data)
            assert ret.status_code != 200, '预期返回响应失败,实际为{}'.format(
                str(ret.status_code))
        except:
            status = 1
        assert status == 1, '预期gas过小,返回异常,实际返回成功'
예제 #23
0
class CommonMethod():
    address = conf.ADDRESS
    pwd = conf.PASSWORD
    abi = conf.DPOS_CONTRACT_ABI
    cbft_json_path = conf.CBFT2
    node_yml_path = conf.PPOS_NODE_TEST_YML
    file = conf.CASE_DICT
    privatekey = conf.PRIVATE_KEY
    gasPrice = Web3.toWei(0.000000000000000001, 'ether')
    gas = 21000
    transfer_gasPrice = Web3.toWei(1, 'ether')
    transfer_gas = 210000000
    value = 1000
    time_interval = 10
    #ConsensusSize = 50
    ExpectedMinutes = 180
    chainid = 101

    def link_list(self):
        '''
        获取随机一个可以连接正常节点url
        :return:
        '''
        rpc_lastlist = []
        node_info = get_node_info(self.node_yml_path)
        self.rpc_list, enode_list, self.nodeid_list, ip_list, port_list = node_info.get(
            'collusion')
        for i in self.rpc_list:
            self.web3 = connect_web3(i)
            if self.web3.isConnected():
                rpc_lastlist.append(i)
        if rpc_lastlist:
            #log.info("目前可连接节点列表:{}".format(rpc_lastlist))
            index = random.randint(0, len(rpc_lastlist) - 1)
            url = rpc_lastlist[index]
            log.info("当前连接节点:{}".format(url))
            return url
        else:
            log.info("无可用节点")

    def get_next_settlement_interval(self,
                                     number=1,
                                     file=conf.PLATON_CONFIG_PATH):
        '''
        获取下个结算周期
        :param :
        :return:
        '''
        data = LoadFile(file).get_data()
        ExpectedMinutes = data['EconomicModel']['Common']['ExpectedMinutes']
        Interval = data['EconomicModel']['Common']['Interval']
        PerRoundBlocks = data['EconomicModel']['Common']['PerRoundBlocks']
        ValidatorCount = data['EconomicModel']['Common']['ValidatorCount']
        Consensuswheel = (ExpectedMinutes * 60) // (Interval * PerRoundBlocks *
                                                    ValidatorCount)
        ConsensusSize = Consensuswheel * (Interval * PerRoundBlocks *
                                          ValidatorCount)
        ConsensusSize = ConsensusSize * number
        log.info("结算周期块高:{}".format(ConsensusSize))
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        current_block = platon_ppos.eth.blockNumber
        differ_block = ConsensusSize - (current_block % ConsensusSize)
        current_end_block = current_block + differ_block
        log.info('当前块高:{} ,下个结算周期结束块高:{}'.format(current_block,
                                                 current_end_block))

        while 1:
            time.sleep(self.time_interval)
            current_block = platon_ppos.eth.blockNumber
            differ_block = ConsensusSize - (current_block % ConsensusSize)
            log.info('当前块高度:{},还差块高:{}'.format((current_block), differ_block))
            if current_block > current_end_block:
                break

    def get_next_consensus_wheel(self, number=1, file=conf.PLATON_CONFIG_PATH):
        '''
        获取下个共识轮
        :param :
        :return:
        '''
        data = LoadFile(file).get_data()
        Interval = data['EconomicModel']['Common']['Interval']
        PerRoundBlocks = data['EconomicModel']['Common']['PerRoundBlocks']
        ValidatorCount = data['EconomicModel']['Common']['ValidatorCount']
        ConsensusSize = Interval * PerRoundBlocks * ValidatorCount
        ConsensusSize = ConsensusSize * number
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        current_block = platon_ppos.eth.blockNumber
        differ_block = ConsensusSize - (current_block % ConsensusSize)
        current_end_block = current_block + differ_block
        log.info('当前块高:{} ,下个共识轮周期结束块高:{}'.format(current_block,
                                                  current_end_block))

        while 1:
            time.sleep(self.time_interval)
            current_block = platon_ppos.eth.blockNumber
            differ_block = ConsensusSize - (current_block % ConsensusSize)
            log.info('当前块高度:{},还差块高:{}'.format((current_block), differ_block))
            if current_block > current_end_block:
                break

    def read_out_nodeId(self, code):
        """
        读取节点id列表
        :param code: 共识节点或者非共识节点标识
        :return:
        """
        node_info = get_node_info(self.node_yml_path)
        self.rpc_list, enode_list, nodeid_list, ip_list, port_list = node_info.get(
            code)
        node_list_length = len(nodeid_list)
        index = random.randint(0, node_list_length - 1)
        nodeId = nodeid_list[index]
        return nodeId

    def test(self):
        self.auto = AutoDeployPlaton()
        self.auto.start_all_node(self.node_yml_path)
        # print(self.nodeid_list)

    def query_blockNumber(self):
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        while 1:
            current_block = platon_ppos.eth.blockNumber
            time.sleep(10)
            print(current_block)

    def update_config(self,
                      key1,
                      key2,
                      key3=None,
                      value=None,
                      file=conf.PLATON_CONFIG_PATH):
        '''
        修改config配置参数
        :param key1: 第一层级key
        :param key2: 第二层级key
        :param key3: 第三层级key
        :param value:
        :param file:
        :return:
        '''
        data = LoadFile(file).get_data()
        if key3 == None:
            data[key1][key2] = value
        else:
            data[key1][key2][key3] = value

        data = json.dumps(data)
        with open(conf.PLATON_CONFIG_PATH, "w") as f:
            f.write(data)
            f.close()

    def read_private_key_list(file=conf.PRIVATE_KEY_LIST):
        '''
        随机获取一组钱包地址和私钥
        :return:
        '''
        with open(file, 'r') as f:
            private_key_list = f.read().split("\n")
            index = random.randrange(1, len(private_key_list) - 1)  # 生成随机行数
            address, private_key = private_key_list[index].split(',')
        return address, private_key

    def get_no_candidate_list(self):
        '''
        获取未被质押的节点ID列表
        :return:
        '''
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        node_info = get_node_info(self.node_yml_path)
        self.rpc_list, enode_list, nodeid_list, ip_list, port_list = node_info.get(
            'nocollusion')
        no_candidate_list = []
        for index in range(len(nodeid_list)):
            nodeid = nodeid_list[index]
            result = platon_ppos.getCandidateInfo(nodeid)
            flag = result['Status']

            if not flag:
                no_candidate_list.append(nodeid)
        if no_candidate_list:
            node_list_length = len(no_candidate_list)
            index = random.randint(0, node_list_length - 1)
            nodeId = no_candidate_list[index]
            return nodeId
        else:
            CommonMethod.start_init(self)
            # self.rpc_list, enode_list, nodeid_list, ip_list, port_list = node_info.get ('nocollusion')
            return nodeid_list[0]

    def start_init(self):
        #修改config参数
        CommonMethod.update_config(self, 'EconomicModel', 'Common',
                                   'ExpectedMinutes', 3)
        CommonMethod.update_config(self, 'EconomicModel', 'Common',
                                   'PerRoundBlocks', 10)
        CommonMethod.update_config(self, 'EconomicModel', 'Common',
                                   'ValidatorCount', 5)
        CommonMethod.update_config(self, 'EconomicModel', 'Staking',
                                   'ElectionDistance', 20)
        CommonMethod.update_config(self, 'EconomicModel', 'Staking',
                                   'StakeThreshold', 1000)
        #启动节点
        self.auto = AutoDeployPlaton()
        self.auto.start_all_node(self.node_yml_path)

    def View_available_nodes(self):
        url = CommonMethod.link_list(self)
        platon_ppos = Ppos(url, self.address, self.chainid)
        node_info = get_node_info(self.node_yml_path)
        self.rpc_list, enode_list, nodeid_list, ip_list, port_list = node_info.get(
            'nocollusion')
        candidateinfo = platon_ppos.getCandidateList()
        candidateinfo = candidateinfo.get('Data')
        candidate_list = []
        for nodeid in candidateinfo:
            candidate_list.append(nodeid.get('NodeId'))

        if set(nodeid_list) <= set(candidate_list):
            CommonMethod.start_init(self)
예제 #24
0
 def test(self):
     self.auto = AutoDeployPlaton()
     self.auto.start_all_node(self.node_yml_path)
class TestLockeDpositionConfig:
    address = conf.ADDRESS
    pwd = conf.PASSWORD
    abi = conf.DPOS_CONTRACT_ABI
    cbft_json_path = conf.CBFT2
    node_yml_path = conf.PPOS_NODE_TEST_YML
    file = conf.CASE_DICT
    privatekey = conf.PRIVATE_KEY
    base_gas_price = 60000000000000
    base_gas = 21000
    staking_gas = base_gas + 32000 + 6000 + 100000
    transfer_gasPrice = Web3.toWei (1, 'ether')
    transfer_gas = 210000000
    value = 1000
    chainid = 120
    ConsensusSize = 150
    time_interval = 10
    initial_amount = {'FOUNDATION': 905000000000000000000000000,
                      'FOUNDATIONLOCKUP': 20000000000000000000000000,
                      'STAKING': 25000000000000000000000000,
                      'INCENTIVEPOOL': 45000000000000000000000000,
                      'DEVELOPERS': 5000000000000000000000000
                      }
    def start_init(self):
        #修改config参数
        CommonMethod.update_config(self,'EconomicModel','Common','ExpectedMinutes',3)
        CommonMethod.update_config(self,'EconomicModel','Common','PerRoundBlocks',10)
        CommonMethod.update_config(self,'EconomicModel','Common','ValidatorCount',5)
        CommonMethod.update_config(self,'EconomicModel','Staking','ElectionDistance',20)
        CommonMethod.update_config(self,'EconomicModel','Staking','StakeThreshold',1000)
        #启动节点
        self.auto = AutoDeployPlaton ()
        self.auto.start_all_node (self.node_yml_path)


    def test_unlock_Normal(self):
        '''
        只有一个锁仓期,到达解锁期返回解锁金额
        :param amount:
        :return:
        '''
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()
        address2, private_key2 = CommonMethod.read_private_key_list ()

        # 签名转账
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None,"转账:{}失败".format(self.value)
        # 创建锁仓计划
        loukupbalace = Web3.toWei (50, 'ether')
        plan = [{'Epoch': 1, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address2, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回状态为:{} 有误".format (result['Status'])
        print(address2)
        balance = platon_ppos.eth.getBalance(address2)
        log.info ("锁仓之后账户余额:{}".format (balance))
        log.info("当前块高:{}".format(platon_ppos.eth.blockNumber))
        RestrictingInfo = platon_ppos.GetRestrictingInfo(address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads(RestrictingInfo['Data'])
        assert dict_Info['balance'] == loukupbalace,"锁仓金额:{}有误".format(dict_Info['balance'])

        #验证到达锁仓解锁期之后账户金额
        CommonMethod.get_next_settlement_interval(self)
        balance2 = platon_ppos.eth.getBalance(address2)
        log.info ("解锁之后账户余额:{}".format (balance2))
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        balance = platon_ppos.eth.getBalance(address2)
        assert dict_Info['balance'] == 0, "锁仓金额:{}有误".format (dict_Info['balance'])
        assert balance2 == loukupbalace,"返回的释放锁仓金额:{} 有误".format(balance)

    def test_multiple_unlock_Normal(self):
        '''
        多个锁仓期,到达部分解锁期返回解锁金额
        :return:
        '''
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()
        address2, private_key2 = CommonMethod.read_private_key_list ()

        # 签名转账
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None,"转账:{}失败".format(self.value)
        loukupbalace = Web3.toWei (50, 'ether')
        plan = [{'Epoch': 1, 'Amount': loukupbalace},{'Epoch': 2, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address2, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回状态为:{} 有误".format (result['Status'])
        balance = platon_ppos.eth.getBalance (address2)
        log.info ("锁仓之后账户余额:{}".format (balance))
        log.info ("当前块高:{}".format (platon_ppos.eth.blockNumber))
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == loukupbalace*2, "锁仓金额:{}有误".format (dict_Info['balance'])

        # 验证到达锁仓第一个解锁期之后账户金额
        CommonMethod.get_next_settlement_interval (self)
        balance2 = platon_ppos.eth.getBalance (address2)
        log.info ("到达第一个解锁期后账户余额:{}".format (balance2))
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        balance = platon_ppos.eth.getBalance (address2)
        assert dict_Info['balance'] == loukupbalace, "锁仓金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['Entry'][0]['amount'] == loukupbalace,"第二个解锁期待释放金额:{}".format(dict_Info['Entry'][0]['amount'])
        assert balance2 == loukupbalace, "返回的释放锁仓金额:{} 有误".format (balance)

        #验证到达锁仓第二个解锁期之后账户金额
        CommonMethod.get_next_settlement_interval (self)
        balance3 = platon_ppos.eth.getBalance (address2)
        log.info ("到达第二个解锁期后账户余额:{}".format (balance2))
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        balance = platon_ppos.eth.getBalance (address2)
        assert dict_Info['balance'] == 0, "锁仓金额:{}有误".format (dict_Info['balance'])
        assert balance3 == loukupbalace*2, "返回的释放锁仓金额:{} 有误".format (balance)

    def test_unlock_point_pledge_amount(self):
        '''
        到达解锁时间点,锁仓金额质押后在解锁期之后再申请退回质押金
        :return:
        '''
        nodeId = CommonMethod.get_no_candidate_list (self)
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()
        address2, private_key2 = CommonMethod.read_private_key_list ()

        # 签名转账
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None,"转账:{}失败".format(self.value)

        # 给锁仓账号转手续费
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address2),
                                                   self.base_gas_price, self.base_gas, self.value,
                                                   self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)
        Balance = platon_ppos.eth.getBalance(address1)
        log.info("{}发起锁仓账户余额:{}".format(address1,Balance))
        Balance1 = platon_ppos.eth.getBalance (address1)
        log.info ("{}发起质押账号余额:{}".format (address2, Balance1))

        # 创建锁仓计划
        lockupamoutn = 900
        loukupbalace = Web3.toWei (lockupamoutn, 'ether')
        plan = [{'Epoch': 1, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address2, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回的状态:{},用例失败".format (result['Status'])
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "查询锁仓计划返回的状态:{},用例失败".format (result['Status'])
        info = json.loads(RestrictingInfo['Data'])
        assert info['balance'] == loukupbalace,"锁仓计划可用余额:{},有误".format(info['balance'])
        balance2 = platon_ppos.eth.getBalance (address1)
        log.info ("{}创建锁仓后余额:{}".format (address1,balance2))

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 800
        result = platon_ppos.createStaking (1, address2, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key2, from_address=address2,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == True, "申请质押返回的状态:{},{},用例失败".format (result['Status'], result['ErrMsg'])
        balance3 = platon_ppos.eth.getBalance (address2)
        log.info ("{}质押完账户余额:{}".format (address2,balance3))
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == Web3.toWei(lockupamoutn - amount,'ether'), "锁仓金额:{}有误".format (dict_Info['balance'])

        # 到达解锁期之后锁仓账号余额
        CommonMethod.get_next_settlement_interval (self)
        balance4 = platon_ppos.eth.getBalance (address2)
        log.info("到达解锁期后预期账户余额:{}".format(balance3 + Web3.toWei(lockupamoutn - amount,'ether')))
        log.info("到达解锁期后实际账户余额:{}".format (balance4))
        assert balance4 == balance3 + Web3.toWei(lockupamoutn - amount,'ether'),"锁仓账户金额:{} 有误".format(balance4)
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == 0, "锁仓金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == True,"锁仓的状态:{} 有误".format(dict_Info['symbol'])
        assert dict_Info['debt'] == Web3.toWei(amount,'ether'),"欠释放锁仓金额:{} 有误".format(dict_Info['debt'])

        # 申请退回质押金
        result = platon_ppos.unStaking (nodeId, privatekey=private_key2, from_address=address2,
                                        gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == True, "申请质押退回质押金返回的状态:{},用例失败".format (result['Status'])
        balance5 = platon_ppos.eth.getBalance (address2)
        log.info ("到达解锁期申请退回质押金后账户余额:{}".format (balance5))

        # 等待两个结算周期后查询锁仓账号情况
        CommonMethod.get_next_settlement_interval (self,3)
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        balance6 = platon_ppos.eth.getBalance (address2)
        log.info ("到达解锁期退回质押金后预期账户金额:{}".format (balance5 + loukupbalace))
        log.info ("到达解锁期退回质押金后实际账户余额:{}".format (balance6))
        assert balance6 == balance5 + loukupbalace, "锁仓账户金额:{} 有误".format (balance6)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == 0, "锁仓金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == False, "锁仓的状态:{} 有误".format (dict_Info['symbol'])
        assert dict_Info['debt'] == 0, "欠释放锁仓金额:{} 有误".format (dict_Info['debt'])



    def test_unlock_point_delegtion_notbalance(self):
        '''
        1、到达解锁时间点用锁仓金额去委托节点,到达解锁期账户锁仓不足
        2、到达解锁期账户申请部分赎回委托
        3、全部赎回委托
        :return:
        '''
        nodeId = CommonMethod.get_no_candidate_list (self)
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()
        address2, private_key2 = CommonMethod.read_private_key_list ()

        # 签名转账
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账质押账号手续费:{}失败".format (self.value)

        # 给锁仓账号转手续费
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address2),
                                                   self.base_gas_price, self.base_gas, self.value,
                                                   conf.PRIVATE_KEY)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账锁仓账号手续费:{}失败".format (self.value)
        Balance = platon_ppos.eth.getBalance (address1)
        log.info ("{}发起锁仓账户余额:{}".format (address1, Balance))
        Balance1 = platon_ppos.eth.getBalance (address1)
        log.info ("{}发起质押账号余额:{}".format (address2, Balance1))

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 100
        result = platon_ppos.createStaking (0, address1, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key1, from_address=address1,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == True, "申请质押返回的状态:{},{},用例失败".format (result['Status'], result['ErrMsg'])
        Balance2 = platon_ppos.eth.getBalance (address1)
        log.info ("{}申请质押节点后账户余额:{}".format (address1, Balance2))

        # 创建锁仓计划
        lockupamoutn = 100
        loukupbalace = Web3.toWei (lockupamoutn, 'ether')
        plan = [{'Epoch': 1, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address2, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回的状态:{},用例失败".format (result['Status'])
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "查询锁仓计划返回的状态:{},用例失败".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == loukupbalace, "锁仓计划金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == False, "锁仓的状态:{} 有误".format (dict_Info['symbol'])
        assert dict_Info['debt'] == 0, "欠释放锁仓金额:{} 有误".format (dict_Info['debt'])
        Balance3 = platon_ppos.eth.getBalance (address1)
        log.info ("{}创建锁仓计划后账户余额:{}".format (address1, Balance3))

        # 申请委托验证人节点
        amount = 100
        result = platon_ppos.delegate (1, nodeId, amount, privatekey=private_key2, from_address=address2,
                                              gasPrice=self.base_gas_price, gas=self.staking_gas)
        log.info ("申请委托地址:{}".format (address2))
        assert result['Status'] == True, "申请委托返回的状态:{},用例失败".format (result['Status'])
        balance4 = platon_ppos.eth.getBalance (address2)
        log.info ("{}申请委托验证人节点后账户余额:{}".format (address2,balance4))

        # 到达解锁期之后锁仓账号余额
        CommonMethod.get_next_settlement_interval (self)
        balance5 = platon_ppos.eth.getBalance (address2)
        log.info ("{}到达解锁期后实际账户余额:{}".format (address2,balance5))
        assert balance5 == balance4, "锁仓账户金额:{} 有误".format (balance5)
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == 0, "锁仓金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == True, "锁仓的状态:{} 有误".format (dict_Info['symbol'])
        assert dict_Info['debt'] == loukupbalace, "欠释放锁仓金额:{} 有误".format (dict_Info['debt'])

        #申请赎回部分委托金
        partamount = 50
        msg = platon_ppos.getCandidateInfo (nodeId)
        stakingBlockNum = msg["Data"]["StakingBlockNum"]
        delegate_info = platon_ppos.unDelegate (stakingBlockNum, nodeId, partamount, privatekey=private_key2,
                                                from_address=address2, gasPrice=self.base_gas_price,
                                                gas=self.staking_gas)
        assert delegate_info['Status'] == True, "申请赎回委托返回的状态:{},用例失败".format (result['Status'])
        balance6 = platon_ppos.eth.getBalance (address2)
        log.info ("{}到达解锁期发起赎回部分委托后账户余额:{}".format (address2,balance6))

        #到达下个解锁期释放部分委托金
        CommonMethod.get_next_settlement_interval (self)
        balance7 = platon_ppos.eth.getBalance (address2)
        log.info ("赎回部分委托金后锁仓账户余额:{}".format (balance7))
        assert balance7 == balance6 + Web3.toWei (partamount, 'ether'),"到达解锁期赎回部分委托后账户余额:{}".format (balance7)
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == 0, "锁仓金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == True, "锁仓的状态:{} 有误".format (dict_Info['symbol'])
        assert dict_Info['debt'] == loukupbalace - Web3.toWei (partamount, 'ether'), "欠释放锁仓金额:{} 有误".format (dict_Info[                                                                                         'debt'])
        #申请赎回全部委托金
        delegate_info = platon_ppos.unDelegate (stakingBlockNum, nodeId, lockupamoutn - partamount, privatekey=private_key2,
                                                from_address=address2, gasPrice=self.base_gas_price,
                                                gas=self.staking_gas)
        assert delegate_info['Status'] == True, "申请赎回委托返回的状态:{},用例失败".format (result['Status'])
        balance8 = platon_ppos.eth.getBalance (address2)
        log.info ("{}赎回全部委托金后锁仓账户余额:{}".format (address2,balance8))

        #到达下个解锁期释放全部委托金
        CommonMethod.get_next_settlement_interval (self)
        balance9 = platon_ppos.eth.getBalance (address2)
        log.info ("{}赎回全部委托金后实际账户余额:{}".format (address2,balance9))
        log.info ("{}赎回全部委托金后预期账户余额:{}".format (address2,balance8 + Web3.toWei (lockupamoutn - partamount, 'ether')))
        assert balance9 == balance8 + loukupbalace - Web3.toWei (partamount, 'ether'), "到达解锁期赎回委托后账户余额:{}".format                                                                                             (balance9)
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == 0, "锁仓金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == False, "锁仓的状态:{} 有误".format (dict_Info['symbol'])
        assert dict_Info['debt'] == 0, "欠释放锁仓金额:{} 有误".format (dict_Info['debt'])

    def test_unlock_point_pledge_punish_amount(self):
        '''
        到达解锁期后处罚节点后锁仓账户的余额情况
        :return:
        '''
        nodeId = CommonMethod.get_no_candidate_list (self)
        log.info("质押节点ID:{}".format(nodeId))
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()
        address2, private_key2 = CommonMethod.read_private_key_list ()

        # 给发起锁仓账户转手续费
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)

        # 给发起质押账号转手续费
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address2),
                                                   self.base_gas_price, self.base_gas, self.value,
                                                   self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)

        Balance = platon_ppos.eth.getBalance (address1)
        log.info ("{}账户余额:{}".format (address1, Balance))
        Balance1 = platon_ppos.eth.getBalance (address1)
        log.info ("{}账号余额:{}".format (address2, Balance1))

        # 创建锁仓计划
        lockupamoutn = 900
        loukupbalace = Web3.toWei (lockupamoutn, 'ether')
        plan = [{'Epoch': 3, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address2, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回的状态:{},用例失败".format (result['Status'])
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "查询锁仓计划返回的状态:{},用例失败".format (result['Status'])
        Balance2 = platon_ppos.eth.getBalance (address1)
        log.info ("{}发起锁仓后账户余额:{}".format (address1, Balance2))

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 900
        result = platon_ppos.createStaking (1, address2, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key2, from_address=address2,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == True, "申请质押返回的状态:{},{},用例失败".format (result['Status'], result['ErrMsg'])
        platon_ppos.GetRestrictingInfo(address2)
        result = platon_ppos.getCandidateInfo(nodeId)
        assert result['Status'] == True, "获取质押节点返回状态为:{} 有误".format (result['Status'])
        RestrictingPlan = result['Data']['RestrictingPlanHes']
        assert RestrictingPlan == Web3.toWei (amount, 'ether'),'质押金额:{} 有误'.format(RestrictingPlan)
        Balance3 = platon_ppos.eth.getBalance (address2)
        log.info ("{}质押完锁仓账户余额:{}".format (address2,Balance3))

        #等待验证人加入共识出块节点
        CommonMethod.get_next_settlement_interval (self,1)
        Balance4 = platon_ppos.eth.getBalance (address2)
        log.info ("{}加入共识验证人后账户余额:{}".format (address2, Balance4))

        # 获取节点内置质押节点信息
        con_node, no_node = get_node_list (self.node_yml_path)
        nodes = con_node + no_node
        for node in nodes:
            if nodeId in node.values ():
                node_data = node
        log.info("{}质押节点信息:{}".format(address2,node_data))

        #停止质押节点
        self.auto = AutoDeployPlaton ()
        self.auto.kill (node_data)
        platon_ppos1 = connect_web3 (node_data['url'])
        assert not platon_ppos1.isConnected(),"节点:{} 连接异常".format(node_data['host'])

        # 到达解锁期后处罚节点后锁仓账户
        CommonMethod.get_next_settlement_interval (self,1)
        Balance5 = platon_ppos.eth.getBalance (address2)
        log.info ("{}到达解锁期后处罚节点后预期账户余额:{}".format (address2,Balance4 + Web3.toWei (amount-(amount * 0.2), 'ether')))
        log.info ("{}到达解锁期后处罚节点后实际账户余额:{}".format (address2,Balance5))
        result = platon_ppos.getCandidateInfo(nodeId)
        assert Balance5 == Balance4 + Web3.toWei (amount-(amount * 0.2), 'ether'), "锁仓账户金额:{} 有误".format (Balance4)
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == 0, "锁仓计划可用金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == True, "欠释放状态:{} 有误".format (dict_Info['symbol'])
        assert dict_Info['debt'] == Web3.toWei (amount-(amount * 0.2), 'ether'), "欠释放锁仓金额:{} 有误".format (dict_Info['debt'])


    def test_eliminated_verifier_create_lockup(self):
        '''
        验证人违规被剔除验证人列表,申请质押节点
        :return:
        '''
        nodeId = CommonMethod.get_no_candidate_list (self)
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()

        # 签名转账
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)

        balance = platon_ppos.eth.getBalance (address1)
        log.info ("{}发起锁仓账户余额:{}".format (address1,balance))

        # 创建锁仓计划
        lockupamoutn = 900
        loukupbalace = Web3.toWei (lockupamoutn, 'ether')
        plan = [{'Epoch': 5, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address1, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回的状态:{},用例失败".format (result['Status'])
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address1)
        assert RestrictingInfo['Status'] == True, "查询锁仓计划返回的状态:{},用例失败".format (result['Status'])

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 200
        result = platon_ppos.createStaking (1, address1, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key1, from_address=address1,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == True, "申请质押返回的状态:{},{},用例失败".format (result['Status'], result['ErrMsg'])
        result = platon_ppos.getCandidateInfo(nodeId)
        log.info("质押节点信息:{}".format(result))

        # 等待成为共识验证人
        CommonMethod.get_next_settlement_interval (self)
        CandidateInfo = platon_ppos.getCandidateInfo(nodeId)
        log.info("验证人信息{}".format(CandidateInfo))
        VerifierList = platon_ppos.getVerifierList ()
        log.info ("当前验证人列表:{}".format (VerifierList))
        ValidatorList = platon_ppos.getValidatorList()
        log.info("当前共识验证人列表:{}".format(ValidatorList))



        # for dictinfo in CandidateInfo['Data']:
        #     if nodeId == dictinfo['NodeId']:
        #         log.info("节点id:{}已成为共识验证人".format(nodeId))
        #         break
        #     else:
        #         log.info("节点id:{}未成为共识验证人".format(nodeId))
        #         status=0
        #         assert status == 1

        # 获取节点内置质押节点信息
        con_node, no_node = get_node_list (self.node_yml_path)
        nodes = con_node + no_node
        for node in nodes:
            if nodeId in node.values ():
                node_data = node

        # 停止其中一个正在出块的节点信息
        self.auto = AutoDeployPlaton ()
        self.auto.kill (node_data)
        platon_ppos1 = connect_web3 (node_data['url'])
        assert not platon_ppos1.isConnected (), "节点:{} 连接异常".format (node_data['host'])

        # 等待节点被剔除验证人列表
        CommonMethod.get_next_consensus_wheel (self,2)

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 200
        result = platon_ppos.createStaking (1, address1, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key1, from_address=address1,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == False, "申请质押返回的状态:{},用例失败".format (result['Status'])

    def test_owe_amountstack_lock_plan(self):
        '''
        到达解锁时间点,如果账户锁仓不足再新增新的锁仓计划
        :return:
        '''
        nodeId = CommonMethod.get_no_candidate_list (self)
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()
        address2, private_key2 = CommonMethod.read_private_key_list ()

        # 签名转账
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)

        # 创建锁仓计划
        lockupamoutn = 500
        loukupbalace = Web3.toWei (lockupamoutn, 'ether')
        plan = [{'Epoch': 1, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address2, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回的状态:{},用例失败".format (result['Status'])
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "查询锁仓计划返回的状态:{},用例失败".format (result['Status'])

        # 给锁仓账号转手续费
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address2),
                                                   self.base_gas_price, self.base_gas, self.value,
                                                   self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)
        balance = platon_ppos.eth.getBalance(address2)
        log.info("锁仓账户余额:{}".format(balance))

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 500
        result = platon_ppos.createStaking (1, address2, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key2, from_address=address2,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == True, "申请质押返回的状态:{},{},用例失败".format (result['Status'], result['ErrMsg'])

        #到达解锁期释放锁仓金额
        CommonMethod.get_next_settlement_interval (self)
        platon_ppos.GetRestrictingInfo(address2)
        balance = platon_ppos.eth.getBalance(address2)
        log.info("到达解锁期释放锁仓余额:{}".format(balance))

        # 创建锁仓计划
        lockupamoutn = 100
        loukupbalace = Web3.toWei (lockupamoutn, 'ether')
        plan = [{'Epoch': 1, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address2, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回的状态:{},用例失败".format (result['Status'])
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "查询锁仓计划返回的状态:{},用例失败".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == Web3.toWei (100, 'ether'), "锁仓金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == True, "锁仓的状态:{} 有误".format (dict_Info['symbol'])
        assert dict_Info['debt'] == Web3.toWei (500, 'ether'), "欠释放锁仓金额:{} 有误".format (dict_Info['debt'])



    def testss(self):
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        while 1:
            block = platon_ppos.eth.blockNumber
            print(block)
예제 #26
0
class TestUndelegate():
    node_yml_path = conf.NODE_YML
    node_info = get_node_info(node_yml_path)
    rpc_list, enode_list, nodeid_list, ip_list, port_list = node_info.get(
        'collusion')
    rpc_list2, enode_list2, nodeid_list2, ip_list2, port_list2 = node_info.get(
        'nocollusion')

    address = Web3.toChecksumAddress(conf.ADDRESS)
    privatekey = conf.PRIVATE_KEY
    account_list = conf.account_list
    privatekey_list = conf.privatekey_list
    externalId = "1111111111"
    nodeName = "platon"
    website = "https://www.test.network"
    details = "supper node"
    programVersion = 1792
    illegal_nodeID = conf.illegal_nodeID

    genesis_path = conf.GENESIS_TMP
    """替换config.json"""
    get_config_data()
    config_json_path = conf.PLATON_CONFIG_PATH
    config_dict = LoadFile(config_json_path).get_data()
    amount_delegate = Web3.fromWei(
        int(config_dict['EconomicModel']['Staking']['MinimumThreshold']),
        'ether')
    amount = Web3.fromWei(
        int(config_dict['EconomicModel']['Staking']['StakeThreshold']),
        'ether')

    def setup_class(self):
        self.auto = AutoDeployPlaton()
        self.auto.start_all_node(self.node_yml_path)
        self.genesis_dict = LoadFile(self.genesis_path).get_data()
        self.chainid = int(self.genesis_dict["config"]["chainId"])
        self.ppos_link = Ppos(self.rpc_list[0], self.address, self.chainid)
        self.w3_list = [connect_web3(url) for url in self.rpc_list]
        """用新的钱包地址和未质押过的节点id封装对象"""
        self.ppos_noconsensus_1 = Ppos(self.rpc_list[0],
                                       self.account_list[0],
                                       self.chainid,
                                       privatekey=self.privatekey_list[0])
        self.ppos_noconsensus_2 = Ppos(self.rpc_list[0],
                                       self.account_list[1],
                                       self.chainid,
                                       privatekey=self.privatekey_list[1])
        self.ppos_noconsensus_3 = Ppos(self.rpc_list[0],
                                       self.account_list[2],
                                       self.chainid,
                                       privatekey=self.privatekey_list[2])
        self.ppos_noconsensus_4 = Ppos(self.rpc_list[0],
                                       self.account_list[3],
                                       self.chainid,
                                       privatekey=self.privatekey_list[3])
        self.ppos_noconsensus_5 = Ppos(self.rpc_list[0],
                                       self.account_list[4],
                                       self.chainid,
                                       privatekey=self.privatekey_list[4])
        self.ppos_noconsensus_6 = Ppos(self.rpc_list[0],
                                       self.account_list[5],
                                       self.chainid,
                                       privatekey=self.privatekey_list[5])
        self.eth = Eth(self.w3_list[0])

    def transaction(self,
                    w3,
                    from_address,
                    to_address=None,
                    value=1000000000000000000000000000000000,
                    gas=91000000,
                    gasPrice=9000000000,
                    pwd=conf.PASSWORD):
        """"
        转账公共方法
        """
        personal = Personal(w3)
        personal.unlockAccount(from_address, pwd, 666666)
        params = {
            'to': to_address,
            'from': from_address,
            'gas': gas,
            'gasPrice': gasPrice,
            'value': value
        }
        tx_hash = w3.eth.sendTransaction(params)
        result = w3.eth.waitForTransactionReceipt(HexBytes(tx_hash).hex())
        return result

    def getCandidateList(self):
        """
        获取实时验证人的nodeID list
        """
        msg = self.ppos_noconsensus_1.getCandidateList()
        recive_list = msg.get("Data")
        nodeid_list = []
        if recive_list is None:
            return recive_list
        else:
            for node_info in recive_list:
                nodeid_list.append(node_info.get("NodeId"))
        return nodeid_list

##############################赎回####################################################

    @allure.title("委托人未达到锁定期申请赎回")
    @pytest.mark.P0
    def test_unDelegate_part(self):
        """
         用例id 106 申请赎回委托
         用例id 111 委托人未达到锁定期申请赎回
         申请部分赎回
        """
        log.info("转账到钱包3")
        self.transaction(self.w3_list[0],
                         self.address,
                         to_address=self.account_list[2])
        log.info("转账到钱包4")
        self.transaction(self.w3_list[0],
                         self.address,
                         to_address=self.account_list[3])
        msg = self.ppos_noconsensus_1.getCandidateInfo(self.nodeid_list2[2])
        if msg['Data'] == "":
            log.info("质押节点3:{}成为验证节点".format(self.nodeid_list2[2]))
            self.ppos_noconsensus_3.createStaking(0, self.account_list[2],
                                                  self.nodeid_list2[2],
                                                  self.externalId,
                                                  self.nodeName, self.website,
                                                  self.details, self.amount,
                                                  self.programVersion)
        log.info("钱包4 {}委托到3 {}".format(self.account_list[3],
                                        self.account_list[2]))
        value = 100
        self.ppos_noconsensus_4.delegate(0, self.nodeid_list2[2], value)
        log.info("查询当前节点质押信息")
        msg = self.ppos_noconsensus_3.getCandidateInfo(self.nodeid_list2[2])
        stakingBlockNum = msg["Data"]["StakingBlockNum"]
        log.info("发起质押的区高{}".format(stakingBlockNum))
        delegate_value = 20
        self.ppos_noconsensus_4.unDelegate(stakingBlockNum,
                                           self.nodeid_list2[2],
                                           delegate_value)
        log.info("查询钱包{}的委托信息".format(self.account_list[3]))
        msg = self.ppos_noconsensus_4.getDelegateInfo(stakingBlockNum,
                                                      self.account_list[3],
                                                      self.nodeid_list2[2])
        print(msg)
        data = msg["Data"]
        """不清楚msg["Data"]对应value是str类型,需要再转字典"""
        data = json.loads(data)
        print(data)
        assert Web3.toChecksumAddress(data["Addr"]) == self.account_list[3]
        assert data["NodeId"] == self.nodeid_list2[2]
        print(data["ReleasedHes"])
        value = value - delegate_value
        result_value = Web3.toWei(value, "ether")
        assert data["ReleasedHes"] == result_value

    @allure.title("大于委托金额赎回")
    @pytest.mark.P0
    def test_unDelegate_iff(self):
        """
        验证 大于委托金额赎回
        """
        msg = self.ppos_noconsensus_1.getCandidateInfo(self.nodeid_list2[2])
        if msg['Data'] == "":
            log.info("质押节点3成为验证节点")
            self.ppos_noconsensus_3.createStaking(0, self.account_list[2],
                                                  self.nodeid_list2[2],
                                                  self.externalId,
                                                  self.nodeName, self.website,
                                                  self.details, self.amount,
                                                  self.programVersion)
        log.info("钱包4 委托到3 {}")
        value = 100
        self.ppos_noconsensus_4.delegate(0, self.nodeid_list2[2], value)
        msg = self.ppos_noconsensus_3.getCandidateInfo(self.nodeid_list2[2])
        stakingBlockNum = msg["Data"]["StakingBlockNum"]
        msg = self.ppos_noconsensus_4.getDelegateInfo(stakingBlockNum,
                                                      self.account_list[3],
                                                      self.nodeid_list2[2])
        data = msg["Data"]
        """不清楚msg["Data"]对应value是str类型,需要再转字典"""
        data = json.loads(data)
        releasedHes = data["ReleasedHes"]
        releasedHes = Web3.fromWei(releasedHes, 'ether')
        log.info("委托钱包可赎回的金额单位eth:{}".format(releasedHes))
        delegate_value = releasedHes + 20
        msg = self.ppos_noconsensus_4.unDelegate(stakingBlockNum,
                                                 self.nodeid_list2[2],
                                                 delegate_value)
        assert msg["Status"] == False
        err_msg = "withdrewDelegate err: The von of delegate is not enough"
        assert err_msg in msg["ErrMsg"]

    @allure.title("赎回全部委托的金额与赎回金额为0")
    @pytest.mark.P1
    def test_unDelegate_all(self):
        """
        验证 赎回全部委托的金额
        验证 赎回金额为0
        """
        log.info("转账到钱包1")
        self.transaction(self.w3_list[0],
                         self.address,
                         to_address=self.account_list[0])
        log.info("转账到钱包2")
        self.transaction(self.w3_list[0],
                         self.address,
                         to_address=self.account_list[1])

        log.info("节点1质押成为验证人")
        self.ppos_noconsensus_1.createStaking(0, self.account_list[0],
                                              self.nodeid_list2[0],
                                              self.externalId, self.nodeName,
                                              self.website, self.details,
                                              self.amount, self.programVersion)

        msg = self.ppos_noconsensus_1.getCandidateInfo(self.nodeid_list2[0])
        stakingBlockNum = msg["Data"]["StakingBlockNum"]
        log.info("查询节点质押信息,质押块高{}".format(stakingBlockNum))
        log.info("钱包2进行委托")
        value = 80
        self.ppos_noconsensus_2.delegate(0, self.nodeid_list2[0], value)
        msg = self.ppos_noconsensus_2.getDelegateInfo(stakingBlockNum,
                                                      self.account_list[1],
                                                      self.nodeid_list2[0])
        data = msg["Data"]
        """不清楚msg["Data"]对应value是str类型,需要再转字典"""
        data = json.loads(data)
        log.info(data)
        releasedHes = data["ReleasedHes"]
        releasedHes = Web3.fromWei(releasedHes, 'ether')
        log.info("委托钱包可赎回的金额单位eth:{}".format(releasedHes))
        account_before = self.eth.getBalance(self.account_list[1])
        msg = self.ppos_noconsensus_2.unDelegate(stakingBlockNum,
                                                 self.nodeid_list2[0],
                                                 releasedHes)
        assert msg["Status"] == True
        account_after = self.eth.getBalance(self.account_list[1])
        result_value = account_after - account_before
        ##为什么会赎回多那么多钱?1000000000000159999910972325109760
        assert account_before + data["ReleasedHes"] > account_after
        assert 70 < Web3.fromWei(result_value,
                                 "ether") < releasedHes, "赎回的金额减去gas应在这范围"
        log.info("全部委托金额赎回后,查询委托金额".format(account_after))
        msg = self.ppos_noconsensus_2.getDelegateInfo(stakingBlockNum,
                                                      self.account_list[1],
                                                      self.nodeid_list2[0])
        log.info(msg)
        """如果全部金额赎回,再查getDelegateInfo返回数据为空"""
        assert msg["Status"] == False
        assert msg["ErrMsg"] == "Delegate info is not found"

    @allure.title("多次委托,多次赎回")
    @pytest.mark.P1
    def test_multiple_delegate_undelegate(self):
        """
        验证多次委托,多次赎回
        """
        log.info("转账到钱包5")
        self.transaction(self.w3_list[0],
                         self.address,
                         to_address=self.account_list[4])
        log.info("转账到钱包6")
        self.transaction(self.w3_list[0],
                         self.address,
                         to_address=self.account_list[5])
        msg = self.ppos_noconsensus_5.getCandidateInfo(self.nodeid_list2[4])
        if msg['Data'] == "":
            log.info("质押节点5成为验证节点")
            self.ppos_noconsensus_5.createStaking(0, self.account_list[4],
                                                  self.nodeid_list2[4],
                                                  self.externalId,
                                                  self.nodeName, self.website,
                                                  self.details, self.amount,
                                                  self.programVersion)
        msg = self.ppos_noconsensus_5.getCandidateInfo(self.nodeid_list2[4])
        stakingBlockNum = msg["Data"]["StakingBlockNum"]
        log.info("查询节点质押信息回去质押块高{}".format(stakingBlockNum))
        value_list = [10, 11, 12, 13, 14, 15, 16, 17, 18]
        for value in value_list:
            log.info("钱包6 委托金额{}".format(value))
            self.ppos_noconsensus_6.delegate(0, self.nodeid_list2[4], value)
        msg = self.ppos_noconsensus_6.getDelegateInfo(stakingBlockNum,
                                                      self.account_list[5],
                                                      self.nodeid_list2[4])
        log.info(msg)
        data = json.loads(msg["Data"])
        releasedHes = Web3.fromWei(data["ReleasedHes"], 'ether')
        log.info("查询委托的金额{}eth".format(releasedHes))
        delegate_value = 0
        for i in value_list:
            delegate_value = i + delegate_value
        assert delegate_value == releasedHes, "委托的金额与查询到的金额不一致"
        for value in value_list:
            log.info("赎回的金额:{}eth".format(value))
            log.info("钱包6进行赎回")
            self.ppos_noconsensus_6.unDelegate(stakingBlockNum,
                                               self.nodeid_list2[4], value)
        log.info("赎回委托金额后查询委托信息")
        msg = self.ppos_noconsensus_6.getDelegateInfo(stakingBlockNum,
                                                      self.account_list[5],
                                                      self.nodeid_list2[4])
        """如果全部金额赎回,再查getDelegateInfo返回数据为空"""
        log.info(msg)
    def test_unlock_point_pledge_punish_amount(self):
        '''
        到达解锁期后处罚节点后锁仓账户的余额情况
        :return:
        '''
        nodeId = CommonMethod.get_no_candidate_list (self)
        log.info("质押节点ID:{}".format(nodeId))
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()
        address2, private_key2 = CommonMethod.read_private_key_list ()

        # 给发起锁仓账户转手续费
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)

        # 给发起质押账号转手续费
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address2),
                                                   self.base_gas_price, self.base_gas, self.value,
                                                   self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)

        Balance = platon_ppos.eth.getBalance (address1)
        log.info ("{}账户余额:{}".format (address1, Balance))
        Balance1 = platon_ppos.eth.getBalance (address1)
        log.info ("{}账号余额:{}".format (address2, Balance1))

        # 创建锁仓计划
        lockupamoutn = 900
        loukupbalace = Web3.toWei (lockupamoutn, 'ether')
        plan = [{'Epoch': 3, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address2, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回的状态:{},用例失败".format (result['Status'])
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "查询锁仓计划返回的状态:{},用例失败".format (result['Status'])
        Balance2 = platon_ppos.eth.getBalance (address1)
        log.info ("{}发起锁仓后账户余额:{}".format (address1, Balance2))

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 900
        result = platon_ppos.createStaking (1, address2, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key2, from_address=address2,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == True, "申请质押返回的状态:{},{},用例失败".format (result['Status'], result['ErrMsg'])
        platon_ppos.GetRestrictingInfo(address2)
        result = platon_ppos.getCandidateInfo(nodeId)
        assert result['Status'] == True, "获取质押节点返回状态为:{} 有误".format (result['Status'])
        RestrictingPlan = result['Data']['RestrictingPlanHes']
        assert RestrictingPlan == Web3.toWei (amount, 'ether'),'质押金额:{} 有误'.format(RestrictingPlan)
        Balance3 = platon_ppos.eth.getBalance (address2)
        log.info ("{}质押完锁仓账户余额:{}".format (address2,Balance3))

        #等待验证人加入共识出块节点
        CommonMethod.get_next_settlement_interval (self,1)
        Balance4 = platon_ppos.eth.getBalance (address2)
        log.info ("{}加入共识验证人后账户余额:{}".format (address2, Balance4))

        # 获取节点内置质押节点信息
        con_node, no_node = get_node_list (self.node_yml_path)
        nodes = con_node + no_node
        for node in nodes:
            if nodeId in node.values ():
                node_data = node
        log.info("{}质押节点信息:{}".format(address2,node_data))

        #停止质押节点
        self.auto = AutoDeployPlaton ()
        self.auto.kill (node_data)
        platon_ppos1 = connect_web3 (node_data['url'])
        assert not platon_ppos1.isConnected(),"节点:{} 连接异常".format(node_data['host'])

        # 到达解锁期后处罚节点后锁仓账户
        CommonMethod.get_next_settlement_interval (self,1)
        Balance5 = platon_ppos.eth.getBalance (address2)
        log.info ("{}到达解锁期后处罚节点后预期账户余额:{}".format (address2,Balance4 + Web3.toWei (amount-(amount * 0.2), 'ether')))
        log.info ("{}到达解锁期后处罚节点后实际账户余额:{}".format (address2,Balance5))
        result = platon_ppos.getCandidateInfo(nodeId)
        assert Balance5 == Balance4 + Web3.toWei (amount-(amount * 0.2), 'ether'), "锁仓账户金额:{} 有误".format (Balance4)
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address2)
        assert RestrictingInfo['Status'] == True, "获取锁仓计划返回状态为:{} 有误".format (result['Status'])
        dict_Info = json.loads (RestrictingInfo['Data'])
        assert dict_Info['balance'] == 0, "锁仓计划可用金额:{}有误".format (dict_Info['balance'])
        assert dict_Info['symbol'] == True, "欠释放状态:{} 有误".format (dict_Info['symbol'])
        assert dict_Info['debt'] == Web3.toWei (amount-(amount * 0.2), 'ether'), "欠释放锁仓金额:{} 有误".format (dict_Info['debt'])
예제 #28
0
    def test_block_cycle_duration(self, period, duration, delay_time, number):
        '''
        用例id 6,7,8,9,10
        测试duration的不同值,观察出块周期
        根据5种场景,出块周期约为10,20,30,50,100
        '''
        self.get_cbft_json_data(period, duration)
        auto = AutoDeployPlaton(cbft=self.cbft_path)
        log.info("上传cbft文件成功")
        auto.start_all_node(self.node_yml)
        time.sleep(delay_time)
        log.info("跟所有节点建立连接")
        w3_list = [connect_web3(url) for url in self.url_list]
        w3 = w3_list[0]
        block_number = w3.eth.blockNumber
        if block_number > 0:
            log.info("正在出块,块高:{}".format(block_number))
        if block_number < number:
            raise Exception("出块很慢,没达到预期{}".format(number))
        node_id_dict = {}
        log.info("获取1至{}块的nodeID".format(number))
        for block in range(1, number):
            node_id = get_pub_key(self.url_list[0], block)
            if node_id not in node_id_dict.keys():
                node_id_dict[node_id] = [block]
            else:
                node_id_dict[node_id].append(block)
        log.info("获取到全部的nodeID对应的出块".format(node_id_dict))
        log.info("由于第一组nodeID收集数据不全,从第二组开始收集统计,删除第一组")
        node_id_list = []
        for node_id in node_id_dict.keys():
            node_id_list.append(node_id)
        node_id_dict.pop(node_id_list[0])
        log.info("统计出nodeID对应的出块ID{}".format(node_id_dict))
        print(node_id_dict)
        print(node_id_list)
        if duration == 10:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 7 <= len(block_cycle_a) <= 12, "出块周期预期在7到12,实际{}".format(
                len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 7 <= len(block_cycle_b) <= 12, "出块周期预期在7到12,实际{}".format(
                len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 8000 < times_tamp_b - \
                times_tamp_a < 12000, "预期出块周期为8到12s,实际为{}".format(
                    times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

        if duration == 20:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 16 <= len(block_cycle_a) <= 23, "出块周期预期在16到23,实际{}".format(
                len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 16 <= len(block_cycle_b) <= 23, "出块周期预期在16到23,实际{}".format(
                len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 16000 < times_tamp_b - times_tamp_a < 23000, "预期出块周期为16到23s,实际为{}".format(
                times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

        if duration == 30:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 26 <= len(block_cycle_a) <= 33, "出块周期预期在26到33,实际{}".format(
                len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 26 <= len(block_cycle_b) <= 33, "出块周期预期在26到33,实际{}".format(
                len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 26000 < times_tamp_b - times_tamp_a < 33000, "预期出块周期为26到30s,实际为{}".format(
                times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

        if duration == 50:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 40 <= len(block_cycle_a) <= 60, "出块周期预期在40到60,实际{}".format(
                len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 40 <= len(block_cycle_b) <= 60, "出块周期预期在40到60,实际{}".format(
                len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 4000 < times_tamp_b - times_tamp_a < 60000, "预期出块周期为40到60s,实际为{}".format(
                times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

        if duration == 100:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 90 <= len(
                block_cycle_a) <= 110, "出块周期预期在90到110,实际{}".format(
                    len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 90 <= len(
                block_cycle_b) <= 110, "出块周期预期在90到110,实际{}".format(
                    len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 90000 < times_tamp_b - times_tamp_a < 110000, "预期出块周期为99到110s,实际为{}".format(
                times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))
    def test_eliminated_verifier_create_lockup(self):
        '''
        验证人违规被剔除验证人列表,申请质押节点
        :return:
        '''
        nodeId = CommonMethod.get_no_candidate_list (self)
        url = CommonMethod.link_list (self)
        platon_ppos = Ppos (url, self.address, self.chainid)
        address1, private_key1 = CommonMethod.read_private_key_list ()

        # 签名转账
        result = platon_ppos.send_raw_transaction ('', Web3.toChecksumAddress (self.address),
                                                   Web3.toChecksumAddress (address1),
                                                   self.base_gas_price, self.base_gas, self.value, self.privatekey)
        return_info = platon_ppos.eth.waitForTransactionReceipt (result)
        assert return_info is not None, "转账:{}失败".format (self.value)

        balance = platon_ppos.eth.getBalance (address1)
        log.info ("{}发起锁仓账户余额:{}".format (address1,balance))

        # 创建锁仓计划
        lockupamoutn = 900
        loukupbalace = Web3.toWei (lockupamoutn, 'ether')
        plan = [{'Epoch': 5, 'Amount': loukupbalace}]
        result = platon_ppos.CreateRestrictingPlan (address1, plan, privatekey=private_key1,
                                                    from_address=address1, gasPrice=self.base_gas_price,
                                                    gas=self.staking_gas)
        assert result['Status'] == True, "创建锁仓计划返回的状态:{},用例失败".format (result['Status'])
        RestrictingInfo = platon_ppos.GetRestrictingInfo (address1)
        assert RestrictingInfo['Status'] == True, "查询锁仓计划返回的状态:{},用例失败".format (result['Status'])

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 200
        result = platon_ppos.createStaking (1, address1, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key1, from_address=address1,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == True, "申请质押返回的状态:{},{},用例失败".format (result['Status'], result['ErrMsg'])
        result = platon_ppos.getCandidateInfo(nodeId)
        log.info("质押节点信息:{}".format(result))

        # 等待成为共识验证人
        CommonMethod.get_next_settlement_interval (self)
        CandidateInfo = platon_ppos.getCandidateInfo(nodeId)
        log.info("验证人信息{}".format(CandidateInfo))
        VerifierList = platon_ppos.getVerifierList ()
        log.info ("当前验证人列表:{}".format (VerifierList))
        ValidatorList = platon_ppos.getValidatorList()
        log.info("当前共识验证人列表:{}".format(ValidatorList))



        # for dictinfo in CandidateInfo['Data']:
        #     if nodeId == dictinfo['NodeId']:
        #         log.info("节点id:{}已成为共识验证人".format(nodeId))
        #         break
        #     else:
        #         log.info("节点id:{}未成为共识验证人".format(nodeId))
        #         status=0
        #         assert status == 1

        # 获取节点内置质押节点信息
        con_node, no_node = get_node_list (self.node_yml_path)
        nodes = con_node + no_node
        for node in nodes:
            if nodeId in node.values ():
                node_data = node

        # 停止其中一个正在出块的节点信息
        self.auto = AutoDeployPlaton ()
        self.auto.kill (node_data)
        platon_ppos1 = connect_web3 (node_data['url'])
        assert not platon_ppos1.isConnected (), "节点:{} 连接异常".format (node_data['host'])

        # 等待节点被剔除验证人列表
        CommonMethod.get_next_consensus_wheel (self,2)

        # 申请质押节点
        version = get_version (platon_ppos)
        amount = 200
        result = platon_ppos.createStaking (1, address1, nodeId, 'externalId', 'nodeName', 'website', 'details',
                                            amount, version, privatekey=private_key1, from_address=address1,
                                            gasPrice=self.base_gas_price, gas=self.staking_gas)
        assert result['Status'] == False, "申请质押返回的状态:{},用例失败".format (result['Status'])
예제 #30
0
class TestConsensus:
    node_yml = conf.NODE_YML
    consensus_list, _ = get_node_list(node_yml)
    f = get_f(consensus_list)
    n = len(consensus_list)
    url_list, enode_list, nodeid_list, ip_list, _ = get_node_info(
        node_yml)["collusion"]
    genesis_path = conf.GENESIS_TMP
    auto = AutoDeployPlaton()
    cbft_path = conf.CBFT_TMP
    cbft_template = conf.CBFT_TEMPLATE

    def teardown_class(self):
        self.auto.start_all_node(self.node_yml)

    def get_cbft_json_data(self, period, duration):
        with open(self.cbft_template, 'r', encoding='utf-8') as f:
            res = json.loads(f.read())
            res['period'] = period
            res['duration'] = duration
        with open(self.cbft_path, 'w', encoding='utf-8') as b:
            cbft_json = json.dumps(res)
            b.write(cbft_json)

    @allure.title("每个节点在窗口期正常出块")
    def test_block_out_of_each_node_window(self):
        """
        用例id:73
        测试 N 个节点每个窗口期都在出块
        """
        log.info("更新cbft文件")
        self.get_cbft_json_data(period=1, duration=10)
        auto = AutoDeployPlaton(cbft=self.cbft_path)
        auto.start_all_node(self.node_yml)
        log.info("跟所有节点建立连接")
        w3_list = [connect_web3(url) for url in self.url_list]
        w3 = w3_list[0]
        start_block = w3.eth.blockNumber
        time.sleep(self.n * 10 + 5)
        block_number = w3.eth.blockNumber
        if block_number > 0:
            log.info("正在出块,块高:{}".format(block_number))
        node_id_dict = {}
        log.info("获取1至{}块的nodeID".format(block_number))
        for block in range(start_block, block_number + 1):
            node_id = get_pub_key(self.url_list[0], block)
            if node_id not in node_id_dict.keys():
                node_id_dict[node_id] = 1
            else:
                node_id_dict[node_id] += 1
        log.info("nodeID对应的出块数{}".format(node_id_dict))
        assert self.n == len(node_id_dict), "出块节点数少于共识节点数"
        for k, v in node_id_dict.items():
            assert 0 <= v <= 20, "节点{}出块周期约为10个块,实际为{}".format(k, v)

    @allure.title("cbft.json配置period{period}-{duration}")
    @pytest.mark.parametrize('period,duration', [(1, 10), (3, 30), (5, 50),
                                                 (10, 100), (0, 10)])
    def test_block_time_period(self, period, duration):
        '''
        用例id 1,2,3,4,5
        测试period的不同值,观察查看时间
        根据5种场景,分别出块时间约为1,3,5,10,1s
        '''
        log.info("更新cbft.json")
        self.get_cbft_json_data(period, duration)
        auto = AutoDeployPlaton(cbft=self.cbft_path)
        auto.start_all_node(self.node_yml)
        time.sleep(duration + 5)
        log.info("跟所有节点建立连接")
        w3_list = [connect_web3(url) for url in self.url_list]
        w3 = w3_list[0]
        block_number = w3.eth.blockNumber
        assert block_number > 1, "没有正常出块"
        log.info(block_number)
        start_time = w3.eth.getBlock(1).get("timestamp")
        end_time = w3.eth.getBlock(block_number).get("timestamp")
        use_time = end_time - start_time
        average_time = int(use_time / (block_number - 1))
        log.info("平均出块时间{}".format(average_time))
        if period == 0:
            period = 1
        deviation = int(period * 1000 * 0.5)
        assert period * 1000 - deviation < average_time < period * \
            1000 + deviation, "出块间隔过大或过小"

    @allure.title("cbft.json配置period{period}-{duration}-{delay_time}--{number}"
                  )
    @pytest.mark.parametrize('period,duration,delay_time,number',
                             [(1, 10, 50, 30), (1, 20, 90, 70),
                              (1, 30, 130, 90), (1, 50, 180, 140),
                              (1, 100, 350, 250)])
    def test_block_cycle_duration(self, period, duration, delay_time, number):
        '''
        用例id 6,7,8,9,10
        测试duration的不同值,观察出块周期
        根据5种场景,出块周期约为10,20,30,50,100
        '''
        self.get_cbft_json_data(period, duration)
        auto = AutoDeployPlaton(cbft=self.cbft_path)
        log.info("上传cbft文件成功")
        auto.start_all_node(self.node_yml)
        time.sleep(delay_time)
        log.info("跟所有节点建立连接")
        w3_list = [connect_web3(url) for url in self.url_list]
        w3 = w3_list[0]
        block_number = w3.eth.blockNumber
        if block_number > 0:
            log.info("正在出块,块高:{}".format(block_number))
        if block_number < number:
            raise Exception("出块很慢,没达到预期{}".format(number))
        node_id_dict = {}
        log.info("获取1至{}块的nodeID".format(number))
        for block in range(1, number):
            node_id = get_pub_key(self.url_list[0], block)
            if node_id not in node_id_dict.keys():
                node_id_dict[node_id] = [block]
            else:
                node_id_dict[node_id].append(block)
        log.info("获取到全部的nodeID对应的出块".format(node_id_dict))
        log.info("由于第一组nodeID收集数据不全,从第二组开始收集统计,删除第一组")
        node_id_list = []
        for node_id in node_id_dict.keys():
            node_id_list.append(node_id)
        node_id_dict.pop(node_id_list[0])
        log.info("统计出nodeID对应的出块ID{}".format(node_id_dict))
        print(node_id_dict)
        print(node_id_list)
        if duration == 10:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 7 <= len(block_cycle_a) <= 12, "出块周期预期在7到12,实际{}".format(
                len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 7 <= len(block_cycle_b) <= 12, "出块周期预期在7到12,实际{}".format(
                len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 8000 < times_tamp_b - \
                times_tamp_a < 12000, "预期出块周期为8到12s,实际为{}".format(
                    times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

        if duration == 20:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 16 <= len(block_cycle_a) <= 23, "出块周期预期在16到23,实际{}".format(
                len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 16 <= len(block_cycle_b) <= 23, "出块周期预期在16到23,实际{}".format(
                len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 16000 < times_tamp_b - times_tamp_a < 23000, "预期出块周期为16到23s,实际为{}".format(
                times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

        if duration == 30:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 26 <= len(block_cycle_a) <= 33, "出块周期预期在26到33,实际{}".format(
                len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 26 <= len(block_cycle_b) <= 33, "出块周期预期在26到33,实际{}".format(
                len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 26000 < times_tamp_b - times_tamp_a < 33000, "预期出块周期为26到30s,实际为{}".format(
                times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

        if duration == 50:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 40 <= len(block_cycle_a) <= 60, "出块周期预期在40到60,实际{}".format(
                len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 40 <= len(block_cycle_b) <= 60, "出块周期预期在40到60,实际{}".format(
                len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 4000 < times_tamp_b - times_tamp_a < 60000, "预期出块周期为40到60s,实际为{}".format(
                times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

        if duration == 100:
            block_cycle_a = node_id_dict.get(node_id_list[1])
            log.info("出块人A出块周期数:%s" % block_cycle_a)
            assert 90 <= len(
                block_cycle_a) <= 110, "出块周期预期在90到110,实际{}".format(
                    len(block_cycle_a))
            block_cycle_b = node_id_dict.get(node_id_list[2])
            log.info("出块人B出块周期数:%s" % block_cycle_b)
            assert 90 <= len(
                block_cycle_b) <= 110, "出块周期预期在90到110,实际{}".format(
                    len(block_cycle_b))
            times_tamp_a = w3.eth.getBlock(block_cycle_a[-1]).get("timestamp")
            times_tamp_b = w3.eth.getBlock(block_cycle_b[-1]).get("timestamp")
            log.info("获取出块人B的最后一个块的时间戳%s" % times_tamp_b)
            assert 90000 < times_tamp_b - times_tamp_a < 110000, "预期出块周期为99到110s,实际为{}".format(
                times_tamp_b - times_tamp_a)
            log.info(
                "出块人B最后一个块出块时间-出块人A最后一个块出块时间 = 出块周期时间{}".format(times_tamp_b -
                                                                times_tamp_a))

    @allure.title("重启节点后查看旧块交易,钱包余额")
    def test_kill_process_observation_block_data(self):
        '''
       用例id 30,31,32,33
       测试kill进程后,重启查看块高持续增长
       测试kill进程后,重启查看旧块转账,合约信息不变
       测试kill进程后,钱包余额不变
        '''
        log.info("部署节点")
        self.auto.start_all_node(self.node_yml)
        log.info("启动会等待60s出块")
        time.sleep(10)
        log.info("跟所有节点建立连接")
        w3_list = [connect_web3(url) for url in self.url_list]
        w3 = w3_list[0]
        number_before = w3.eth.blockNumber
        if number_before == 0:
            raise Exception("起服务但未出块")
        log.info("块高为:{}".format(number_before))
        log.info("发起转账交易")
        t_hash = self.transaction(w3)
        result, number, result_block, hash_list = self.check_block_information(
            w3, t_hash)
        log.info("发起合约交易")
        contract_address, resp, contract_number = self.deploy_contract()
        log.info("kill 所有节点")
        self.auto.kill_of_yaml(self.node_yml)
        time.sleep(2)
        log.info("重启platon服务")
        self.auto.start_all_node(self.node_yml, is_need_init=False)
        log.info("重启25节点后,延迟30s")
        time.sleep(30)
        w3_list = [connect_web3(url) for url in self.url_list]
        w3 = w3_list[0]
        number_after = w3.eth.blockNumber
        assert number_after >= number_before, "块高未有增长"
        balance = w3.eth.getBalance(w3.eth.accounts[1])
        assert balance == 100000, "kill进程重启后余额发生变化,余额为:{}".format(balance)
        log.info("查看重启前的{}区块转账信息".format(number))
        t_hash_list = (w3.eth.getBlock(number).get("transactions"))
        log.info("查看重启前的{}区块合约信息".format(contract_number))
        c_hash_list = (w3.eth.getBlock(contract_number).get("transactions"))
        log.info("通过transactions字段得到的交易哈希列表:{}".format(hash_list))
        assert t_hash in t_hash_list, "kill进程重启后转账交易丢失"
        c_hash = HexBytes(resp)
        assert c_hash in c_hash_list, "kill进程重启后合约交易丢失"
        contract_address_after = w3.eth.waitForTransactionReceipt(resp).get(
            'contractAddress')
        assert contract_address == contract_address_after, "kill进程后,合约地址发生改变"

    def check_block_information(self, w3, hash):
        transaction_hash = HexBytes(hash).hex()
        result = w3.eth.waitForTransactionReceipt(transaction_hash)
        number = result.get("blockNumber")
        result_block = w3.eth.getBlock(number)
        hash_list = result_block.get("transactions")
        return result, number, result_block, hash_list

    def transaction(self, w3, value=100000):
        from_address = w3.toChecksumAddress(w3.eth.accounts[0])
        to_address = w3.toChecksumAddress(w3.personal.newAccount('88888888'))
        log.info("解锁账号")
        w3.personal.unlockAccount(from_address, '88888888', 666666)
        params = {
            'to': to_address,
            'from': from_address,
            'gas': 91000000,
            'gasPrice': 9000000000,
            'value': value
        }
        t_hash = w3.eth.sendTransaction(params)
        return t_hash

    def deploy_contract(self):
        consensus_list, _ = get_node_list(self.node_yml)
        url = consensus_list[0]['url']
        wt = PlatonContractTransaction(url)
        addrress = wt.w3.toChecksumAddress(conf.ADDRESS)
        wt.w3.personal.unlockAccount(addrress, conf.PASSWORD, 99999999)
        log.info("部署合约")
        resp = wt.contract_deploy(
            get_byte_code(abspath('./data/contract/sum.wasm')),
            get_abi_bytes(abspath('./data/contract/sum.cpp.abi.json')),
            addrress)
        log.info("获取合约交易信息")
        result = wt.eth.waitForTransactionReceipt(resp)
        contract_address = result['contractAddress']
        contract_number = result['blockNumber']
        return contract_address, resp, contract_number