diff --git a/contracts/eosio.system/delegate_bandwith.hpp b/contracts/eosio.system/delegate_bandwith.hpp index 917f331253e77544db634cbaec61c17095f9b449..950add2870eeace32c7015c47f378a1cc87346a6 100644 --- a/contracts/eosio.system/delegate_bandwith.hpp +++ b/contracts/eosio.system/delegate_bandwith.hpp @@ -4,6 +4,7 @@ */ #pragma once #include "common.hpp" +#include "voting.hpp" #include #include @@ -27,7 +28,7 @@ namespace eosiosystem { using std::pair; template - class delegate_bandwith { + class delegate_bandwith : public voting { public: static constexpr account_name system_account = SystemAccount; using currency = typename common::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::get_default_parameters(); + auto token_supply = currency::get_total_supply();//.quantity; - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::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( 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 }; } diff --git a/contracts/eosio.system/eosio.system.hpp b/contracts/eosio.system/eosio.system.hpp index 9d3c94e5696973b3fd5763e7ff3015898392a9c6..35c4bfcc88fbc8c69a5d7864f7476b0803acad5e 100644 --- a/contracts/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/eosio.system.hpp @@ -4,7 +4,7 @@ */ #pragma once -#include "voting.hpp" +//include "voting.hpp" #include "delegate_bandwith.hpp" #include @@ -39,7 +39,7 @@ namespace eosiosystem { }; template - class contract : public voting, public delegate_bandwith { + class contract : /*public voting,*/ public delegate_bandwith { public: using voting::on; using delegate_bandwith::on; @@ -188,8 +188,6 @@ namespace eosiosystem { typename voting::regproducer, typename voting::unregprod, typename voting::voteproducer, - typename voting::stakevote, - typename voting::unstakevote, typename voting::unstake_vote_deferred, onblock, claim_rewards, diff --git a/contracts/eosio.system/voting.hpp b/contracts/eosio.system/voting.hpp index 4d30d08c22fa7c88bce989b9fc0596d15f2643e9..2fc33075a3d4f30f7fc66c9b932f3ddc2725152d 100644 --- a/contracts/eosio.system/voting.hpp +++ b/contracts/eosio.system/voting.hpp @@ -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* 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* 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 ); diff --git a/contracts/libc++/CMakeLists.txt b/contracts/libc++/CMakeLists.txt index d59707a64ccc2117491a65c63aec18ee390a3472..6fc747de469768852b95d4f1004747c792a8f47e 100644 --- a/contracts/libc++/CMakeLists.txt +++ b/contracts/libc++/CMakeLists.txt @@ -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}")