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 values​based 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