.. _election: Election =============== Principles and Steps +++++++++++++++++++++ In election, a certain number of candidates (referred as *seats*) are elected to be proposer according to their RPT value. We have the following principles to design the election: #. An RNode with higher RPT has higher chance to be elected; #. Each term of proposers has a certain number of representatives from RNodes with low RPT. Thus, the basic steps of election process are: #. Candidates are divided into two partitions, high-RPT RNodes and low-RPT RNodes; #. Either partition has a number of available seats; #. The probability mass for each node being elected is proportional to its RPT in its corresponding partition; #. Random select nodes in two partitions, which together constitute proposers committee. Pseudocode of Election +++++++++++++++++++++++ Let :math:TotalRnode be the number of all RNode candidates, :math:TotalSeats be the number of seats for each term, :math:LowRptPercentage be the percentage of low-RPT RNdoes in all RNode candidates, and :math:LowRptSeats be available seats for low-RPT RNodes. The equation :math:0\leq LowRptPercentage\leq 1 and :math:0\leq LowRptSeats\leq LowRptPercentage \times TotalSeats \leq TotalSeats always hold. In current implementation, :math:LowRptPercentage is :math:50\%, and :math:LowRptSeats occupies one fourth of :math:TotalSeats. .. code-block:: go // rptList is the list of all candidates as well as their RPT value // seed is the seed for generating random numbers // tha value of seed is the hash value of the parent block func elect(rptList, seed, TotalRnode, TotalSeats, LowRptPercentage, LowRptSeats) []address { // sort rptList sort.Sort(rptList) var partition uint64 partition = LowRptPercentage * TotalRnode // partition rptList into lowRpts and highRpts lowRpts := rptList[:partition] highRpts := rptList[partition:] // generate a series of random numbers given the seed randSource := rand.NewSource(seed) myRand := rand.rand.New(randSource) lowElected := randomSelectByRpt(lowRpts, myRand, partition, LowRptSeats) highElected := randomSelectByRpt(highRpts, myRand, TotalRnode - partition, TotalSeats - LowRptSeats) return append(lowElected, highElected) } // uniform random selection from rptPartition // the mass probability for each node being elected is proportional to its RPT // the function select l random addresses // and return them as result func randomSelectByRpt(rptPartition, myRand, k, l) []address { if (k < l) { return all k addresses } // each element in rptPartition is referred as rpt // then we sum all rpt values, as sumRpt // using myRand to random select l addresses according to its rpt/sumRpt // return these l addresses } The Structure of Term ++++++++++++++++++++++++ Each **term** consists of 12 proposers and 36 blocks sealed by these proposers. The order of proposals is scheduled in the form of *Round Robin*, which is shown in the following figure. Each term consists of three identical *views*, in which 12 proposers seal blocks one by one. .. image:: term_structure.png