提交 8c997121 编写于 作者: D Daniel Larimer

Free RAM on undelegate bandwidth Fix #3107

- fix warnings in eosiolib
- remove debug print statements from contracts
- erase the delegate_bw object (didn't actually remove voter info
                                object)
- remove user balance object from token contract when balance goes to 0
上级 854f8d80
......@@ -139,7 +139,7 @@ namespace eosiosystem {
*/
void system_contract::buyram( account_name payer, account_name receiver, asset quant )
{
print( "\n payer: ", eosio::name{payer}, " buys ram for ", eosio::name{receiver}, " with ", quant, "\n" );
// print( "\n payer: ", eosio::name{payer}, " buys ram for ", eosio::name{receiver}, " with ", quant, "\n" );
require_auth( payer );
eosio_assert( quant.amount > 0, "must purchase a positive amount" );
......@@ -148,7 +148,7 @@ namespace eosiosystem {
{ payer, N(eosio), quant, std::string("buy ram") } );
}
print( "free ram: ", _gstate.free_ram(), "\n");
// print( "free ram: ", _gstate.free_ram(), "\n");
int64_t bytes_out;
......@@ -157,7 +157,7 @@ namespace eosiosystem {
bytes_out = es.convert( quant, S(0,RAM) ).amount;
});
print( "ram bytes out: ", bytes_out, "\n" );
// print( "ram bytes out: ", bytes_out, "\n" );
eosio_assert( bytes_out > 0, "must reserve a positive amount" );
......@@ -187,17 +187,19 @@ namespace eosiosystem {
*/
void system_contract::sellram( account_name account, uint64_t bytes ) {
require_auth( account );
int64_t ibytes = static_cast<int64_t>(bytes);
user_resources_table userres( _self, account );
auto res_itr = userres.find( account );
eosio_assert( res_itr != userres.end(), "no resource row" );
eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" );
eosio_assert( res_itr->ram_bytes >= ibytes, "insufficient quota" );
asset tokens_out;
auto itr = _rammarket.find(S(4,RAMEOS));
_rammarket.modify( itr, 0, [&]( auto& es ) {
tokens_out = es.convert( asset(bytes,S(0,RAM)), S(4,EOS) );
print( "out: ", tokens_out, "\n" );
/// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases
tokens_out = es.convert( asset(ibytes,S(0,RAM)), S(4,EOS) );
// print( "out: ", tokens_out, "\n" );
});
_gstate.total_ram_bytes_reserved -= bytes;
......@@ -223,7 +225,7 @@ namespace eosiosystem {
{
require_auth( from );
print( "from: ", eosio::name{from}, " to: ", eosio::name{receiver}, " net: ", stake_net_quantity, " cpu: ", stake_cpu_quantity );
// print( "from: ", eosio::name{from}, " to: ", eosio::name{receiver}, " net: ", stake_net_quantity, " cpu: ", stake_cpu_quantity );
eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" );
eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" );
......@@ -252,7 +254,6 @@ namespace eosiosystem {
});
}
print( "totals" );
user_resources_table totals_tbl( _self, receiver );
auto tot_itr = totals_tbl.find( receiver );
if( tot_itr == totals_tbl.end() ) {
......@@ -275,23 +276,18 @@ namespace eosiosystem {
{ source_stake_from, N(eosio), asset(total_stake), std::string("stake bandwidth") } );
}
print( "voters \n" );
auto from_voter = _voters.find(from);
if( from_voter == _voters.end() ) {
print( " create voter \n" );
from_voter = _voters.emplace( from, [&]( auto& v ) {
v.owner = from;
v.staked = total_stake;
print( " vote weight: ", v.last_vote_weight, "\n" );
});
} else {
_voters.modify( from_voter, 0, [&]( auto& v ) {
v.staked += total_stake;
print( " vote weight: ", v.last_vote_weight, "\n" );
});
}
print( "voteproducer\n" );
if( from_voter->producers.size() || from_voter->proxy ) {
voteproducer( from, from_voter->proxy, from_voter->producers );
}
......@@ -332,10 +328,14 @@ namespace eosiosystem {
eosio_assert( total_refund > 0, "must unstake a positive amount" );
del_tbl.modify( dbw, from, [&]( auto& dbo ){
dbo.net_weight -= unstake_net_quantity;
dbo.cpu_weight -= unstake_cpu_quantity;
});
if( dbw.net_weight == unstake_net_quantity && dbw.cpu_weight == unstake_cpu_quantity ) {
del_tbl.erase( dbw );
} else {
del_tbl.modify( dbw, from, [&]( auto& dbo ){
dbo.net_weight -= unstake_net_quantity;
dbo.cpu_weight -= unstake_cpu_quantity;
});
}
user_resources_table totals_tbl( _self, receiver );
......
......@@ -121,7 +121,8 @@ namespace eosiosystem {
}
double stake2vote( int64_t staked ) {
double weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 );
/// TODO subtract 2080 brings the large numbers closer to this decade
double weight = int64_t( (now() / (seconds_per_day * 7)) ) / double( 52 );
return double(staked) * std::pow( 2, weight );
}
/**
......@@ -174,7 +175,7 @@ namespace eosiosystem {
}
boost::container::flat_map<account_name, pair<double, bool /*new*/> > producer_deltas;
if ( voter->last_vote_weight != 0 ) {
if ( voter->last_vote_weight > 0 ) {
if( voter->proxy ) {
auto old_proxy = _voters.find( voter->proxy );
eosio_assert( old_proxy != _voters.end(), "old proxy not found" ); //data corruption
......@@ -271,7 +272,8 @@ namespace eosiosystem {
new_weight += voter.proxied_vote_weight;
}
if ( new_weight != voter.last_vote_weight ) {
/// don't propagate small changes (1 ~= epsilon)
if ( fabs( new_weight - voter.last_vote_weight ) > 1 ) {
if ( voter.proxy ) {
auto& proxy = _voters.get( voter.proxy, "proxy not found" ); //data corruption
_voters.modify( proxy, 0, [&]( auto& p ) {
......
......@@ -37,7 +37,6 @@ void token::create( account_name issuer,
void token::issue( account_name to, asset quantity, string memo )
{
print( "issue" );
auto sym = quantity.symbol;
eosio_assert( sym.is_valid(), "invalid symbol name" );
......@@ -70,7 +69,6 @@ void token::transfer( account_name from,
asset quantity,
string /*memo*/ )
{
print( "transfer from ", eosio::name{from}, " to ", eosio::name{to}, " ", quantity, "\n" );
eosio_assert( from != to, "cannot transfer to self" );
require_auth( from );
eosio_assert( is_account( to ), "to account does not exist");
......@@ -106,10 +104,13 @@ void token::sub_balance( account_name owner, asset value, const currency_stats&
eosio_assert( false, "insufficient authority" );
}
from_acnts.modify( from, owner, [&]( auto& a ) {
a.balance -= value;
print( eosio::name{owner}, " balance: ", a.balance, "\n" );
});
if( from.balance.amount == value.amount ) {
from_acnts.erase( from );
} else {
from_acnts.modify( from, owner, [&]( auto& a ) {
a.balance -= value;
});
}
}
void token::add_balance( account_name owner, asset value, const currency_stats& st, account_name ram_payer )
......@@ -120,13 +121,11 @@ void token::add_balance( account_name owner, asset value, const currency_stats&
eosio_assert( !st.enforce_whitelist, "can only transfer to white listed accounts" );
to_acnts.emplace( ram_payer, [&]( auto& a ){
a.balance = value;
print( eosio::name{owner}, " balance: ", a.balance, "\n" );
});
} else {
eosio_assert( !st.enforce_whitelist || to->whitelist, "receiver requires whitelist by issuer" );
to_acnts.modify( to, 0, [&]( auto& a ) {
a.balance += value;
print( eosio::name{owner}, " balance: ", a.balance, "\n" );
});
}
}
......
......@@ -159,17 +159,17 @@ namespace eosio {
EOSLIB_SERIALIZE( block_timestamp, (slot) )
private:
static constexpr uint32_t block_interval_ms = 500;
static constexpr uint64_t block_timestamp_epoch = 946684800000ll; // epoch is year 2000
static constexpr int32_t block_interval_ms = 500;
static constexpr int64_t block_timestamp_epoch = 946684800000ll; // epoch is year 2000
void set_time_point(const time_point& t) {
auto micro_since_epoch = t.time_since_epoch();
auto msec_since_epoch = micro_since_epoch.count() / 1000;
slot = uint32_t(( msec_since_epoch - block_timestamp_epoch ) / block_interval_ms);
int64_t micro_since_epoch = t.time_since_epoch().count();
int64_t msec_since_epoch = micro_since_epoch / 1000;
slot = uint32_t(( msec_since_epoch - block_timestamp_epoch ) / int64_t(block_interval_ms));
}
void set_time_point(const time_point_sec& t) {
uint64_t sec_since_epoch = t.sec_since_epoch();
int64_t sec_since_epoch = t.sec_since_epoch();
slot = uint32_t((sec_since_epoch * 1000 - block_timestamp_epoch) / block_interval_ms);
}
}; // block_timestamp
......
......@@ -91,7 +91,7 @@ namespace eosio {
tmp >>= (i == 0 ? 4 : 5);
}
trim_right_if( str, []( char c ){ return c == '.'; } );
trim_right_dots( str );
return str;
}
......@@ -99,8 +99,7 @@ namespace eosio {
account_name value = 0;
private:
template<typename Lambda>
static void trim_right_if(std::string& str, Lambda&& l ) {
static void trim_right_dots(std::string& str ) {
const auto last = str.find_last_not_of('.');
if (last != std::string::npos)
str = str.substr(0, last + 1);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册