Provide objects to trace budget computations
This commit is contained in:
parent
d3b283b60e
commit
9d3bcbb569
6 changed files with 133 additions and 11 deletions
|
|
@ -293,6 +293,7 @@ namespace graphene { namespace app {
|
|||
} case impl_account_transaction_history_object_type:{
|
||||
} case impl_chain_property_object_type: {
|
||||
} case impl_witness_schedule_object_type: {
|
||||
} case impl_budget_record_object_type: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <graphene/chain/asset_object.hpp>
|
||||
#include <graphene/chain/balance_object.hpp>
|
||||
#include <graphene/chain/block_summary_object.hpp>
|
||||
#include <graphene/chain/budget_record_object.hpp>
|
||||
#include <graphene/chain/chain_property_object.hpp>
|
||||
#include <graphene/chain/committee_member_object.hpp>
|
||||
#include <graphene/chain/global_property_object.hpp>
|
||||
|
|
@ -194,6 +195,7 @@ void database::initialize_indexes()
|
|||
add_index< primary_index<flat_index< block_summary_object >> >();
|
||||
add_index< primary_index<simple_index<chain_property_object > > >();
|
||||
add_index< primary_index<simple_index<witness_schedule_object > > >();
|
||||
add_index< primary_index<simple_index<budget_record_object > > >();
|
||||
}
|
||||
|
||||
void database::init_genesis(const genesis_state_type& genesis_state)
|
||||
|
|
|
|||
|
|
@ -271,17 +271,25 @@ void database::update_active_committee_members()
|
|||
});
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
share_type database::get_max_budget( fc::time_point_sec now )const
|
||||
void database::initialize_budget_record( fc::time_point_sec now, budget_record& rec )const
|
||||
{
|
||||
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
|
||||
const asset_object& core = asset_id_type(0)(*this);
|
||||
const asset_dynamic_data_object& core_dd = core.dynamic_asset_data_id(*this);
|
||||
|
||||
rec.from_initial_reserve = core.reserved(*this);
|
||||
rec.from_accumulated_fees = core_dd.accumulated_fees;
|
||||
rec.from_unused_witness_budget = dpo.witness_budget;
|
||||
|
||||
if( (dpo.last_budget_time == fc::time_point_sec())
|
||||
|| (now <= dpo.last_budget_time) )
|
||||
return share_type(0);
|
||||
{
|
||||
rec.time_since_last_budget = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t dt = (now - dpo.last_budget_time).to_seconds();
|
||||
rec.time_since_last_budget = uint64_t( dt );
|
||||
|
||||
// We'll consider accumulated_fees to be reserved at the BEGINNING
|
||||
// of the maintenance interval. However, for speed we only
|
||||
|
|
@ -289,7 +297,7 @@ share_type database::get_max_budget( fc::time_point_sec now )const
|
|||
// end of the maintenance interval. Thus the accumulated_fees
|
||||
// are available for the budget at this point, but not included
|
||||
// in core.reserved().
|
||||
share_type reserve = core.reserved(*this) + core_dd.accumulated_fees;
|
||||
share_type reserve = rec.from_initial_reserve + core_dd.accumulated_fees;
|
||||
// Similarly, we consider leftover witness_budget to be burned
|
||||
// at the BEGINNING of the maintenance interval.
|
||||
reserve += dpo.witness_budget;
|
||||
|
|
@ -304,11 +312,11 @@ share_type database::get_max_budget( fc::time_point_sec now )const
|
|||
budget_u128 >>= GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS;
|
||||
share_type budget;
|
||||
if( budget_u128 < reserve.value )
|
||||
budget = share_type(budget_u128.to_uint64());
|
||||
rec.total_budget = share_type(budget_u128.to_uint64());
|
||||
else
|
||||
budget = reserve;
|
||||
rec.total_budget = reserve;
|
||||
|
||||
return budget;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -342,10 +350,14 @@ void database::process_budget()
|
|||
// blocks_to_maint > 0 because time_to_maint > 0,
|
||||
// which means numerator is at least equal to block_interval
|
||||
|
||||
share_type available_funds = get_max_budget(now);
|
||||
budget_record rec;
|
||||
initialize_budget_record( now, rec );
|
||||
share_type available_funds = rec.total_budget;
|
||||
|
||||
share_type witness_budget = gpo.parameters.witness_pay_per_block.value * blocks_to_maint;
|
||||
rec.requested_witness_budget = witness_budget;
|
||||
witness_budget = std::min(witness_budget, available_funds);
|
||||
rec.witness_budget = witness_budget;
|
||||
available_funds -= witness_budget;
|
||||
|
||||
fc::uint128_t worker_budget_u128 = gpo.parameters.worker_budget_per_day.value;
|
||||
|
|
@ -357,17 +369,27 @@ void database::process_budget()
|
|||
worker_budget = available_funds;
|
||||
else
|
||||
worker_budget = worker_budget_u128.to_uint64();
|
||||
rec.worker_budget = worker_budget;
|
||||
available_funds -= worker_budget;
|
||||
|
||||
share_type leftover_worker_funds = worker_budget;
|
||||
pay_workers(leftover_worker_funds);
|
||||
rec.leftover_worker_funds = leftover_worker_funds;
|
||||
available_funds += leftover_worker_funds;
|
||||
|
||||
rec.supply_delta = rec.witness_budget
|
||||
+ rec.worker_budget
|
||||
- rec.leftover_worker_funds
|
||||
- rec.from_accumulated_fees
|
||||
- rec.from_unused_witness_budget;
|
||||
|
||||
share_type unused_prev_witness_budget = dpo.witness_budget;
|
||||
modify(core, [&]( asset_dynamic_data_object& _core )
|
||||
{
|
||||
_core.current_supply = (_core.current_supply
|
||||
+ witness_budget
|
||||
_core.current_supply = (_core.current_supply + rec.supply_delta );
|
||||
|
||||
assert( rec.supply_delta ==
|
||||
witness_budget
|
||||
+ worker_budget
|
||||
- leftover_worker_funds
|
||||
- _core.accumulated_fees
|
||||
|
|
@ -384,6 +406,12 @@ void database::process_budget()
|
|||
_dpo.last_budget_time = now;
|
||||
});
|
||||
|
||||
create< budget_record_object >( [&]( budget_record_object& _rec )
|
||||
{
|
||||
_rec.time = head_block_time();
|
||||
_rec.record = rec;
|
||||
});
|
||||
|
||||
// available_funds is money we could spend, but don't want to.
|
||||
// we simply let it evaporate back into the reserve.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Cryptonomex, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
||||
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted until September 8, 2015, provided that the following conditions are met:
|
||||
*
|
||||
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
#include <graphene/db/object.hpp>
|
||||
#include <graphene/db/generic_index.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
struct budget_record
|
||||
{
|
||||
uint64_t time_since_last_budget = 0;
|
||||
|
||||
// sources of budget
|
||||
share_type from_initial_reserve = 0;
|
||||
share_type from_accumulated_fees = 0;
|
||||
share_type from_unused_witness_budget = 0;
|
||||
|
||||
// witness budget requested by the committee
|
||||
share_type requested_witness_budget = 0;
|
||||
|
||||
// funds that can be released from reserve at maximum rate
|
||||
share_type total_budget = 0;
|
||||
|
||||
// sinks of budget, should sum up to total_budget
|
||||
share_type witness_budget = 0;
|
||||
share_type worker_budget = 0;
|
||||
|
||||
// unused budget
|
||||
share_type leftover_worker_funds = 0;
|
||||
|
||||
// change in supply due to budget operations
|
||||
share_type supply_delta = 0;
|
||||
};
|
||||
|
||||
class budget_record_object;
|
||||
|
||||
class budget_record_object : public graphene::db::abstract_object<budget_record_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = implementation_ids;
|
||||
static const uint8_t type_id = impl_budget_record_object_type;
|
||||
|
||||
fc::time_point_sec time;
|
||||
budget_record record;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT(
|
||||
graphene::chain::budget_record,
|
||||
(time_since_last_budget)
|
||||
(from_initial_reserve)
|
||||
(from_accumulated_fees)
|
||||
(from_unused_witness_budget)
|
||||
(requested_witness_budget)
|
||||
(total_budget)
|
||||
(witness_budget)
|
||||
(worker_budget)
|
||||
(leftover_worker_funds)
|
||||
(supply_delta)
|
||||
)
|
||||
|
||||
FC_REFLECT_DERIVED(
|
||||
graphene::chain::budget_record_object,
|
||||
(graphene::db::object),
|
||||
(time)
|
||||
(record)
|
||||
)
|
||||
|
|
@ -40,6 +40,8 @@ namespace graphene { namespace chain {
|
|||
using graphene::db::abstract_object;
|
||||
using graphene::db::object;
|
||||
|
||||
struct budget_record;
|
||||
|
||||
/**
|
||||
* @class database
|
||||
* @brief tracks the blockchain state in an extensible manner
|
||||
|
|
@ -432,7 +434,7 @@ namespace graphene { namespace chain {
|
|||
|
||||
//////////////////// db_maint.cpp ////////////////////
|
||||
|
||||
share_type get_max_budget( fc::time_point_sec now )const;
|
||||
void initialize_budget_record( fc::time_point_sec now, budget_record& rec )const;
|
||||
void process_budget();
|
||||
void pay_workers( share_type& budget );
|
||||
void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props);
|
||||
|
|
|
|||
|
|
@ -142,7 +142,8 @@ namespace graphene { namespace chain {
|
|||
impl_account_transaction_history_object_type,
|
||||
impl_blinded_balance_object_type,
|
||||
impl_chain_property_object_type,
|
||||
impl_witness_schedule_object_type
|
||||
impl_witness_schedule_object_type,
|
||||
impl_budget_record_object_type
|
||||
};
|
||||
|
||||
//typedef fc::unsigned_int object_id_type;
|
||||
|
|
@ -189,6 +190,7 @@ namespace graphene { namespace chain {
|
|||
class account_transaction_history_object;
|
||||
class chain_property_object;
|
||||
class witness_schedule_object;
|
||||
class budget_record_object;
|
||||
|
||||
typedef object_id< implementation_ids, impl_global_property_object_type, global_property_object> global_property_id_type;
|
||||
typedef object_id< implementation_ids, impl_dynamic_global_property_object_type, dynamic_global_property_object> dynamic_global_property_id_type;
|
||||
|
|
@ -204,6 +206,7 @@ namespace graphene { namespace chain {
|
|||
account_transaction_history_object> account_transaction_history_id_type;
|
||||
typedef object_id< implementation_ids, impl_chain_property_object_type, chain_property_object> chain_property_id_type;
|
||||
typedef object_id< implementation_ids, impl_witness_schedule_object_type, witness_schedule_object> witness_schedule_id_type;
|
||||
typedef object_id< implementation_ids, impl_budget_record_object_type, budget_record_object > budget_record_id_type;
|
||||
|
||||
typedef fc::array<char, GRAPHENE_MAX_ASSET_SYMBOL_LENGTH> symbol_type;
|
||||
typedef fc::ripemd160 block_id_type;
|
||||
|
|
@ -281,6 +284,7 @@ FC_REFLECT_ENUM( graphene::chain::impl_object_type,
|
|||
(impl_blinded_balance_object_type)
|
||||
(impl_chain_property_object_type)
|
||||
(impl_witness_schedule_object_type)
|
||||
(impl_budget_record_object_type)
|
||||
)
|
||||
|
||||
FC_REFLECT_TYPENAME( graphene::chain::share_type )
|
||||
|
|
@ -307,6 +311,7 @@ FC_REFLECT_TYPENAME( graphene::chain::account_statistics_id_type )
|
|||
FC_REFLECT_TYPENAME( graphene::chain::transaction_obj_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::block_summary_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::account_transaction_history_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::budget_record_id_type )
|
||||
FC_REFLECT( graphene::chain::void_t, )
|
||||
|
||||
FC_REFLECT_ENUM( graphene::chain::asset_issuer_permission_flags, (charge_market_fee)(white_list)(transfer_restricted)(override_authority)(disable_force_settle)(global_settle)(disable_confidential) )
|
||||
|
|
|
|||
Loading…
Reference in a new issue