23 #include <boost/range/adaptor/transformed.hpp>
24 #include <boost/range/algorithm/transform.hpp>
25 #include <boost/range/algorithm_ext/copy_n.hpp>
26 #include <scorum/utils/take_n_range.hpp>
27 #include <scorum/utils/collect_range_adaptor.hpp>
33 namespace database_ns {
38 : _content_reward_service(ctx.services().content_reward_scr_service())
39 , _dev_pool_service(ctx.services().dev_pool_service())
40 , _dprops_service(ctx.services().dynamic_global_property_service())
41 , _fund_budget_service(ctx.services().fund_budget_service())
42 , _post_budget_service(ctx.services().post_budget_service())
43 , _banner_budget_service(ctx.services().banner_budget_service())
44 , _account_service(ctx.services().account_service())
45 , _adv_property_svc(ctx.services().advertising_property_service())
46 , _virt_op_emitter(ctx)
47 , _voter_reward_scr_svc(ctx.services().voters_reward_scr_service())
48 , _voter_reward_sp_svc(ctx.services().voters_reward_sp_service())
49 , _content_reward_fund_scr_svc(ctx.services().content_reward_fund_scr_service())
50 , _content_reward_fund_sp_svc(ctx.services().content_reward_fund_sp_service())
51 , _hardfork_svc(ctx.services().hardfork_property_service())
52 , _witness_svc(ctx.services().witness_service())
54 , _block_num(ctx.block_num())
60 if (apply_mainnet_schedule_crutches())
73 original_fund_reward += _fund_budget_service.
allocate_cash(_fund_budget_service.
get());
75 distribute_reward(original_fund_reward);
77 auto adv_budgets_reward = run_auction_round();
82 auto dev_team_reward = adv_budgets_reward * dev_team_reward_factor;
84 _dev_pool_service.
update([&](dev_committee_object& dco) { dco.scr_balance += dev_team_reward; });
92 distribute_reward(users_reward);
97 asset process_funds::run_auction_round()
99 advertising_auction auction(_dprops_service, _adv_property_svc, _post_budget_service, _banner_budget_service);
102 auto post_budgets_reward = process_adv_pending_payouts(_post_budget_service);
103 auto banner_budgets_reward = process_adv_pending_payouts(_banner_budget_service);
104 auto adv_budgets_reward = post_budgets_reward + banner_budgets_reward;
106 close_empty_budgets(_post_budget_service);
107 close_empty_budgets(_banner_budget_service);
109 return adv_budgets_reward;
112 template <budget_type budget_type_v>
117 std::vector<budget_outgo_operation> allocated_cash_ops;
118 std::vector<budget_owner_income_operation> returned_cash_ops;
121 if (budget.budget_pending_outgo.amount > 0)
122 allocated_cash_ops.emplace_back(budget_type_v, budget.owner, budget.id._id, budget.budget_pending_outgo);
124 if (budget.owner_pending_income.amount > 0)
125 returned_cash_ops.emplace_back(budget_type_v, budget.owner, budget.id._id, budget.owner_pending_income);
130 for (
const auto& op : allocated_cash_ops)
133 for (
const auto& op : returned_cash_ops)
136 return adv_budgets_reward;
139 template <budget_type budget_type_v>
140 void process_funds::close_empty_budgets(adv_budget_service_i<budget_type_v>& budget_svc)
142 auto empty_budgets = budget_svc.get_empty_budgets();
144 for (
const auto& b : empty_budgets)
146 _virt_op_emitter.
push_virtual_operation(budget_closing_operation(budget_type_v, b.get().owner, b.get().id._id));
148 budget_svc.remove(b);
152 void process_funds::distribute_reward(
const asset& users_reward)
158 asset content_reward = users_reward - witness_reward - active_sp_holder_reward;
161 process_witness_reward_in_sp_migration().adjust_witness_reward(_ctx, witness_reward);
163 FC_ASSERT(content_reward.amount >= 0,
"content_reward(${r}) must not be less zero", (
"r", content_reward));
165 distribute_witness_reward(witness_reward);
167 distribute_active_sp_holders_reward(active_sp_holder_reward);
169 pay_content_reward(content_reward);
172 void process_funds::distribute_witness_reward(
const asset& witness_reward)
178 wlog(
"Encountered unknown witness type for witness: ${w}", (
"w", cwit.owner));
181 const auto& witness = _account_service.
get_account(cwit.owner);
183 pay_witness_reward(witness, witness_reward);
185 if (witness_reward.amount != 0)
189 void process_funds::distribute_active_sp_holders_reward(
const asset& reward)
191 asset total_reward = get_activity_reward(reward);
193 asset distributed_reward = asset(0, reward.symbol());
196 if (!active_sp_holders_array.empty())
199 asset total_sp = std::accumulate(active_sp_holders_array.begin(), active_sp_holders_array.end(),
200 asset(0,
SP_SYMBOL), [&](asset& accumulator,
const account_object& account) {
201 return accumulator += account.vote_reward_competitive_sp;
204 if (total_sp.amount > 0)
207 for (
const account_object& account : active_sp_holders_array)
211 = total_reward * utils::make_fraction(account.vote_reward_competitive_sp.amount, total_sp.amount);
215 pay_account_pending_reward(account, account_reward);
219 pay_account_reward(account, account_reward);
222 distributed_reward += account_reward;
224 if (!_hardfork_svc.
has_hardfork(SCORUM_HARDFORK_0_2) && account_reward.amount > 0)
226 rewarded[account.name] = account_reward;
230 if (!_hardfork_svc.
has_hardfork(SCORUM_HARDFORK_0_2) && !rewarded.empty())
233 active_sp_holders_reward_legacy_operation{ std::move(rewarded) });
239 pay_activity_reward(total_reward - distributed_reward);
242 void process_funds::pay_account_reward(
const account_object& account,
const asset& reward)
244 if (reward.amount <= 0)
257 void process_funds::pay_account_pending_reward(
const account_object& account,
const asset& reward)
259 if (reward.amount <= 0)
272 void process_funds::pay_witness_reward(
const account_object& witness,
const asset& reward)
276 _dprops_service.
update([&](dynamic_global_property_object& p) { p.total_witness_reward_scr += reward; });
280 _dprops_service.
update([&](dynamic_global_property_object& p) { p.total_witness_reward_sp += reward; });
283 pay_account_reward(witness, reward);
286 void process_funds::pay_content_reward(
const asset& reward)
288 if (reward.amount <= 0)
293 _content_reward_fund_scr_svc.
update(
298 _content_reward_fund_sp_svc.
update(
303 void process_funds::pay_activity_reward(
const asset& reward)
305 if (reward.amount <= 0)
310 reward_balance_algorithm<voters_reward_scr_service_i> balancer(_voter_reward_scr_svc);
311 balancer.increase_ballance(reward);
315 reward_balance_algorithm<voters_reward_sp_service_i> balancer(_voter_reward_sp_svc);
316 balancer.increase_ballance(reward);
320 const asset process_funds::get_activity_reward(
const asset& reward)
324 reward_balance_algorithm<voters_reward_scr_service_i> balancer(_voter_reward_scr_svc);
325 return reward + balancer.take_block_reward();
329 reward_balance_algorithm<voters_reward_sp_service_i> balancer(_voter_reward_sp_svc);
330 return reward + balancer.take_block_reward();
334 bool process_funds::apply_mainnet_schedule_crutches()
339 if (_block_num == 1650380 ||
340 _block_num == 1808664)
block_info & get_block_info() const
process_funds(block_task_context &)
virtual void on_apply(block_task_context &)
const asset & increase_ballance(const asset &delta)
const asset take_block_reward()
account_name_type current_witness
Head block signed by current witness.
#define SCORUM_WITNESS_PER_BLOCK_REWARD_PERCENT
#define SCORUM_100_PERCENT
#define SCORUM_ACTIVE_SP_HOLDERS_PER_BLOCK_REWARD_PERCENT
#define SCORUM_DEV_TEAM_PER_BLOCK_REWARD_PERCENT
#define debug_log(CTX, FORMAT,...)
reward_fund_object< content_reward_fund_sp_object_type, SP_SYMBOL > content_reward_fund_sp_object
reward_fund_object< content_reward_fund_scr_object_type, SCORUM_SYMBOL > content_reward_fund_scr_object
virtual const asset create_scorumpower(const account_object &to_account, const asset &scorum)=0
virtual const account_object & get_account(const account_name_type &) const =0
virtual void increase_balance(const account_object &account, const asset &amount)=0
virtual void increase_pending_balance(const account_object &account, const asset &amount)=0
virtual void increase_pending_scorumpower(const account_object &account, const asset &amount)=0
virtual account_refs_type get_active_sp_holders() const =0
virtual budgets_type get_pending_budgets() const =0
virtual asset perform_pending_payouts(const budgets_type &budgets)=0
virtual bool is_exists() const =0
virtual void update(const modifier_type &modifier)=0
virtual const object_type & get() const =0
virtual void push_virtual_operation(const operation &op)=0
virtual asset allocate_cash(const fund_budget_object &budget)=0
virtual bool has_hardfork(uint32_t hardfork) const =0
virtual const witness_object & get(const account_name_type &owner) const =0
fc::flat_map< account_name_type, asset > rewarded_type