提交 03ccbbda 编写于 作者: A Anton Perkov

Merge branch 'slim' into cleos-listproducers

......@@ -123,22 +123,28 @@
"name": "eosio_global_state",
"base": "eosio_parameters",
"fields": [
{"name":"total_ram_bytes_reserved", "type":"uint64"},
{"name":"total_ram_stake", "type":"uint64"},
{"name":"payment_per_block", "type":"uint64"}
{"name":"total_ram_bytes_reserved", "type":"uint64"},
{"name":"total_ram_stake", "type":"asset"},
{"name":"last_producer_schedule_update", "type":"time"},
{"name":"last_pervote_bucket_fill", "type":"time"},
{"name":"eos_bucket", "type":"asset"},
{"name":"savings", "type":"asset"},
{"name":"last_producer_schedule_id", "type":"checksum160"},
{"name":"total_activatied_stake", "type":"int64"}
]
},{
"name": "producer_info",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"total_votes", "type":"float64"},
{"name":"producer_key", "type":"public_key"},
{"name":"url", "type":"string"},
{"name":"last_rewards_claim", "type":"uint32"},
{"name":"location", "type":"uint16"},
{"name":"time_became_active", "type":"uint32"},
{"name":"time_produced_block_time", "type":"uint32"}
{"name":"owner", "type":"account_name"},
{"name":"total_votes", "type":"float64"},
{"name":"producer_key", "type":"public_key"},
{"name":"url", "type":"string"},
{"name":"produced_blocks", "type":"uint32"},
{"name":"last_claim_time", "type":"time"},
{"name":"location", "type":"uint16"},
{"name":"time_became_active", "type":"time"},
{"name":"last_produced_block_time", "type":"time"}
]
},{
"name": "regproducer",
......@@ -182,7 +188,7 @@
{"name":"owner", "type":"account_name"},
{"name":"proxy", "type":"account_name"},
{"name":"producers", "type":"account_name[]"},
{"name":"staked", "type":"uint64"},
{"name":"staked", "type":"int64"},
{"name":"last_vote_weight", "type":"float64"},
{"name":"proxied_vote_weight", "type":"float64"},
{"name":"is_proxy", "type":"bool"},
......
......@@ -32,18 +32,18 @@ namespace eosiosystem {
eosio::asset total_ram_stake;
block_timestamp last_producer_schedule_update = 0;
block_timestamp last_pervote_bucket_fill = 0;
time last_pervote_bucket_fill = 0;
eosio::asset eos_bucket;
eosio::asset savings;
checksum160 last_producer_schedule_id;
int64_t total_activiated_stake = 0;
int64_t total_activated_stake = 0;
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake)
(last_producer_schedule_update)
(last_pervote_bucket_fill)
(eos_bucket)(savings)(last_producer_schedule_id)(total_activiated_stake) )
(eos_bucket)(savings)(last_producer_schedule_id)(total_activated_stake) )
};
struct producer_info {
......@@ -52,7 +52,7 @@ namespace eosiosystem {
eosio::public_key producer_key; /// a packed public key object
std::string url;
uint32_t produced_blocks;
time last_rewards_claim = 0;
time last_claim_time = 0;
uint16_t location = 0;
block_timestamp time_became_active = 0;
block_timestamp last_produced_block_time = 0;
......@@ -63,7 +63,7 @@ namespace eosiosystem {
// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(url)
(produced_blocks)(last_rewards_claim)
(produced_blocks)(last_claim_time)(location)
(time_became_active)(last_produced_block_time) )
};
......@@ -189,9 +189,11 @@ namespace eosiosystem {
void claimrewards( const account_name& owner );
private:
eosio::asset payment_per_block( double rate, const eosio::asset& token_supply );
eosio::asset payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks );
eosio::asset payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket );
eosio::asset supply_growth( double rate, const eosio::asset& token_supply, time seconds );
void update_elected_producers( block_timestamp timestamp );
......
......@@ -5,69 +5,48 @@
namespace eosiosystem {
const int64_t min_daily_tokens = 100;
/*
const double continuous_rate = std::log1p(0.05); // 5% annual rate
const double per_block_rate = 0.0025; // 0.25%
const double continuous_rate = 0.04879; // 5% annual rate
const double perblock_rate = 0.0025; // 0.25%
const double standby_rate = 0.0075; // 0.75%
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;
eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks ) {
const int64_t payment = static_cast<int64_t>( (rate * double(token_supply.amount) * double(num_blocks)) / double(blocks_per_year) );
return eosio::asset( payment, token_supply.symbol );
}
eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply ) {
const int64_t payment = static_cast<int64_t>( (rate * double(token_supply.amount)) / double(blocks_per_year) );
eosio::asset system_contract::supply_growth( double rate, const eosio::asset& token_supply, time seconds ) {
const int64_t payment = static_cast<int64_t>( (rate * double(token_supply.amount) * double(seconds)) / double(seconds_per_year) );
return eosio::asset( payment, token_supply.symbol );
}
*/
void system_contract::onblock( block_timestamp timestamp, account_name producer ) {
using namespace eosio;
/** until activated stake crosses this threshold no new rewards are paid */
if( _gstate.total_activiated_stake < 150'000'000'0000 )
if( _gstate.total_activated_stake < 150'000'000'0000 )
return;
if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses
_gstate.last_pervote_bucket_fill = timestamp;
_producers.modify( _producers.get(producer), 0, [&](auto& p ) {
p.produced_blocks++;
p.last_produced_block_time = timestamp;
});
auto prod = _producers.find(producer);
if ( prod != _producers.end() ) {
_producers.modify( prod, 0, [&](auto& p ) {
p.produced_blocks++;
p.last_produced_block_time = timestamp;
});
}
/// only update block producers once every minute, block_timestamp is in half seconds
if( timestamp - _gstate.last_producer_schedule_update > 120 ) {
update_elected_producers( timestamp );
}
/// only update block producers once every minute, block_timestamp is in half seconds
/*
if( timestamp % 120 != 0 )
return;
const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() );
const asset issued = payment_per_block( continuous_rate, token_supply );
const asset producer_payment = payment_per_block( per_block_rate, token_supply );
const asset to_eos_bucket = payment_per_block( standby_rate, token_supply );
const asset to_savings = issued - (producer_payment + to_eos_bucket);
INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}},
{N(eosio), issued, std::string("issue tokens per block")} );
*/
/*
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio),N(active)}},
{N(eosio), N(eosio), to_savings, std::string("transfer to savings per block")} );
auto parameters = _global.exists() ? _global.get() : get_default_parameters();
parameters.eos_bucket += to_eos_bucket;
parameters.savings += to_savings;
_global.set ( parameters, _self );
const auto& producer_schedule_update = parameters.last_producer_schedule_update;
if ( producer_schedule_update == 0 || producer_schedule_update < timestamp + blocks_per_hour ) {
update_elected_producers( producer_schedule_update );
}
*/
}
eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ) {
......@@ -112,42 +91,43 @@ namespace eosiosystem {
}
void system_contract::claimrewards( const account_name& owner ) {
using namespace eosio;
require_auth(owner);
auto prod = _producers.find( owner );
eosio_assert( prod != _producers.end(), "account name is not in producer list" );
if( prod->last_rewards_claim > 0 ) {
eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day");
if( prod->last_claim_time > 0 ) {
eosio_assert(now() >= prod->last_claim_time + seconds_per_day, "already claimed rewards within a day");
}
/// calcualte the price-per-block
/*
eosio::asset rewards = prod->per_block_payments;
if ( _global.exists() ) {
auto parameters = _global.get();
if ( parameters.eos_bucket.amount > 0 && prod->total_votes > 0 ) {
eosio::asset standby_payment = payment_per_vote( owner, prod->total_votes, parameters.eos_bucket );
if ( standby_payment.amount > 0 ) {
rewards += standby_payment;
parameters.eos_bucket -= standby_payment;
_global.set( parameters, _self );
}
}
}
auto parameters = _global.get();
const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() );
const time time_since_last_fill = now() - parameters.last_pervote_bucket_fill;
const asset to_eos_bucket = supply_growth( standby_rate, token_supply, time_since_last_fill );
const asset to_savings = supply_growth( continuous_rate - (perblock_rate + standby_rate), token_supply, time_since_last_fill );
const asset perblock_pay = payment_per_block( perblock_rate, token_supply, prod->produced_blocks );
const asset issue_amount = to_eos_bucket + to_savings + perblock_pay;
eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" );
INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}},
{N(eosio), issue_amount, std::string("issue tokens for producer pay and savings")} );
const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + parameters.eos_bucket );
parameters.eos_bucket += ( to_eos_bucket - pervote_pay );
parameters.last_pervote_bucket_fill = now();
parameters.savings += to_savings;
_global.set( parameters, _self );
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
{ N(eosio), owner, perblock_pay + pervote_pay, std::string("producer claiming rewards") } );
_producers.modify( prod, 0, [&](auto& p) {
p.last_rewards_claim = now();
p.last_claim_time = now();
p.produced_blocks = 0;
});
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
{ N(eosio), owner, rewards, std::string("producer claiming rewards") } );
*/
}
} //namespace eosiosystem
......@@ -139,11 +139,11 @@ namespace eosiosystem {
/**
* The first time someone votes we calculate and set last_vote_weight, since they cannot unstake until
* after total_activiated_stake hits threshold, we can use last_vote_weight to determine that this is
* after total_activated_stake hits threshold, we can use last_vote_weight to determine that this is
* their first vote and should consider their stake activated.
*/
if( voter->last_vote_weight <= 0.0 ) {
_gstate.total_activiated_stake += voter->staked;
_gstate.total_activated_stake += voter->staked;
}
auto weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 );
......
......@@ -1169,8 +1169,6 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester) try {
issue( "alice", "10000.0000 EOS", config::system_account_name);
BOOST_REQUIRE_EQUAL( asset::from_string("10000.0000 EOS"), get_balance( "alice" ) );
fc::variant params = producer_parameters_example(50);
// 1 block produced
BOOST_REQUIRE_EQUAL(success(), regproducer(N(alice)));
......@@ -1178,8 +1176,6 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester) try {
BOOST_REQUIRE_EQUAL("alice", prod["owner"].as_string());
BOOST_REQUIRE_EQUAL(0, prod["total_votes"].as_uint64());
REQUIRE_EQUAL_OBJECTS(params, prod["prefs"]);
issue("bob", "2000.0000 EOS", config::system_account_name);
BOOST_REQUIRE_EQUAL( asset::from_string("2000.0000 EOS"), get_balance( "bob" ) );
......@@ -1198,15 +1194,16 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester) try {
)
);
produce_blocks(10);
produce_blocks(20);
prod = get_producer_info("alice");
BOOST_REQUIRE(prod["per_block_payments"].as_uint64() > 0);
// this test fails as there isn't enough total activated stake and onblock is a noop
BOOST_REQUIRE(prod["produced_blocks"].as<uint32_t>() > 0);
BOOST_REQUIRE_EQUAL(success(), push_action(N(alice), N(claimrewards), mvo()
("owner", "alice")
)
);
prod = get_producer_info("alice");
BOOST_REQUIRE_EQUAL(0, prod["per_block_payments"].as_uint64());
BOOST_REQUIRE_EQUAL(0, prod["produced_blocks"].as<uint32_t>());
} FC_LOG_AND_RETHROW()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册