提交 2b70675d 编写于 作者: A Anton Perkov

starting to integrate voting and delegating bandwith

上级 f4dcec06
......@@ -4,6 +4,7 @@
*/
#pragma once
#include "common.hpp"
#include "voting.hpp"
#include <eosiolib/eosio.hpp>
#include <eosiolib/token.hpp>
......@@ -27,7 +28,7 @@ namespace eosiosystem {
using std::pair;
template<account_name SystemAccount>
class delegate_bandwith {
class delegate_bandwith : public voting<SystemAccount> {
public:
static constexpr account_name system_account = SystemAccount;
using currency = typename common<SystemAccount>::currency;
......@@ -112,21 +113,27 @@ namespace eosiosystem {
require_auth( del.from );
//eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" );
uint64_t storage_bytes = 0;
if ( 0 < del.stake_storage_quantity.amount ) {
auto parameters = global_state_singleton::exists() ? global_state_singleton::get()
: common<SystemAccount>::get_default_parameters();
auto token_supply = currency::get_total_supply();//.quantity;
auto parameters = global_state_singleton::exists() ? global_state_singleton::get()
: common<SystemAccount>::get_default_parameters();
auto token_supply = currency::get_total_supply();//.quantity;
//make sure that there is no posibility of overflow here
uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved )
* parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity)
/ ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */;
//make sure that there is no posibility of overflow here
uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved )
* parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity)
/ ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */;
storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated )
* parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity)
/ ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */;
uint64_t storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated )
* parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity)
/ ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */;
eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" );
eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" );
parameters.total_storage_bytes_reserved += storage_bytes;
parameters.total_storage_stake += del.stake_storage_quantity;
global_state_singleton::set(parameters);
}
del_bandwidth_index_type del_index( SystemAccount, del.from );
auto itr = del_index.find( del.receiver );
......@@ -171,10 +178,11 @@ namespace eosiosystem {
set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity, 0 );
currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" );
parameters.total_storage_bytes_reserved += storage_bytes;
parameters.total_storage_stake += del.stake_storage_quantity;
global_state_singleton::set(parameters);
/* temporarily commented out
if ( 0 < del.stake_net_quantity + del.stake_cpu_quantity ) {
increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity );
}
*/
} // delegatebw
static void on( const undelegatebw& del ) {
......@@ -191,9 +199,17 @@ namespace eosiosystem {
eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" );
eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" );
system_token_type storage_stake_decrease = 0 < dbw.storage_bytes ?
dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes
: system_token_type(0);
system_token_type storage_stake_decrease = system_token_type(0);
if ( 0 < del.unstake_storage_bytes ) {
storage_stake_decrease = 0 < dbw.storage_bytes ?
dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes
: system_token_type(0);
auto parameters = global_state_singleton::get();
parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes;
parameters.total_storage_stake -= storage_stake_decrease;
global_state_singleton::set( parameters );
}
auto total_refund = system_token_type(del.unstake_cpu_quantity)
+ system_token_type(del.unstake_net_quantity) + storage_stake_decrease;
......@@ -220,11 +236,6 @@ namespace eosiosystem {
/// TODO: implement / enforce time delays on withdrawing
currency::inline_transfer( SystemAccount, del.from, asset( static_cast<int64_t>( total_refund.quantity )), "unstake bandwidth" );
auto parameters = global_state_singleton::get();
parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes;
parameters.total_storage_stake -= storage_stake_decrease;
global_state_singleton::set( parameters );
} // undelegatebw
};
}
......@@ -4,7 +4,7 @@
*/
#pragma once
#include "voting.hpp"
//include "voting.hpp"
#include "delegate_bandwith.hpp"
#include <eosiolib/optional.hpp>
......@@ -39,7 +39,7 @@ namespace eosiosystem {
};
template<account_name SystemAccount>
class contract : public voting<SystemAccount>, public delegate_bandwith<SystemAccount> {
class contract : /*public voting<SystemAccount>,*/ public delegate_bandwith<SystemAccount> {
public:
using voting<SystemAccount>::on;
using delegate_bandwith<SystemAccount>::on;
......@@ -188,8 +188,6 @@ namespace eosiosystem {
typename voting<SystemAccount>::regproducer,
typename voting<SystemAccount>::unregprod,
typename voting<SystemAccount>::voteproducer,
typename voting<SystemAccount>::stakevote,
typename voting<SystemAccount>::unstakevote,
typename voting<SystemAccount>::unstake_vote_deferred,
onblock,
claim_rewards,
......
......@@ -144,13 +144,6 @@ namespace eosiosystem {
});
}
ACTION( SystemAccount, stakevote ) {
account_name voter;
system_token_type amount;
EOSLIB_SERIALIZE( stakevote, (voter)(amount) )
};
static void increase_voting_power( account_name acnt, system_token_type amount ) {
voters_table voters_tbl( SystemAccount, SystemAccount );
const auto* voter = voters_tbl.find( acnt );
......@@ -191,6 +184,76 @@ namespace eosiosystem {
}
}
static void decrease_voting_power( account_name acnt, system_token_type amount ) {
require_auth( acnt );
voters_table voters_tbl( SystemAccount, SystemAccount );
const auto* voter = voters_tbl.find( acnt );
eosio_assert( bool(voter), "stake not found" );
if ( 0 < amount.quantity ) {
eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" );
/*
if (voter->deferred_trx_id) {
//XXX cancel_deferred_transaction(voter->deferred_trx_id);
}
unstake_vote_deferred dt;
dt.voter = acnt;
uint32_t new_trx_id = 0;//XXX send_deferred(dt);
avotes.update( *voter, 0, [&](voter_info& a) {
a.staked -= amount;
a.unstaking += a.unstaking + amount;
//round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments
a.unstake_per_week = system_token_type( a.unstaking.quantity /unstake_payments + a.unstaking.quantity % unstake_payments );
a.deferred_trx_id = new_trx_id;
a.last_update = now();
});
*/
// Temporary code: immediate unstake
voters_tbl.update( *voter, 0, [&](voter_info& a) {
a.staked -= amount;
a.last_update = now();
});
//currency::inline_transfer( SystemAccount, acnt, amount, "unstake voting" );
// end of temporary code
const std::vector<account_name>* producers = nullptr;
if ( voter->proxy ) {
auto proxy = voters_tbl.find( voter->proxy );
voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.quantity; } );
if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers
producers = &proxy->producers;
}
} else {
producers = &voter->producers;
}
if ( producers ) {
producers_table producers_tbl( SystemAccount, SystemAccount );
for( auto p : *producers ) {
auto prod = producers_tbl.find( p );
eosio_assert( bool(prod), "never existed producer" ); //data corruption
producers_tbl.update( *prod, 0, [&]( auto& v ) {
v.total_votes -= amount.quantity;
});
}
}
} else {
if (voter->deferred_trx_id) {
//XXX cancel_deferred_transaction(voter->deferred_trx_id);
}
voters_tbl.update( *voter, 0, [&](voter_info& a) {
a.staked += a.unstaking;
a.unstaking.quantity = 0;
a.unstake_per_week.quantity = 0;
a.deferred_trx_id = 0;
a.last_update = now();
});
}
}
static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) {
const system_token_type token_supply = currency::get_total_supply();
const auto inflation_rate = max_inflation_rate * percent_of_max_inflation_rate;
......@@ -299,97 +362,12 @@ namespace eosiosystem {
global_state_singleton::set( parameters );
}
static void on( const stakevote& sv ) {
eosio_assert( sv.amount.quantity > 0, "must stake some tokens" );
require_auth( sv.voter );
increase_voting_power( sv.voter, sv.amount );
currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" );
}
ACTION( SystemAccount, unstakevote ) {
account_name voter;
system_token_type amount;
EOSLIB_SERIALIZE( unstakevote, (voter)(amount) )
};
ACTION( SystemAccount, unstake_vote_deferred ) {
account_name voter;
EOSLIB_SERIALIZE( unstake_vote_deferred, (voter) )
};
static void on( const unstakevote& usv ) {
require_auth( usv.voter );
voters_table voters_tbl( SystemAccount, SystemAccount );
const auto* voter = voters_tbl.find( usv.voter );
eosio_assert( bool(voter), "stake not found" );
if ( 0 < usv.amount.quantity ) {
eosio_assert( usv.amount <= voter->staked, "cannot unstake more than total stake amount" );
/*
if (voter->deferred_trx_id) {
//XXX cancel_deferred_transaction(voter->deferred_trx_id);
}
unstake_vote_deferred dt;
dt.voter = usv.voter;
uint32_t new_trx_id = 0;//XXX send_deferred(dt);
avotes.update( *voter, 0, [&](voter_info& a) {
a.staked -= usv.amount;
a.unstaking += a.unstaking + usv.amount;
//round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments
a.unstake_per_week = system_token_type( a.unstaking.quantity /unstake_payments + a.unstaking.quantity % unstake_payments );
a.deferred_trx_id = new_trx_id;
a.last_update = now();
});
*/
// Temporary code: immediate unstake
voters_tbl.update( *voter, 0, [&](voter_info& a) {
a.staked -= usv.amount;
a.last_update = now();
});
currency::inline_transfer( SystemAccount, usv.voter, usv.amount, "unstake voting" );
// end of temporary code
const std::vector<account_name>* producers = nullptr;
if ( voter->proxy ) {
auto proxy = voters_tbl.find( voter->proxy );
voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes -= usv.amount.quantity; } );
if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers
producers = &proxy->producers;
}
} else {
producers = &voter->producers;
}
if ( producers ) {
producers_table producers_tbl( SystemAccount, SystemAccount );
for( auto p : *producers ) {
auto prod = producers_tbl.find( p );
eosio_assert( bool(prod), "never existed producer" ); //data corruption
producers_tbl.update( *prod, 0, [&]( auto& v ) {
v.total_votes -= usv.amount.quantity;
});
}
}
} else {
if (voter->deferred_trx_id) {
//XXX cancel_deferred_transaction(voter->deferred_trx_id);
}
voters_tbl.update( *voter, 0, [&](voter_info& a) {
a.staked += a.unstaking;
a.unstaking.quantity = 0;
a.unstake_per_week.quantity = 0;
a.deferred_trx_id = 0;
a.last_update = now();
});
}
}
static void on( const unstake_vote_deferred& usv) {
require_auth( usv.voter );
voters_table voters_tbl( SystemAccount, SystemAccount );
......
......@@ -3,6 +3,8 @@ SET(SRC_FILENAMES algorithm.cpp any.cpp bind.cpp condition_variable.cpp exceptio
regex.cpp shared_mutex.cpp stdexcept.cpp string.cpp strstream.cpp system_error.cpp
thread.cpp typeinfo.cpp utility.cpp valarray.cpp variant.cpp vector.cpp)
#SET(SRC_FILENAMES exception.cpp)
SET(SRC_FILES "")
FOREACH(FN ${SRC_FILENAMES})
LIST(APPEND SRC_FILES "upstream/src/${FN}")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册