From 59503acde9eef6520fc177c1cde71fe486d72533 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Tue, 2 Feb 2016 13:58:58 -0500 Subject: [PATCH] Cap auto-cancel fees at deferred_fee #549 --- libraries/chain/db_update.cpp | 11 +++++++++++ libraries/chain/include/graphene/chain/evaluator.hpp | 12 ++++++++---- .../graphene/chain/transaction_evaluation_state.hpp | 1 + 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/libraries/chain/db_update.cpp b/libraries/chain/db_update.cpp index 76dc1df9..3855c50b 100644 --- a/libraries/chain/db_update.cpp +++ b/libraries/chain/db_update.cpp @@ -264,6 +264,17 @@ void database::clear_expired_orders() canceler.fee_paying_account = order.seller; canceler.order = order.id; canceler.fee = current_fee_schedule().calculate_fee( canceler ); + if( canceler.fee.amount > order.deferred_fee ) + { + // Cap auto-cancel fees at deferred_fee; see #549 + wlog( "At block ${b}, fee for clearing expired order ${oid} was capped at deferred_fee ${fee}", ("b", head_block_num())("oid", order.id)("fee", order.deferred_fee) ); + canceler.fee = asset( order.deferred_fee, asset_id_type() ); + } + // we know the fee for this op is set correctly since it is set by the chain. + // this allows us to avoid a hung chain: + // - if #549 case above triggers + // - if the fee is incorrect, which may happen due to #435 (although since cancel is a fixed-fee op, it shouldn't) + cancel_context.skip_fee_schedule_check = true; apply_operation(cancel_context, canceler); } }); diff --git a/libraries/chain/include/graphene/chain/evaluator.hpp b/libraries/chain/include/graphene/chain/evaluator.hpp index cfbbaea2..a80a2df8 100644 --- a/libraries/chain/include/graphene/chain/evaluator.hpp +++ b/libraries/chain/include/graphene/chain/evaluator.hpp @@ -20,6 +20,7 @@ */ #pragma once #include +#include #include namespace graphene { namespace chain { @@ -224,10 +225,13 @@ namespace graphene { namespace chain { const auto& op = o.get(); prepare_fee(op.fee_payer(), op.fee); - GRAPHENE_ASSERT( core_fee_paid >= db().current_fee_schedule().calculate_fee( op ).amount, - insufficient_fee, - "Insufficient Fee Paid", - ("core_fee_paid",core_fee_paid)("required",db().current_fee_schedule().calculate_fee( op ).amount) ); + if( !trx_state->skip_fee_schedule_check ) + { + GRAPHENE_ASSERT( core_fee_paid >= db().current_fee_schedule().calculate_fee( op ).amount, + insufficient_fee, + "Insufficient Fee Paid", + ("core_fee_paid",core_fee_paid)("required",db().current_fee_schedule().calculate_fee( op ).amount) ); + } return eval->do_evaluate(op); } diff --git a/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp b/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp index 4c28e122..4a5b5183 100644 --- a/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp +++ b/libraries/chain/include/graphene/chain/transaction_evaluation_state.hpp @@ -43,5 +43,6 @@ namespace graphene { namespace chain { database* _db = nullptr; bool _is_proposed_trx = false; bool skip_fee = false; + bool skip_fee_schedule_check = false; }; } } // namespace graphene::chain