Skip to content

Commit

Permalink
Adding docs and test
Browse files Browse the repository at this point in the history
  • Loading branch information
revflash committed Mar 29, 2016
1 parent dd379fa commit 6af3f63
Show file tree
Hide file tree
Showing 30 changed files with 7,215 additions and 89 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ endif()

add_subdirectory( libraries )
add_subdirectory( programs )
add_subdirectory( tests )


if (ENABLE_INSTALLER)
Expand Down
93 changes: 82 additions & 11 deletions libraries/chain/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ void database::open( const fc::path& data_dir, uint64_t initial_supply )
("last_block->block_num()",last_block->block_num())( "head_block_num", head_block_num()) );
}
}
//idump((head_block_id())(head_block_num()));
}
FC_CAPTURE_LOG_AND_RETHROW( (data_dir) )
}
Expand Down Expand Up @@ -164,7 +163,6 @@ void database::close(bool rewind)
try
{
uint32_t cutoff = get_dynamic_global_properties().last_irreversible_block_num;
//idump((head_block_num()));
//ilog( "rewinding to last irreversible block number ${c}", ("c",cutoff) );

clear_pending();
Expand Down Expand Up @@ -355,6 +353,7 @@ void database::update_account_bandwidth( const account_object& a, uint32_t trx_s
fc::uint128 account_average_bandwidth( acnt.average_bandwidth );
fc::uint128 max_virtual_bandwidth( props.max_virtual_bandwidth );

// account_vshares / total_vshares > account_average_bandwidth / max_virtual_bandwidth
FC_ASSERT( (account_vshares * max_virtual_bandwidth) > (account_average_bandwidth * total_vshares),
"account exceeded maximum allowed bandwidth per vesting share",
("account_vshares",account_vshares)
Expand Down Expand Up @@ -396,6 +395,8 @@ void database::update_account_market_bandwidth( const account_object& a, uint32_

fc::uint128 account_average_bandwidth( acnt.average_market_bandwidth );
fc::uint128 max_virtual_bandwidth( props.max_virtual_bandwidth / 10 ); /// only 10% of bandwidth can be market

// account_vshares / total_vshares > account_average_bandwidth / max_virtual_bandwidth
FC_ASSERT( (account_vshares * max_virtual_bandwidth) > (account_average_bandwidth * total_vshares),
"account exceeded maximum allowed market bandwidth per vesting share",
("account_vshares",account_vshares)
Expand Down Expand Up @@ -430,6 +431,12 @@ bool database::before_last_checkpoint()const
return (_checkpoints.size() > 0) && (_checkpoints.rbegin()->first >= head_block_num());
}

/**
* Push block "may fail" in which case every partial change is unwound. After
* push block is successful the block is appended to the chain database on disk.
*
* @return true if we switched forks as a result of this push.
*/
bool database::push_block(const signed_block& new_block, uint32_t skip)
{
bool result;
Expand Down Expand Up @@ -574,13 +581,11 @@ signed_block database::generate_block(
uint32_t skip /* = 0 */
)
{
set_producing( true );
signed_block result;
detail::with_skip_flags( *this, skip, [&]()
{
result = _generate_block( when, witness_owner, block_signing_private_key );
} );
set_producing( false );
return result;
}

Expand Down Expand Up @@ -844,9 +849,8 @@ fc::sha256 database::get_pow_target()const {
*/
void database::update_witness_schedule()
{
const auto& props = get_dynamic_global_properties();
const auto& props = get_dynamic_global_properties();
const witness_schedule_object& wso = witness_schedule_id_type()(*this);
//idump((wso.next_shuffle_block_num)(props.num_pow_witnesses) );
if( (head_block_num() % STEEMIT_MAX_MINERS) == 0 ) //wso.next_shuffle_block_num )
{
vector<string> active_witnesses;
Expand Down Expand Up @@ -1019,6 +1023,10 @@ void database::clear_witness_votes( const account_object& a ) {
}
}

/**
* This method recursively tallies children_rshares2 for this post plus all of its parents,
* TODO: this method can be skipped for validation-only nodes
*/
void database::adjust_rshares2( const comment_object& c, fc::uint128_t old_rshares2, fc::uint128_t new_rshares2 ) {

modify( c, [&](comment_object& comment ){
Expand All @@ -1039,6 +1047,13 @@ void database::process_vesting_withdrawals() {
while( current != widx.end() && current->next_vesting_withdrawal <= head_block_time() ) {
const auto& cur = *current; ++current;

/**
* Let T = total tokens in vesting fund
* Let V = total vesting shares
* Let v = total vesting shares being cashed out
*
* The user may withdraw vT / V tokens
*/
share_type withdrawn_vesting;
if ( cur.to_withdraw - cur.withdrawn < cur.vesting_withdraw_rate.amount )
withdrawn_vesting = std::min( cur.vesting_shares.amount, cur.to_withdraw % cur.vesting_withdraw_rate.amount ).value;
Expand Down Expand Up @@ -1083,6 +1098,7 @@ void database::adjust_total_payout( const comment_object& cur, const asset& sbd_
if( c.total_payout_value.symbol == sbd_created.symbol )
c.total_payout_value += sbd_created;
});
/// TODO: potentially modify author's total payout numbers as well
}

/**
Expand All @@ -1103,32 +1119,44 @@ void database::cashout_comment_helper( const comment_object& cur, const comment_
auto sbd_created = create_sbd( author, sbd_reward );
adjust_total_payout( cur, sbd_created + to_sbd( vesting_steem_reward ) );

/// push virtual operation for this reward payout
push_applied_operation( comment_reward_operation( cur.author, cur.permlink, origin.author, origin.permlink, sbd_created, vest_created ) );

/// only recurse if the SBD created is more than $0.02, this should stop recursion quickly for
/// small payouts.
if( sbd_created > asset( 20, SBD_SYMBOL ) )
{
const auto& parent = get_comment( cur.parent_author, cur.parent_permlink );
sbd_created.amount *= 2;
sbd_created.amount *= 2; /// 50/50 VESTING SBD means total value is 2x

cashout_comment_helper( parent, origin, parent_vesting_steem_reward, parent_sbd_reward );
} else {
} else { /// parent gets the full change, recursion stops

const auto& parent_author = get_account(cur.parent_author);
vest_created = create_vesting( parent_author, vesting_steem_reward );
sbd_created = create_sbd( parent_author, sbd_reward );

/// THE FOLLOWING IS NOT REQUIRED FOR VALIDATION
push_applied_operation( comment_reward_operation( cur.parent_author, cur.parent_permlink, origin.author, origin.permlink, sbd_created, vest_created ) );
adjust_total_payout( get_comment( cur.parent_author, cur.parent_permlink ), sbd_created + to_sbd( vesting_steem_reward ) );
}
} else {
} else { /// no parent, everything goes to the post
auto vest_created = create_vesting( author, vesting_steem_reward );
auto sbd_created = create_sbd( author, sbd_reward );

/// THE FOLLOWING IS NOT REQUIRED FOR VALIDATION
/// push virtual operation for this reward payout
push_applied_operation( comment_reward_operation( cur.author, cur.permlink, origin.author, origin.permlink, sbd_created, vest_created ) );
adjust_total_payout( cur, sbd_created + to_sbd( vesting_steem_reward ) );
}
}

/**
* This method will iterate through all comment_vote_objects and give them
* (max_rewards * weight) / c.total_vote_weight.
*
* @returns unclaimed rewards.
*/
share_type database::pay_curators( const comment_object& c, share_type max_rewards )
{
u256 total_weight( c.total_vote_weight );
Expand All @@ -1155,6 +1183,9 @@ share_type database::pay_curators( const comment_object& c, share_type max_rewar
}

void database::process_comment_cashout() {
/// don't allow any content to get paid out until the website is ready to launch
/// and people have had a week to start posting. The first cashout will be the biggest because it
/// will represent 2+ months of rewards.
if( head_block_time() < STEEMIT_FIRST_CASHOUT_TIME )
return;

Expand Down Expand Up @@ -1199,6 +1230,10 @@ void database::process_comment_cashout() {


modify( cur, [&]( comment_object& c ) {
/**
* A payout is only made for positive rshares, negative rshares hang around
* for the next time this post might get an upvote.
*/
if( c.net_rshares > 0 )
c.net_rshares = 0;
c.abs_rshares = 0;
Expand All @@ -1215,6 +1250,16 @@ void database::process_comment_cashout() {
}
}

/**
* Overall the network has an inflation rate of 102% of virtual steem per year
* 90% of inflation is directed to vesting shares
* 10% of inflation is directed to subjective proof of work voting
* 1% of inflation is directed to liquidity providers
* 1% of inflation is directed to block producers
*
* This method pays out vesting and reward shares every block, and liquidity shares once per day.
* This method does not pay out witnesses.
*/
void database::process_funds() {
const auto& props = get_dynamic_global_properties();

Expand Down Expand Up @@ -1304,6 +1349,11 @@ void database::pay_liquidity_reward() {
}
}

/**
* Iterates over all conversion requests with a conversion date before
* the head block time and then converts them to/from steem/sbd at the
* current median price feed history price times the premium
*/
void database::process_conversions() {
auto now = head_block_time();
const auto& request_by_date = get_index_type<convert_index>().indices().get<by_conversion_date>();
Expand Down Expand Up @@ -1358,6 +1408,10 @@ asset database::to_steem( const asset& sbd )const {
return sbd * feed_history.current_median_history;
}

/**
* This method reduces the rshare^2 supply and returns the number of tokens are
* redeemed.
*/
share_type database::claim_rshare_reward( share_type rshares ) {
FC_ASSERT( rshares > 0 );

Expand Down Expand Up @@ -1777,6 +1831,7 @@ void database::_apply_transaction(const signed_transaction& trx)
++_current_op_in_trx;
}


} FC_CAPTURE_AND_RETHROW( (trx) ) }

void database::apply_operation(transaction_evaluation_state& eval_state, const operation& op)
Expand Down Expand Up @@ -1859,11 +1914,27 @@ void database::update_global_dynamic_data( const signed_block& b )
dgp.current_aslot += missed_blocks+1;
dgp.average_block_size = (99 * dgp.average_block_size + block_size)/100;

/**
* About once per minute the average network use is consulted and used to
* adjust the reserve ratio. Anything above 50% usage reduces the ratio by
* half which should instantly bring the network from 50% to 25% use unless
* the demand comes from users who have surplus capacity. In other words,
* a 50% reduction in reserve ratio does not result in a 50% reduction in usage,
* it will only impact users who where attempting to use more than 50% of their
* capacity.
*
* When the reserve ratio is at its max (10,000) a 50% reduction will take 3 to
* 4 days to return back to maximum. When it is at its minimum it will return
* back to its prior level in just a few minutes.
*
* If the network reserve ratio falls under 100 then it is probably time to
* increase the capacity of the network.
*/
if( dgp.head_block_number % 20 == 0 ) {
if( dgp.average_block_size > dgp.maximum_block_size/2 )
{
dgp.current_reserve_ratio /= 2;
} else {
dgp.current_reserve_ratio /= 2; /// exponential back up
} else { /// linear growth... not much fine grain control near full capacity
dgp.current_reserve_ratio++;
}
}
Expand Down
1 change: 0 additions & 1 deletion libraries/chain/get_config.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#include <steemit/chain/get_config.hpp>
#include <steemit/chain/config.hpp>
#include <steemit/chain/protocol/types.hpp>
Expand Down
72 changes: 51 additions & 21 deletions libraries/chain/include/steemit/chain/account_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ namespace steemit { namespace chain {
static const uint8_t type_id = impl_account_object_type;

string name;
authority owner;
authority active;
authority posting;
authority owner; ///< used for backup control, can set owner or active
authority active; ///< used for all monetary operations, can set active or posting
authority posting; ///< used for voting and posting
public_key_type memo_key;
string json_metadata;
string proxy;
Expand All @@ -30,27 +30,51 @@ namespace steemit { namespace chain {
uint32_t comment_count = 0;
uint32_t lifetime_vote_count = 0;

uint16_t voting_power = STEEMIT_100_PERCENT;
time_point_sec last_vote_time;

asset balance = asset( 0, STEEM_SYMBOL );

uint16_t voting_power = STEEMIT_100_PERCENT; ///< current voting power of this account, it falls after every vote
time_point_sec last_vote_time; ///< used to increase the voting power of this account the longer it goes without voting.

asset balance = asset( 0, STEEM_SYMBOL ); ///< total liquid shares held by this account

/**
* SBD Deposits pay interest based upon the interest rate set by witnesses. The purpose of these
* fields is to track the total (time * sbd_balance) that it is held. Then at the appointed time
* interest can be paid using the following equation:
*
* interest = interest_rate * sbd_seconds / seconds_per_year
*
* Every time the sbd_balance is updated the sbd_seconds is also updated. If at least
* STEEMIT_MIN_COMPOUNDING_INTERVAL_SECONDS has past since sbd_last_interest_payment then
* interest is added to sbd_balance.
*
* @defgroup sbd_data sbd Balance Data
*/
///@{
asset sbd_balance = asset( 0, SBD_SYMBOL );
fc::uint128_t sbd_seconds;
fc::time_point_sec sbd_seconds_last_update;
fc::time_point_sec sbd_last_interest_payment;
asset sbd_balance = asset( 0, SBD_SYMBOL ); /// total sbd balance
fc::uint128_t sbd_seconds; ///< total sbd * how long it has been hel
fc::time_point_sec sbd_seconds_last_update; ///< the last time the sbd_seconds was updated
fc::time_point_sec sbd_last_interest_payment; ///< used to pay interest at most once per month
///@}


asset vesting_shares = asset( 0, VESTS_SYMBOL );
asset vesting_withdraw_rate = asset( 0, VESTS_SYMBOL );
time_point_sec next_vesting_withdrawal = fc::time_point_sec::maximum();
share_type withdrawn = 0;
share_type to_withdraw = 0;

share_type proxied_vsf_votes;

asset vesting_shares = asset( 0, VESTS_SYMBOL ); ///< total vesting shares held by this account, controls its voting power
asset vesting_withdraw_rate = asset( 0, VESTS_SYMBOL ); ///< at the time this is updated it can be at most vesting_shares/104
time_point_sec next_vesting_withdrawal = fc::time_point_sec::maximum(); ///< after every withdrawal this is incremented by 1 week
share_type withdrawn = 0; /// Track how many shares have been withdrawn
share_type to_withdraw = 0; /// Might be able to look this up with operation history.

share_type proxied_vsf_votes; ///< the total VFS votes proxied to this account

/**
* This field tracks the average bandwidth consumed by this account and gets updated every time a transaction
* is produced by this account using the following equation. It has units of micro-bytes-per-second.
*
* W = STEEMIT_BANDWIDTH_AVERAGE_WINDOW_SECONDS = 1 week in seconds
* S = now - last_bandwidth_update
* N = fc::raw::packsize( transaction ) * 1,000,000
*
* average_bandwidth = MIN(0,average_bandwidth * (W-S) / W) + N * S / W
* last_bandwidth_update = T + S
*/
uint64_t average_bandwidth = 0;
uint64_t lifetime_bandwidth = 0;
time_point_sec last_bandwidth_update;
Expand All @@ -64,6 +88,10 @@ namespace steemit { namespace chain {
share_type witness_vote_weight()const { return vesting_shares.amount + proxied_vsf_votes; }
};

/**
* @brief This secondary index will allow a reverse lookup of all accounts that a particular key or account
* is an potential signing authority.
*/
class account_member_index : public secondary_index
{
public:
Expand All @@ -72,6 +100,7 @@ namespace steemit { namespace chain {
virtual void about_to_modify( const object& before ) override;
virtual void object_modified( const object& after ) override;

/** given an account or key, map it to the set of accounts that reference it in an active or owner authority */
map< string, set<string> > account_to_account_memberships;
map< public_key_type, set<string> > account_to_key_memberships;

Expand Down Expand Up @@ -123,5 +152,6 @@ FC_REFLECT_DERIVED( steemit::chain::account_object, (graphene::db::object),
(vesting_shares)(vesting_withdraw_rate)(next_vesting_withdrawal)(withdrawn)(to_withdraw)
(proxied_vsf_votes)
(average_bandwidth)(lifetime_bandwidth)(last_bandwidth_update)
(average_market_bandwidth)(last_market_bandwidth_update)(last_post)
(average_market_bandwidth)(last_market_bandwidth_update)
(last_post)
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
namespace steemit { namespace chain {
using namespace graphene::db;

/**
* @brief tracks minimal information about past blocks to implement TaPOS
* @ingroup object
*
* When attempting to calculate the validity of a transaction we need to
* lookup a past block and check its block hash and the time it occurred
* so we can calculate whether the current transaction is valid and at
* what time it should expire.
*/
class block_summary_object : public abstract_object<block_summary_object>
{
public:
Expand Down
Loading

0 comments on commit 6af3f63

Please sign in to comment.