eosio.system.hpp 8.8 KB
Newer Older
1 2 3 4
/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
5
#pragma once
6

D
Daniel Larimer 已提交
7
#include <eosio.system/native.hpp>
8 9 10
#include <eosiolib/asset.hpp>
#include <eosiolib/privileged.hpp>
#include <eosiolib/singleton.hpp>
D
Daniel Larimer 已提交
11
#include <eosio.system/exchange_state.hpp>
12

13
#include <string>
14

15
namespace eosiosystem {
K
Khaled Al-Hassanieh 已提交
16

17 18 19 20 21
   using eosio::asset;
   using eosio::indexed_by;
   using eosio::const_mem_fun;

   struct eosio_parameters : eosio::blockchain_parameters {
22
      uint64_t          max_ram_size = 64ll*1024 * 1024 * 1024;
23

A
Anton Perkov 已提交
24
      // explicit serialization macro is not necessary, used here only to improve compilation time
K
Khaled Al-Hassanieh 已提交
25
      EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_ram_size) )
26 27 28
   };

   struct eosio_global_state : eosio_parameters {
29
      uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; }
D
Daniel Larimer 已提交
30

31 32
      uint64_t             total_ram_bytes_reserved = 0;
      eosio::asset         total_ram_stake;
D
Daniel Larimer 已提交
33

34
      block_timestamp      last_producer_schedule_update = 0;
35
      uint64_t             last_pervote_bucket_fill = 0;
36
      eosio::asset         pervote_bucket;
37
      eosio::asset         savings;
D
Daniel Larimer 已提交
38 39
      checksum160          last_producer_schedule_id;

K
Khaled Al-Hassanieh 已提交
40
      int64_t              total_activated_stake = 0;
41

A
Anton Perkov 已提交
42
      // explicit serialization macro is not necessary, used here only to improve compilation time
43
      EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake)
D
Daniel Larimer 已提交
44 45
                                (last_producer_schedule_update)
                                (last_pervote_bucket_fill)
46
                                (pervote_bucket)(savings)(last_producer_schedule_id)(total_activated_stake) )
47 48 49
   };

   struct producer_info {
D
Daniel Larimer 已提交
50 51 52
      account_name          owner;
      double                total_votes = 0;
      eosio::public_key     producer_key; /// a packed public key object
A
Anton Perkov 已提交
53
      std::string           url;
D
Daniel Larimer 已提交
54
      uint32_t              produced_blocks;
55
      uint64_t              last_claim_time = 0;
D
Daniel Larimer 已提交
56
      uint16_t              location = 0;
57 58
      block_timestamp       time_became_active = 0;
      block_timestamp       last_produced_block_time = 0;
D
Daniel Larimer 已提交
59 60 61 62

      uint64_t    primary_key()const { return owner;                        }
      double      by_votes()const    { return -total_votes;                 }
      bool        active() const     { return producer_key != public_key(); }
63

A
Anton Perkov 已提交
64
      // explicit serialization macro is not necessary, used here only to improve compilation time
A
Anton Perkov 已提交
65
      EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(url)
66
                        (produced_blocks)(last_claim_time)(location)
67 68 69
                        (time_became_active)(last_produced_block_time) )
   };

D
Daniel Larimer 已提交
70 71 72 73
   struct voter_info {
      account_name                owner = 0; /// the voter
      account_name                proxy = 0; /// the proxy set by the voter, if any
      std::vector<account_name>   producers; /// the producers approved by this voter if no proxy set
D
Daniel Larimer 已提交
74
      int64_t                     staked = 0;
D
Daniel Larimer 已提交
75 76 77 78 79 80 81

      /**
       *  Every time a vote is cast we must first "undo" the last vote weight, before casting the
       *  new vote weight.  Vote weight is calculated as:
       *
       *  stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year)
       */
82
      double                      last_vote_weight = 0; /// the vote weight cast the last time the vote was updated
D
Daniel Larimer 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

      /**
       * Total vote weight delegated to this voter.
       */
      double                      proxied_vote_weight= 0; /// the total vote weight delegated to this voter as a proxy
      bool                        is_proxy = 0; /// whether the voter is a proxy for others


      uint32_t                    deferred_trx_id = 0; /// the ID of the 3-day delay deferred transaction
      time                        last_unstake_time = 0; /// the time when the deferred_trx_id was sent
      eosio::asset                unstaking; /// the total unstaking (pending 3 day delay)

      uint64_t primary_key()const { return owner; }

      // explicit serialization macro is not necessary, used here only to improve compilation time
      EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(deferred_trx_id)(last_unstake_time)(unstaking) )
   };

   typedef eosio::multi_index< N(voters), voter_info>  voters_table;


