github.com/platonnetwork/platon-go@v0.7.6/cases/tests/lib/economic.py (about)

     1  from decimal import Decimal
     2  
     3  from dacite import from_dict
     4  from .utils import wait_block_number, get_pledge_list
     5  from environment.node import Node
     6  from .genesis import Genesis
     7  from common.key import get_pub_key
     8  import math
     9  from .config import EconomicConfig
    10  from environment.env import TestEnvironment
    11  
    12  
    13  class Economic:
    14      cfg = EconomicConfig
    15  
    16      def __init__(self, env: TestEnvironment):
    17          self.env = env
    18  
    19          self.genesis = from_dict(data_class=Genesis, data=self.env.genesis_config)
    20  
    21          # Block rate parameter
    22          self.per_round_blocks = self.genesis.config.cbft.amount
    23          self.interval = int((self.genesis.config.cbft.period / self.per_round_blocks) / 1000)
    24  
    25          # Length of additional issuance cycle
    26          self.additional_cycle_time = self.genesis.economicModel.common.additionalCycleTime
    27  
    28          # Number of verification
    29          self.validator_count = self.genesis.economicModel.common.maxConsensusVals
    30  
    31          # Billing related
    32          # Billing cycle
    33          self.expected_minutes = self.genesis.economicModel.common.maxEpochMinutes
    34          # Consensus rounds
    35          self.consensus_wheel = (self.expected_minutes * 60) // (
    36              self.interval * self.per_round_blocks * self.validator_count)
    37          # Number of settlement periods
    38          self.settlement_size = self.consensus_wheel * (self.interval * self.per_round_blocks * self.validator_count)
    39          # Consensus round number
    40          self.consensus_size = self.per_round_blocks * self.validator_count
    41  
    42          # Minimum amount limit
    43          # Minimum deposit amount
    44          self.create_staking_limit = self.genesis.economicModel.staking.stakeThreshold
    45          # Minimum holding amount
    46          self.add_staking_limit = self.genesis.economicModel.staking.operatingThreshold
    47          # Minimum commission amount
    48          self.delegate_limit = self.add_staking_limit
    49          # unstaking freeze duration
    50          self.unstaking_freeze_ratio = self.genesis.economicModel.staking.unStakeFreezeDuration
    51          # ParamProposalVote_DurationSeconds
    52          self.pp_vote_settlement_wheel = self.genesis.economicModel.gov.paramProposalVoteDurationSeconds // self.settlement_size
    53          # slash blocks reward
    54          self.slash_blocks_reward = self.genesis.economicModel.slashing.slashBlocksReward
    55          # text proposal vote duration senconds
    56          self.tp_vote_settlement_wheel = self.genesis.economicModel.gov.textProposalVoteDurationSeconds // (
    57              self.interval * self.per_round_blocks * self.validator_count)
    58  
    59      @property
    60      def account(self):
    61          return self.env.account
    62  
    63      def get_block_count_number(self, node: Node, roundnum=1):
    64          """
    65          Get the number of blocks out of the verification node
    66          """
    67          current_block = node.eth.blockNumber
    68          block_namber = self.consensus_size * roundnum
    69          count = 0
    70          for i in range(block_namber - 1):
    71              node_id = get_pub_key(node.url, current_block)
    72              current_block = current_block - 1
    73              if node_id == node.node_id:
    74                  count = count + 1
    75          return count
    76  
    77      def get_current_year_reward(self, node: Node, verifier_num=None):
    78          """
    79          Get the first year of the block reward, pledge reward
    80          :return:
    81          """
    82          # if new_block_rate is None:
    83          #     new_block_rate = self.genesis.economicModel.reward.newBlockRate
    84          # # current_block = node.eth.blockNumber
    85          # annualcycle = (self.additional_cycle_time * 60) // self.settlement_size
    86          # annual_size = annualcycle * self.settlement_size
    87          # # starting_block_height = math.floor(current_block / annual_size) * annual_size
    88          if verifier_num is None:
    89              verifier_list = get_pledge_list(node.ppos.getVerifierList)
    90              verifier_num = len(verifier_list)
    91          # # amount = node.eth.getBalance(self.cfg.INCENTIVEPOOL_ADDRESS, starting_block_height)
    92          # if amount is None:
    93          #     amount = 262215742000000000000000000
    94          # block_proportion = str(new_block_rate / 100)
    95          # staking_proportion = str(1 - new_block_rate / 100)
    96          # block_reward = int(Decimal(str(amount)) * Decimal(str(block_proportion)) / Decimal(str(annual_size))) - node.web3.toWei(1 , 'ether')
    97          # staking_reward = int(
    98          #     Decimal(str(amount)) * Decimal(str(staking_proportion)) / Decimal(str(annualcycle)) / Decimal(
    99          #         str(verifier_num)))
   100          # # staking_reward = amount - block_reward
   101          result = node.ppos.getPackageReward()
   102          block_reward = result['Ret']
   103          result = node.ppos.getStakingReward()
   104          staking_reward = int(Decimal(str(result['Ret'])) / Decimal(str(verifier_num)))
   105          return block_reward, staking_reward
   106  
   107      def get_settlement_switchpoint(self, node: Node, number=0):
   108          """
   109          Get the last block of the current billing cycle
   110                                  :param node: node object
   111                                  :param number: number of billing cycles
   112          :return:
   113          """
   114          block_number = self.settlement_size * number
   115          tmp_current_block = node.eth.blockNumber
   116          current_end_block = math.ceil(tmp_current_block / self.settlement_size) * self.settlement_size + block_number
   117          return current_end_block
   118  
   119      def get_front_settlement_switchpoint(self, node: Node, number=0):
   120          """
   121          Get a block height before the current billing cycle
   122                                  :param node: node object
   123                                  :param number: number of billing cycles
   124          :return:
   125          """
   126          block_num = self.settlement_size * (number + 1)
   127          current_end_block = self.get_settlement_switchpoint(node)
   128          history_block = current_end_block - block_num + 1
   129          return history_block
   130  
   131      def wait_settlement_blocknum(self, node: Node, number=0):
   132          """
   133          Waiting for a billing cycle to settle
   134                                  :param node:
   135                                  :param number: number of billing cycles
   136          :return:
   137          """
   138          end_block = self.get_settlement_switchpoint(node, number)
   139          wait_block_number(node, end_block, self.interval)
   140  
   141      def get_annual_switchpoint(self, node: Node):
   142          """
   143          Get the number of annual settlement cycles
   144          """
   145          annual_cycle = (self.additional_cycle_time * 60) // self.settlement_size
   146          annualsize = annual_cycle * self.settlement_size
   147          current_block = node.eth.blockNumber
   148          current_end_block = math.ceil(current_block / annualsize) * annualsize
   149          return annual_cycle, annualsize, current_end_block
   150  
   151      def wait_annual_blocknum(self, node: Node):
   152          """
   153          Waiting for the end of the annual block high
   154          """
   155          annualcycle, annualsize, current_end_block = self.get_annual_switchpoint(node)
   156          current_block = node.eth.blockNumber
   157          differ_block = annualsize - (current_block % annualsize)
   158          annual_end_block = current_block + differ_block
   159          wait_block_number(node, annual_end_block, self.interval)
   160  
   161      def wait_consensus_blocknum(self, node: Node, number=0):
   162          """
   163          Waiting for a consensus round to end
   164          """
   165          end_block = self.get_consensus_switchpoint(node, number)
   166          wait_block_number(node, end_block, self.interval)
   167  
   168      def get_consensus_switchpoint(self, node: Node, number=0):
   169          """
   170          Get the specified consensus round high
   171          """
   172          block_number = self.consensus_size * number
   173          current_block = node.eth.blockNumber
   174          current_end_block = math.ceil(current_block / self.consensus_size) * self.consensus_size + block_number
   175          return current_end_block
   176  
   177      def get_report_reward(self, amount, penalty_ratio=None, proportion_ratio=None):
   178          """
   179          Gain income from double sign whistleblower and incentive pool
   180          :param node:
   181          :return:
   182          """
   183          if penalty_ratio is None:
   184              penalty_ratio = self.genesis.economicModel.slashing.slashFractionDuplicateSign
   185          if proportion_ratio is None:
   186              proportion_ratio = self.genesis.economicModel.slashing.duplicateSignReportReward
   187          penalty_reward = int(Decimal(str(amount)) * Decimal(str(penalty_ratio / 10000)))
   188          proportion_reward = int(Decimal(str(penalty_reward)) * Decimal(str(proportion_ratio / 100)))
   189          incentive_pool_reward = penalty_reward - proportion_reward
   190          return proportion_reward, incentive_pool_reward
   191  
   192  
   193  if __name__ == '__main__':
   194      a = Economic()
   195      a.get_current_year_reward()