producer_pay.cpp 7.6 KB
Newer Older
1
#include "eosio.system.hpp"
B
big4david 已提交
2
#include <eosiolib/print.hpp>
3 4 5 6
#include <eosio.token/eosio.token.hpp>

namespace eosiosystem {

7
   const int64_t  min_pervote_daily_pay = 100'0000;
8 9 10 11 12
   //##YTA-Change  start:
   //Change total vote rate from 15% to 1% for test network
   //const int64_t  min_activated_stake   = 150'000'000'0000;
   const int64_t  min_activated_stake   = 10'000'000'0000;
   //##YTA-Change  end:
13 14 15 16 17 18
   const uint32_t blocks_per_year       = 52*7*24*2*3600;   // half seconds per year
   const uint32_t seconds_per_year      = 52*7*24*3600;
   const uint32_t blocks_per_day        = 2 * 24 * 3600;
   const uint32_t blocks_per_hour       = 2 * 3600;
   const uint64_t useconds_per_day      = 24 * 3600 * uint64_t(1000000);
   const uint64_t useconds_per_year     = seconds_per_year*1000000ll;
K
Khaled Al-Hassanieh 已提交
19

L
luchiagogogo 已提交
20
   const int64_t block_initial_timestamp = 1551369600ll;  // epoch year 2019.03.01    unix timestamp 1551369600s
X
xiaoming 已提交
21 22
   //yta seo total= yta_seo_year[i] * YTA_SEO_BASE
   const uint32_t YTA_SEO_BASE = 10'0000;
L
luchiagogogo 已提交
23 24
   const double YTA_PRECISION =10000.0000;
   const uint32_t yta_seo_year[62] = {
X
xiaoming 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
            1000, 900, 800, 700,
            600, 600, 500, 500,
            400, 400, 300, 300,
            200, 200, 200,
            100, 100, 100,
            90, 90, 90,
            80, 80, 80,
            70, 70, 70, 70,
            60, 60, 60, 60,
            50, 50, 50, 50, 50,
            40, 40, 40, 40, 40,
            30, 30, 30, 30, 30,
            20, 20, 20, 20, 20,
            10, 10, 10, 10, 10,
            9, 9, 9, 9, 9
    };
41

42 43
   void system_contract::onblock( block_timestamp timestamp, account_name producer ) {
      using namespace eosio;
K
Khaled Al-Hassanieh 已提交
44

45 46
      require_auth(N(eosio));

D
Daniel Larimer 已提交
47
      /** until activated stake crosses this threshold no new rewards are paid */
48
      if( _gstate.total_activated_stake < min_activated_stake )
D
Daniel Larimer 已提交
49 50 51
         return;

      if( _gstate.last_pervote_bucket_fill == 0 )  /// start the presses
52
         _gstate.last_pervote_bucket_fill = current_time();
D
Daniel Larimer 已提交
53

D
Daniel Larimer 已提交
54 55 56 57 58

      /**
       * At startup the initial producer may not be one that is registered / elected
       * and therefore there may be no producer object for them.
       */
K
Khaled Al-Hassanieh 已提交
59 60
      auto prod = _producers.find(producer);
      if ( prod != _producers.end() ) {
D
Daniel Larimer 已提交
61
         _gstate.total_unpaid_blocks++;
K
Khaled Al-Hassanieh 已提交
62
         _producers.modify( prod, 0, [&](auto& p ) {
63
               p.unpaid_blocks++;
K
Khaled Al-Hassanieh 已提交
64 65
         });
      }
66

67
      //##YTA-Change  start:         
68
      /// only update block producers once every minute, block_timestamp is in half seconds
69 70 71 72 73
      //if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) {
      /// update block producers once every two minute due to election strategy is more complex than before
      if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 240 ) {
      //##YTA-Change  end:         

74
         update_elected_producers( timestamp );
75

76
         if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) {
D
Daniel Larimer 已提交
77 78 79
            name_bid_table bids(_self,_self);
            auto idx = bids.get_index<N(highbid)>();
            auto highest = idx.begin();
80
            if( highest != idx.end() &&
81
                highest->high_bid > 0 &&
82
                highest->last_bid_time < (current_time() - useconds_per_day) &&
83 84 85 86 87
                _gstate.thresh_activated_stake_time > 0 &&
                (current_time() - _gstate.thresh_activated_stake_time) > 14 * useconds_per_day ) {
                   _gstate.last_name_close = timestamp;
                   idx.modify( highest, 0, [&]( auto& b ){
                         b.high_bid = -b.high_bid;
D
Daniel Larimer 已提交
88 89 90
               });
            }
         }
91
      }
