diff --git a/libraries/chain/include/graphene/chain/protocol/splitter.hpp b/libraries/chain/include/graphene/chain/protocol/splitter.hpp index 36cafa35..5ce1f34d 100644 --- a/libraries/chain/include/graphene/chain/protocol/splitter.hpp +++ b/libraries/chain/include/graphene/chain/protocol/splitter.hpp @@ -35,8 +35,10 @@ namespace graphene { namespace chain { struct splitter_create_operation : public base_operation { - /// TODO: charge fee based upon size - struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; }; + struct fee_parameters_type { + uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; + uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION; + }; asset fee; account_id_type payer; @@ -59,12 +61,16 @@ namespace graphene { namespace chain { } } account_id_type fee_payer()const { return payer; } + share_type calculate_fee(const fee_parameters_type& k )const + { return calculate_data_fee( fc::raw::pack_size(*this), k.price_per_kbyte ) + k.fee; } }; struct splitter_update_operation : public base_operation { - /// TODO: charge fee based upon size - struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; }; + struct fee_parameters_type { + uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; + uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION; + }; asset fee; splitter_id_type splitter_id; @@ -85,6 +91,8 @@ namespace graphene { namespace chain { } account_id_type fee_payer()const { return owner; } + share_type calculate_fee(const fee_parameters_type& k )const + { return calculate_data_fee( fc::raw::pack_size(*this), k.price_per_kbyte ) + k.fee; } }; struct splitter_pay_operation : public base_operation @@ -139,8 +147,8 @@ FC_REFLECT( graphene::chain::splitter_update_operation, (fee)(owner)(new_owner)( FC_REFLECT( graphene::chain::splitter_pay_operation, (fee)(splitter_id)(paying_account)(payment) ) FC_REFLECT( graphene::chain::splitter_payout_operation, (fee)(splitter_id)(owner) ) FC_REFLECT( graphene::chain::splitter_delete_operation, (fee)(splitter_id)(owner) ) -FC_REFLECT( graphene::chain::splitter_create_operation::fee_parameters_type, (fee) ); -FC_REFLECT( graphene::chain::splitter_update_operation::fee_parameters_type, (fee) ); +FC_REFLECT( graphene::chain::splitter_create_operation::fee_parameters_type, (fee)(price_per_kbyte) ); +FC_REFLECT( graphene::chain::splitter_update_operation::fee_parameters_type, (fee)(price_per_kbyte) ); FC_REFLECT( graphene::chain::splitter_pay_operation::fee_parameters_type, (fee) ); FC_REFLECT( graphene::chain::splitter_payout_operation::fee_parameters_type, (fee) ); FC_REFLECT( graphene::chain::splitter_delete_operation::fee_parameters_type, (fee) ); diff --git a/libraries/chain/include/graphene/chain/splitter_evaluator.hpp b/libraries/chain/include/graphene/chain/splitter_evaluator.hpp index d8d822f2..c5d60f57 100644 --- a/libraries/chain/include/graphene/chain/splitter_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/splitter_evaluator.hpp @@ -43,8 +43,41 @@ namespace graphene { namespace chain { db.apply_order(new_order_object); } }; - void payout( database& db )const + void payout( database& db, bool pay_fee = true )const { + /** this happens when the threshold is used as the trigger, but not when the payout operation is used */ + if( pay_fee ) + { + const auto& fee_config = db.get_global_properties().parameters.current_fees->get(); + asset fee_in_aobj_units = asset(fee_config.fee); + const asset_object& aobj = min_payment.asset_id(db); + const asset_dynamic_data_object& aobj_dyn = aobj.dynamic_asset_data_id(db); + if( aobj.id != asset_id_type() ) + { + fee_in_aobj_units = asset(fee_config.fee) * aobj.options.core_exchange_rate; + /// not enough in fee pool to cover + if( aobj_dyn.fee_pool < fee_config.fee ) return; + } + /// not enough to cover payout fee, so don't payout. + if( fee_in_aobj_units > balance ) return; + + + db.modify( *this, [&]( splitter_object& obj ){ obj.balance-= fee_in_aobj_units; } ); + + if( aobj.id != asset_id_type() ) + { + db.modify( aobj_dyn, [&]( asset_dynamic_data_object& obj ){ + obj.accumulated_fees += fee_in_aobj_units.amount; + obj.fee_pool -= fee_config.fee; + }); + } + + db.modify( aobj_dyn, [&]( asset_dynamic_data_object& obj ){ + obj.current_supply -= fee_config.fee; + }); + } + + uint64_t total_weight = 0; for( auto& t : targets ) total_weight += t.weight;