Skip to content
This repository has been archived by the owner on Oct 4, 2019. It is now read-only.

Commit

Permalink
Implement payments for approved works #1024
Browse files Browse the repository at this point in the history
  • Loading branch information
maslenitsa93 committed Jan 18, 2019
1 parent 7958127 commit 6ad664c
Show file tree
Hide file tree
Showing 16 changed files with 231 additions and 86 deletions.
2 changes: 2 additions & 0 deletions libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ if(BUILD_SHARED_LIBRARIES)
shared_authority.cpp
# transaction_object.cpp
block_log.cpp
evaluator.cpp
proposal_object.cpp
proposal_evaluator.cpp
database_proposal_object.cpp
Expand Down Expand Up @@ -80,6 +81,7 @@ else()
shared_authority.cpp
# transaction_object.cpp
block_log.cpp
evaluator.cpp
proposal_object.cpp
proposal_evaluator.cpp
database_proposal_object.cpp
Expand Down
3 changes: 2 additions & 1 deletion libraries/chain/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1309,7 +1309,7 @@ namespace golos { namespace chain {
}
}

inline const void database::push_virtual_operation(const operation &op, bool force) {
const void database::push_virtual_operation(const operation &op, bool force) {
if (!force && _skip_virtual_ops ) {
return;
}
Expand Down Expand Up @@ -3663,6 +3663,7 @@ namespace golos { namespace chain {
process_funds();
process_conversions();
process_comment_cashout();
process_worker_cashout();
process_vesting_withdrawals();
process_savings_withdraws();
pay_liquidity_reward();
Expand Down
41 changes: 41 additions & 0 deletions libraries/chain/database_worker_objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,45 @@ namespace golos { namespace chain {
return find<worker_techspec_object, by_worker_result>(std::make_tuple(author, permlink));
}

void database::process_worker_cashout() {
if (!has_hardfork(STEEMIT_HARDFORK_0_20__1013)) {
return;
}

const auto now = head_block_time();

const auto& wto_idx = get_index<worker_techspec_index, by_next_cashout_time>();

for (auto wto_itr = wto_idx.begin(); wto_itr != wto_idx.end() && wto_itr->next_cashout_time <= now; ++wto_itr) {
const auto& wpo = get_worker_proposal(wto_itr->worker_proposal_author, wto_itr->worker_proposal_permlink);

const auto& reward = wto_itr->development_cost / wto_itr->payments_count;

const auto& gpo = get_dynamic_global_properties();
modify(gpo, [&](dynamic_global_property_object& gpo) {
gpo.total_worker_fund_steem -= reward;
});

adjust_balance(get_account(wto_itr->worker), reward);

if (wto_itr->finished_payments_count+1 == wto_itr->payments_count) {
modify(*wto_itr, [&](worker_techspec_object& wto) {
wto.finished_payments_count++;
wto.next_cashout_time = time_point_sec::maximum();
});

modify(wpo, [&](worker_proposal_object& wpo) {
wpo.state = worker_proposal_state::closed;
});
} else {
modify(*wto_itr, [&](worker_techspec_object& wto) {
wto.finished_payments_count++;
wto.next_cashout_time = now + wto.payments_interval;
});
}

push_virtual_operation(worker_reward_operation(wto_itr->worker, wto_itr->author, to_string(wto_itr->permlink), reward));
}
}

} } // golos::chain
53 changes: 53 additions & 0 deletions libraries/chain/evaluator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <golos/chain/evaluator.hpp>

namespace golos { namespace chain {

asset get_balance(const account_object &account, balance_type type, asset_symbol_type symbol) {
switch(type) {
case MAIN_BALANCE:
switch (symbol) {
case STEEM_SYMBOL:
return account.balance;
case SBD_SYMBOL:
return account.sbd_balance;
default:
GOLOS_CHECK_VALUE(false, "invalid symbol");
}
case SAVINGS:
switch (symbol) {
case STEEM_SYMBOL:
return account.savings_balance;
case SBD_SYMBOL:
return account.savings_sbd_balance;
default:
GOLOS_CHECK_VALUE(false, "invalid symbol");
}
case VESTING:
GOLOS_CHECK_VALUE(symbol == VESTS_SYMBOL, "invalid symbol");
return account.vesting_shares;
case EFFECTIVE_VESTING:
GOLOS_CHECK_VALUE(symbol == VESTS_SYMBOL, "invalid symbol");
return account.effective_vesting_shares();
case HAVING_VESTING:
GOLOS_CHECK_VALUE(symbol == VESTS_SYMBOL, "invalid symbol");
return account.available_vesting_shares(false);
case AVAILABLE_VESTING:
GOLOS_CHECK_VALUE(symbol == VESTS_SYMBOL, "invalid symbol");
return account.available_vesting_shares(true);
default: FC_ASSERT(false, "invalid balance type");
}
}

std::string get_balance_name(balance_type type) {
switch(type) {
case MAIN_BALANCE: return "fund";
case SAVINGS: return "savings";
case VESTING: return "vesting shares";
case EFFECTIVE_VESTING: return "effective vesting shares";
case HAVING_VESTING: return "having vesting shares";
case AVAILABLE_VESTING: return "available vesting shares";
default: FC_ASSERT(false, "invalid balance type");
}
}

} } // golos::chain
4 changes: 3 additions & 1 deletion libraries/chain/include/golos/chain/database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ namespace golos { namespace chain {

void notify_post_apply_operation(const operation_notification &note);

inline const void push_virtual_operation(const operation &op, bool force = false); // vops are not needed for low mem. Force will push them on low mem.
const void push_virtual_operation(const operation &op, bool force = false); // vops are not needed for low mem. Force will push them on low mem.
void notify_applied_block(const signed_block &block);

void notify_on_pending_transaction(const signed_transaction &tx);
Expand Down Expand Up @@ -449,6 +449,8 @@ namespace golos { namespace chain {

void process_comment_cashout();

void process_worker_cashout();

void process_funds();

void process_conversions();
Expand Down
26 changes: 26 additions & 0 deletions libraries/chain/include/golos/chain/evaluator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <golos/protocol/exceptions.hpp>
#include <golos/protocol/operations.hpp>
#include <golos/chain/account_object.hpp>

#define ASSERT_REQ_HF_IN_DB(HF, FEATURE, DATABASE) \
GOLOS_ASSERT(DATABASE.has_hardfork(HF), unsupported_operation, \
Expand All @@ -11,6 +12,18 @@
#define ASSERT_REQ_HF(HF, FEATURE) \
ASSERT_REQ_HF_IN_DB(HF, FEATURE, _db)
#define GOLOS_CHECK_BALANCE(ACCOUNT, TYPE, REQUIRED ...) \
FC_EXPAND_MACRO( \
FC_MULTILINE_MACRO_BEGIN \
asset exist = get_balance(ACCOUNT, TYPE, (REQUIRED).symbol); \
if( UNLIKELY( exist < (REQUIRED) )) { \
FC_THROW_EXCEPTION( golos::insufficient_funds, \
"Account \"${account}\" does not have enough ${balance}: required ${required}, exist ${exist}", \
("account",ACCOUNT.name)("balance",get_balance_name(TYPE))("required",REQUIRED)("exist",exist)); \
} \
FC_MULTILINE_MACRO_END \
)

namespace golos {
namespace chain {

Expand Down Expand Up @@ -52,6 +65,19 @@ namespace golos {
database &_db;
};

enum balance_type {
MAIN_BALANCE,
SAVINGS,
VESTING,
EFFECTIVE_VESTING,
HAVING_VESTING,
AVAILABLE_VESTING
};

asset get_balance(const account_object &account, balance_type type, asset_symbol_type symbol);

std::string get_balance_name(balance_type type);

}
}

Expand Down
23 changes: 15 additions & 8 deletions libraries/chain/include/golos/chain/worker_objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,8 @@ namespace golos { namespace chain {
shared_string permlink;
worker_proposal_type type;
worker_proposal_state state;
asset deposit;
account_name_type approved_techspec_author;
shared_string approved_techspec_permlink;
account_name_type worker;
time_point_sec work_beginning_time;
uint8_t worker_payments_count;
time_point_sec payment_beginning_time;
time_point_sec created;
time_point_sec modified;
};
Expand All @@ -62,10 +57,15 @@ namespace golos { namespace chain {
uint32_t specification_eta;
asset development_cost;
uint32_t development_eta;
uint16_t payments_count;
uint32_t payments_interval;
account_name_type worker;
time_point_sec work_beginning_time;
shared_string worker_result_permlink;
time_point_sec completion_date;
uint16_t payments_count;
uint32_t payments_interval;
time_point_sec payment_beginning_time;
time_point_sec next_cashout_time = time_point_sec::maximum();
uint8_t finished_payments_count = 0;
};

class worker_techspec_approve_object : public object<worker_techspec_approve_object_type, worker_techspec_approve_object> {
Expand Down Expand Up @@ -125,6 +125,7 @@ namespace golos { namespace chain {

struct by_worker_proposal;
struct by_worker_result;
struct by_next_cashout_time;

using worker_techspec_index = multi_index_container<
worker_techspec_object,
Expand Down Expand Up @@ -158,7 +159,13 @@ namespace golos { namespace chain {
member<worker_techspec_object, shared_string, &worker_techspec_object::worker_result_permlink>>,
composite_key_compare<
std::less<account_name_type>,
chainbase::strcmp_less>>>,
chainbase::strcmp_less>>,
ordered_unique<
tag<by_next_cashout_time>,
composite_key<
worker_techspec_object,
member<worker_techspec_object, time_point_sec, &worker_techspec_object::next_cashout_time>,
member<worker_techspec_object, worker_techspec_object_id_type, &worker_techspec_object::id>>>>,
allocator<worker_techspec_object>>;

struct by_techspec_approver;
Expand Down
69 changes: 0 additions & 69 deletions libraries/chain/steem_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,6 @@
#include <golos/chain/block_summary_object.hpp>
#include <golos/chain/worker_objects.hpp>

#define GOLOS_CHECK_BALANCE(ACCOUNT, TYPE, REQUIRED ...) \
FC_EXPAND_MACRO( \
FC_MULTILINE_MACRO_BEGIN \
asset exist = get_balance(ACCOUNT, TYPE, (REQUIRED).symbol); \
if( UNLIKELY( exist < (REQUIRED) )) { \
FC_THROW_EXCEPTION( golos::insufficient_funds, \
"Account \"${account}\" does not have enough ${balance}: required ${required}, exist ${exist}", \
("account",ACCOUNT.name)("balance",get_balance_name(TYPE))("required",REQUIRED)("exist",exist)); \
} \
FC_MULTILINE_MACRO_END \
)

#define GOLOS_CHECK_BANDWIDTH(NOW, NEXT, TYPE, MSG, ...) \
GOLOS_ASSERT((NOW) > (NEXT), golos::bandwidth_exception, MSG, \
("bandwidth",TYPE)("now",NOW)("next",NEXT) __VA_ARGS__)
Expand All @@ -25,63 +13,6 @@
namespace golos { namespace chain {
using fc::uint128_t;

enum balance_type {
MAIN_BALANCE,
SAVINGS,
VESTING,
EFFECTIVE_VESTING,
HAVING_VESTING,
AVAILABLE_VESTING
};

asset get_balance(const account_object &account, balance_type type, asset_symbol_type symbol) {
switch(type) {
case MAIN_BALANCE:
switch (symbol) {
case STEEM_SYMBOL:
return account.balance;
case SBD_SYMBOL:
return account.sbd_balance;
default:
GOLOS_CHECK_VALUE(false, "invalid symbol");
}
case SAVINGS:
switch (symbol) {
case STEEM_SYMBOL:
return account.savings_balance;
case SBD_SYMBOL:
return account.savings_sbd_balance;
default:
GOLOS_CHECK_VALUE(false, "invalid symbol");
}
case VESTING:
GOLOS_CHECK_VALUE(symbol == VESTS_SYMBOL, "invalid symbol");
return account.vesting_shares;
case EFFECTIVE_VESTING:
GOLOS_CHECK_VALUE(symbol == VESTS_SYMBOL, "invalid symbol");
return account.effective_vesting_shares();
case HAVING_VESTING:
GOLOS_CHECK_VALUE(symbol == VESTS_SYMBOL, "invalid symbol");
return account.available_vesting_shares(false);
case AVAILABLE_VESTING:
GOLOS_CHECK_VALUE(symbol == VESTS_SYMBOL, "invalid symbol");
return account.available_vesting_shares(true);
default: FC_ASSERT(false, "invalid balance type");
}
}

std::string get_balance_name(balance_type type) {
switch(type) {
case MAIN_BALANCE: return "fund";
case SAVINGS: return "savings";
case VESTING: return "vesting shares";
case EFFECTIVE_VESTING: return "effective vesting shares";
case HAVING_VESTING: return "having vesting shares";
case AVAILABLE_VESTING: return "available vesting shares";
default: FC_ASSERT(false, "invalid balance type");
}
}

inline void validate_permlink_0_1(const string &permlink) {
GOLOS_CHECK_VALUE(permlink.size() > STEEMIT_MIN_PERMLINK_LENGTH &&
permlink.size() < STEEMIT_MAX_PERMLINK_LENGTH,
Expand Down
29 changes: 23 additions & 6 deletions libraries/chain/worker_evaluators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,15 @@ namespace golos { namespace chain {
}
}

if (approvers >= STEEMIT_MAJOR_VOTED_WITNESSES) {
_db.modify(wpo, [&](worker_proposal_object& wpo) {
wpo.approved_techspec_author = o.author;
from_string(wpo.approved_techspec_permlink, o.permlink);
wpo.state = worker_proposal_state::techspec;
});
if (approvers < STEEMIT_MAJOR_VOTED_WITNESSES) {
return;
}

_db.modify(wpo, [&](worker_proposal_object& wpo) {
wpo.approved_techspec_author = o.author;
from_string(wpo.approved_techspec_permlink, o.permlink);
wpo.state = worker_proposal_state::techspec;
});
}
}

Expand Down Expand Up @@ -335,6 +337,21 @@ namespace golos { namespace chain {
_db.modify(wpo, [&](worker_proposal_object& wpo) {
wpo.state = worker_proposal_state::payment;
});

_db.modify(wto, [&](worker_techspec_object& wto) {
wto.next_cashout_time = _db.head_block_time() + wto.payments_interval;
wto.payment_beginning_time = wto.next_cashout_time;
});

const auto& gpo = _db.get_dynamic_global_properties();
_db.modify(gpo, [&](dynamic_global_property_object& gpo) {
gpo.total_worker_fund_steem -= wto.specification_cost;
});

_db.adjust_balance(_db.get_account(wto.author), wto.specification_cost);

//
_db.push_virtual_operation(techspec_reward_operation(wto.author, to_string(wto.permlink), wto.specification_cost));
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion libraries/protocol/include/golos/protocol/operations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ namespace golos { namespace protocol {
return_vesting_delegation_operation,
producer_reward_operation,
delegation_reward_operation,
auction_window_reward_operation
auction_window_reward_operation,
techspec_reward_operation,
worker_reward_operation
> operation;

/*void operation_get_required_authorities( const operation& op,
Expand Down
Loading

0 comments on commit 6ad664c

Please sign in to comment.