92 93
   }

D
Daniel Larimer 已提交
94
   using namespace eosio;
95 96
   void system_contract::claimrewards( const account_name& owner ) {
      require_auth(owner);
K
Khaled Al-Hassanieh 已提交
97

D
Daniel Larimer 已提交
98 99
      const auto& prod = _producers.get( owner );
      eosio_assert( prod.active(), "producer does not have an active key" );
100

L
luchiagogogo 已提交
101
      eosio_assert( _gstate.total_activated_stake >= min_activated_stake,
102
                    "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" );
L
luchiagogogo 已提交
103
      
D
Daniel Larimer 已提交
104
      auto ct = current_time();
105

L
luchiagogogo 已提交
106
      //eosio_assert( ct - prod.last_claim_time > useconds_per_day, "already claimed rewards within past day" );
107

D
Daniel Larimer 已提交
108 109 110
      const asset token_supply   = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() );
      const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill;

L
luchiagogogo 已提交
111 112 113
      print("usecs_since_last_fill: ", usecs_since_last_fill, "\n");   
      print("_gstate.last_pervote_bucket_fill: ", _gstate.last_pervote_bucket_fill, "\n");
      print("now(): ", now(), "\n");
L
luchiagogogo 已提交
114 115
       
      int idx_year = (int)((now()- block_initial_timestamp) / seconds_per_year);
B
big4david 已提交
116
      auto seo_token = yta_seo_year[idx_year] * YTA_SEO_BASE;
L
luchiagogogo 已提交
117 118 119
       
      print("idx_year: ", idx_year, "\n");
      print("yta_seo_year[idx_year]: ", yta_seo_year[idx_year], "\n");
B
big4david 已提交
120 121
      print( "token_supply: ", token_supply, "\n");
      print("seo_token: ", seo_token, "\n");
L
luchiagogogo 已提交
122
		 
B
big4david 已提交
123
      if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > 0 ) {
L
luchiagogogo 已提交
124
         auto new_tokens = static_cast<int64_t>(seo_token * YTA_PRECISION * double(usecs_since_last_fill)/double(useconds_per_year));
B
big4david 已提交
125
         print("new_token: ", new_tokens, "\n");
X
xiaoming 已提交
126
         auto to_producers       = new_tokens;
D
Daniel Larimer 已提交
127 128 129 130 131 132
         auto to_per_block_pay   = to_producers / 4;
         auto to_per_vote_pay    = to_producers - to_per_block_pay;

         INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}},
                                                    {N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} );

133 134 135 136 137 138 139

         INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
                                                       { N(eosio), N(eosio.bpay), asset(to_per_block_pay), "fund per-block bucket" } );

         INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
                                                       { N(eosio), N(eosio.vpay), asset(to_per_vote_pay), "fund per-vote bucket" } );

D
Daniel Larimer 已提交
140 141 142 143
         _gstate.pervote_bucket  += to_per_vote_pay;
         _gstate.perblock_bucket += to_per_block_pay;

         _gstate.last_pervote_bucket_fill = ct;
144
      }
145

146 147 148 149 150
      int64_t producer_per_block_pay = 0;
      if( _gstate.total_unpaid_blocks > 0 ) {
         producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks;
      }
      int64_t producer_per_vote_pay = 0;
151
      if( _gstate.total_producer_vote_weight > 0 ) {
152 153
         producer_per_vote_pay  = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight);
      }
154
      if( producer_per_vote_pay < min_pervote_daily_pay ) {
155 156
         producer_per_vote_pay = 0;
      }
D
Daniel Larimer 已提交
157 158
      _gstate.pervote_bucket      -= producer_per_vote_pay;
      _gstate.perblock_bucket     -= producer_per_block_pay;
159
      _gstate.total_unpaid_blocks -= prod.unpaid_blocks;
160

D
Daniel Larimer 已提交
161 162
      _producers.modify( prod, 0, [&](auto& p) {
          p.last_claim_time = ct;
163
          p.unpaid_blocks = 0;
D
Daniel Larimer 已提交
164
      });
165

166 167 168 169 170 171 172
      if( producer_per_block_pay > 0 ) {
         INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.bpay),N(active)},
                                                       { N(eosio.bpay), owner, asset(producer_per_block_pay), std::string("producer block pay") } );
      }
      if( producer_per_vote_pay > 0 ) {
         INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.vpay),N(active)},
                                                       { N(eosio.vpay), owner, asset(producer_per_vote_pay), std::string("producer vote pay") } );
D
Daniel Larimer 已提交
173
      }
174 175 176
   }

} //namespace eosiosystem