github.com/platonnetwork/platon-go@v0.7.6/cases/tests/lib/utils.py (about) 1 # -*- coding: utf-8 -*- 2 import json 3 import time 4 import random 5 import string 6 from decimal import Decimal 7 8 from hexbytes import HexBytes 9 from environment.node import Node 10 from common.log import log 11 from common.key import get_pub_key 12 from typing import List 13 14 15 def decorator_sleep(func): 16 def wrap(): 17 result = func() 18 if result is None: 19 time.sleep(5) 20 result = func() 21 return result 22 return wrap 23 24 25 def find_proposal(proposal_list, block_number): 26 for proposal in proposal_list: 27 if proposal_effective(proposal, block_number): 28 return proposal 29 30 31 def proposal_list_effective(proposal_list, block_number): 32 """ 33 Determine if there is a proposal in the voting period 34 :param proposal_list: 35 :param block_number: 36 :return: 37 """ 38 for proposal in proposal_list: 39 if proposal_effective(proposal, block_number): 40 return True 41 return False 42 43 44 def proposal_effective(proposal, block_number): 45 """ 46 Determine if the proposal is in the voting period 47 :param proposal: 48 :param block_number: 49 :return: 50 """ 51 if proposal["EndVotingBlock"] > block_number: 52 return True 53 return False 54 55 56 def upload_platon(node: Node, platon_bin): 57 """ 58 Upload a binary file to the specified node 59 :param node: 60 :param platon_bin: 61 :return: 62 """ 63 node.run_ssh("rm -rf {}".format(node.remote_bin_file)) 64 node.upload_file(platon_bin, node.remote_bin_file) 65 node.run_ssh("chmod +x {}".format(node.remote_bin_file)) 66 node.run_ssh("mkdir zlp") 67 68 69 def get_blockhash(node, blocknumber=None): 70 """ 71 Get block hash based on block height 72 :param node: 73 :param blocknumber: 74 :return: 75 """ 76 if not blocknumber: 77 blocknumber = node.block_number 78 blockinfo = node.eth.getBlock(blocknumber) 79 blockhash = blockinfo.get('hash') 80 blockhash = HexBytes(blockhash).hex() 81 return blockhash 82 83 84 def int_to_bytes(value): 85 return int(value).to_bytes(length=4, byteorder='big', signed=False) 86 87 88 def int16_to_bytes(value): 89 return int(value).to_bytes(length=1, byteorder='big', signed=False) 90 91 92 def bytes_to_int(value): 93 return int.from_bytes(value, byteorder='big', signed=False) 94 95 96 def compare_two_dict(dict1, dict2, key_list=None): 97 """ 98 Compare two dictionary values 99 :param dict1: 100 :param dict2: 101 :param key_list: Align dictionary key list 102 :return: 103 """ 104 if key_list is None: 105 key_list = ['blockNumber', 'amount'] 106 flag = True 107 keys1 = dict1.keys() 108 keys2 = dict2.keys() 109 if len(key_list) != 0: 110 for key in key_list: 111 if key in keys1 and key in keys2: 112 if dict1[key] == dict2[key]: 113 flag = True 114 else: 115 flag = False 116 else: 117 raise Exception('key_list contains error key') 118 else: 119 raise Exception('key_list is null') 120 return flag 121 122 123 def get_no_pledge_node(node_list) -> Node: 124 """ 125 Get nodes that are not pledged 126 :param node_list: Node list 127 :return: 128 """ 129 for node in node_list: 130 result = node.ppos.getCandidateInfo(node.node_id) 131 if result['Code'] == 301204: 132 return node 133 return None 134 135 136 def get_no_pledge_node_list(node_list: List[Node]) -> List[Node]: 137 """ 138 Get all the nodes that can be pledged 139 :param node_list: Node list 140 :return: 141 """ 142 no_pledge_node_list = [] 143 for node in node_list: 144 result = node.ppos.getCandidateInfo(node.node_id) 145 if result['Code'] == 301204: 146 no_pledge_node_list.append(node) 147 return no_pledge_node_list 148 149 150 def get_pledge_list(func) -> list: 151 """ 152 View the list of specified node IDs 153 :param func: Query method, 1. List of current pledge nodes 2, 154 the current consensus node list 3, real-time certifier list 155 :return: 156 """ 157 validator_info = func().get('Ret') 158 if validator_info == "Getting verifierList is failed:The validator is not exist": 159 time.sleep(10) 160 validator_info = func().get('Ret') 161 validator_list = [] 162 for info in validator_info: 163 validator_list.append(info.get('NodeId')) 164 return validator_list 165 166 167 def check_node_in_list(nodeid, func) -> bool: 168 """ 169 Check if the node is in the specified list 170 :param nodeid: Node id 171 :param func: Query method, 1. List of current pledge nodes 2, 172 the current consensus node list 3, real-time certifier list 173 :return: 174 """ 175 data_dict = func() 176 for data in data_dict["Ret"]: 177 if data["NodeId"] == nodeid: 178 return True 179 return False 180 181 182 def get_param_by_dict(data, *args): 183 """ 184 Query parameter valuesbased on json data 185 :param data: dictionary 186 :param args: Key 187 :return: 188 """ 189 i = 0 190 if isinstance(data, dict): 191 for key in args: 192 data = data.get(key) 193 i = i + 1 194 if isinstance(data, dict) and i > len(args): 195 raise Exception("The parameters entered are incorrect.") 196 return data 197 elif isinstance(data, str): 198 data = json.loads(data) 199 for key in args: 200 data = data.get(key) 201 i = i + 1 202 if isinstance(data, dict) and i > len(args): 203 raise Exception("The parameters entered are incorrect.") 204 return data 205 206 raise Exception("Data format error") 207 208 209 def update_param_by_dict(data, key1, key2, key3, value): 210 """ 211 Modify the json parameter 212 :param data: 213 :param key1: 214 :param key2: 215 :param key3: 216 :param value: 217 :return: 218 """ 219 if isinstance(data, dict): 220 if key3 is None: 221 data[key1][key2] = value 222 else: 223 data[key1][key2][key3] = value 224 return data 225 elif isinstance(data, str): 226 jsoninfo = json.loads(data) 227 if key3 is None: 228 jsoninfo[key1][key2] = value 229 else: 230 jsoninfo[key1][key2][key3] = value 231 jsondata = json.dumps(jsoninfo) 232 return jsondata 233 raise Exception("Data format error") 234 235 236 def wait_block_number(node, block, interval=1): 237 """ 238 Waiting until the specified block height 239 :param node: Node 240 :param block: Block height 241 :param interval: Block interval, default is 1s 242 :return: 243 """ 244 current_block = node.block_number 245 if 0 < block - current_block <= 10: 246 timeout = 10 + int(time.time()) 247 elif block - current_block > 10: 248 timeout = int((block - current_block) * interval * 1.5) + int(time.time()) 249 else: 250 log.info('current block {} is greater than block {}'.format(node.block_number, block)) 251 return 252 print_t = 0 253 while int(time.time()) < timeout: 254 print_t += 1 255 if print_t == 10: 256 # Print once every 10 seconds to avoid printing too often 257 log.info('The current block height is {}, waiting until {}'.format(node.block_number, block)) 258 print_t = 0 259 if node.block_number > block: 260 return 261 time.sleep(1) 262 raise Exception("Unable to pop out the block normally, the " 263 "current block height is: {}, the target block height is: {}".format(node.block_number, block)) 264 265 266 def get_validator_term(node): 267 """ 268 Get the nodeID with the highest term 269 """ 270 msg = node.ppos.getValidatorList() 271 term = [] 272 nodeid = [] 273 for i in msg["Ret"]: 274 term.append(i["ValidatorTerm"]) 275 nodeid.append(i["NodeId"]) 276 max_term = (max(term)) 277 term_nodeid_dict = dict(zip(term, nodeid)) 278 return term_nodeid_dict[max_term] 279 280 281 def get_max_staking_tx_index(node): 282 """ 283 Get the nodeID of the largest transaction index 284 """ 285 msg = node.ppos.getValidatorList() 286 staking_tx_index_list = [] 287 nodeid = [] 288 for i in msg["Ret"]: 289 staking_tx_index_list.append(i["StakingTxIndex"]) 290 nodeid.append(i["NodeId"]) 291 max_staking_tx_index = (max(staking_tx_index_list)) 292 term_nodeid_dict = dict(zip(staking_tx_index_list, nodeid)) 293 return term_nodeid_dict[max_staking_tx_index] 294 295 296 def get_block_count_number(node, number): 297 """ 298 Get the number of verifier blocks 299 :param url: node url 300 :param cycle: Consensus cycle 301 :return: 302 """ 303 current_block = node.block_number 304 count = 0 305 for i in range(number - 1): 306 nodeid = get_pub_key(node.url, current_block) 307 current_block = current_block - 1 308 if nodeid == node.node_id: 309 count = count + 1 310 return count 311 312 313 def random_string(length=10) -> str: 314 """ 315 Randomly generate a string of letters and numbers of a specified length 316 :param length: 317 :return: 318 """ 319 return ''.join( 320 random.choice( 321 string.ascii_lowercase 322 + string.ascii_uppercase 323 + string.digits 324 ) for _ in range(length) 325 ) 326 327 328 def assert_code(result, code): 329 ''' 330 assert the ErrorCode 331 :param result: 332 :param code: 333 :return: 334 ''' 335 if isinstance(result, int): 336 assert result == code, "code error,expect:{},actually:{}".format(code, result) 337 else: 338 assert result.get('Code') == code, "code error,expect:{},actually:{}".format(code, result) 339 340 341 def von_amount(amonut, base): 342 """ 343 Get von amount 344 :param amonut: 345 :param base: 346 :return: 347 """ 348 return int(Decimal(str(amonut)) * Decimal(str(base))) 349 350 351 def get_governable_parameter_value(client_obj, parameter): 352 """ 353 Get governable parameter value 354 :return: 355 """ 356 # Get governable parameters 357 govern_param = client_obj.pip.pip.listGovernParam() 358 parameter_information = govern_param['Ret'] 359 for i in parameter_information: 360 if i['ParamItem']['Name'] == parameter: 361 log.info("{} ParamValue: {}".format(parameter, i['ParamValue']['Value'])) 362 return i['ParamValue']['Value'] 363 364 365 def get_the_dynamic_parameter_gas_fee(data): 366 """ 367 Get the dynamic parameter gas consumption cost 368 :return: 369 """ 370 zero_number = 0 371 byte_group_length = len(data) 372 for i in data: 373 if i == 0: 374 zero_number = zero_number + 1 375 non_zero_number = byte_group_length - zero_number 376 dynamic_gas = non_zero_number * 68 + zero_number * 4 377 return dynamic_gas