104
   typedef eosio::multi_index< N(producers), producer_info,
D
Daniel Larimer 已提交
105
                               indexed_by<N(prototalvote), const_mem_fun<producer_info, double, &producer_info::by_votes>  >
106 107
                               >  producers_table;

108
   typedef eosio::singleton<N(global), eosio_global_state> global_state_singleton;
109

110
   //   static constexpr uint32_t     max_inflation_rate = 5;  // 5% annual inflation
111
   static constexpr uint32_t     seconds_per_day = 24 * 3600;
112 113
   static constexpr uint64_t     system_token_symbol = S(4,EOS);

D
Daniel Larimer 已提交
114
   class system_contract : public native {
D
Daniel Larimer 已提交
115 116 117 118 119 120
      private:
         voters_table           _voters;
         producers_table        _producers;
         global_state_singleton _global;

         eosio_global_state     _gstate;
D
Daniel Larimer 已提交
121
         rammarket              _rammarket;
D
Daniel Larimer 已提交
122

123
      public:
D
Daniel Larimer 已提交
124
         system_contract( account_name s );
125
         ~system_contract();
126

127
         // Actions:
128
         void onblock( uint32_t timestamp_slot, account_name producer );
D
Daniel Larimer 已提交
129
                      // const block_header& header ); /// only parse first 3 fields of block header
130

131
         // functions defined in delegate_bandwidth.cpp
132 133 134 135 136 137

         /**
          *  Stakes SYS from the balance of 'from' for the benfit of 'receiver'. 
          *  If transfer == true, then 'receiver' can unstake to their account
          *  Else 'from' can unstake at any time.
          */
D
Daniel Larimer 已提交
138
         void delegatebw( account_name from, account_name receiver,
139
                          asset stake_net_quantity, asset stake_cpu_quantity, bool transfer );
D
Daniel Larimer 已提交
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167


         /**
          *  Decreases the total tokens delegated by from to receiver and/or
          *  frees the memory associated with the delegation if there is nothing
          *  left to delegate.
          *
          *  This will cause an immediate reduction in net/cpu bandwidth of the
          *  receiver. 
          *
          *  A transaction is scheduled to send the tokens back to 'from' after
          *  the staking period has passed. If existing transaction is scheduled, it
          *  will be canceled and a new transaction issued that has the combined
          *  undelegated amount.
          *
          *  The 'from' account loses voting power as a result of this call and
          *  all producer tallies are updated.
          */
         void undelegatebw( account_name from, account_name receiver,
                            asset unstake_net_quantity, asset unstake_cpu_quantity );


         /**
          * Increases receiver's ram quota based upon current price and quantity of
          * tokens provided. An inline transfer from receiver to system contract of
          * tokens will be executed.
          */
         void buyram( account_name buyer, account_name receiver, asset tokens );
168
         void buyrambytes( account_name buyer, account_name receiver, uint32_t bytes );
D
Daniel Larimer 已提交
169 170 171 172 173

         /**
          *  Reduces quota my bytes and then performs an inline transfer of tokens
          *  to receiver based upon the average purchase price of the original quota.
          */
D
Daniel Larimer 已提交
174
         void sellram( account_name receiver, uint64_t bytes );
D
Daniel Larimer 已提交
175 176 177 178 179 180

         /**
          *  This action is called after the delegation-period to claim all pending
          *  unstaked tokens belonging to owner
          */
         void refund( account_name owner );
181

182
         // functions defined in voting.cpp
183

184
         void regproducer( const account_name producer, const public_key& producer_key, const std::string& url );
185

186
         void unregprod( const account_name producer );
187

188
         void setram( uint64_t max_ram_size );
189

190
         void voteproducer( const account_name voter, const account_name proxy, const std::vector<account_name>& producers );
191

192
         void regproxy( const account_name proxy, bool isproxy );
193

194 195
         // functions defined in producer_pay.cpp
         void claimrewards( const account_name& owner );
196

197
      private:
198
         eosio::asset payment_per_block( double rate, const eosio::asset& token_supply,  uint32_t num_blocks );
199

200
         eosio::asset payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket );
201 202
         
         eosio::asset supply_growth( double rate, const eosio::asset& token_supply, time seconds );
D
Daniel Larimer 已提交
203

204
         void update_elected_producers( block_timestamp timestamp );
D
Daniel Larimer 已提交
205

206
         // Implementation details:
207

208 209 210 211
         //defined in voting.hpp
         static eosio_global_state get_default_parameters();

         // defined in voting.cpp
212
         void propagate_weight_change( const voter_info& voter );
213
   };
214

215
} /// eosiosystem