2015-06-08 15:50:35 +00:00
/*
2015-10-12 17:48:40 +00:00
* Copyright ( c ) 2015 Cryptonomex , Inc . , and contributors .
*
2016-01-06 09:51:18 +00:00
* The MIT License
2015-10-12 17:48:40 +00:00
*
2016-01-06 09:51:18 +00:00
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
2015-10-12 17:48:40 +00:00
*
2016-01-06 09:51:18 +00:00
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
2015-10-12 17:02:59 +00:00
*
2016-01-06 09:51:18 +00:00
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
2015-06-08 15:50:35 +00:00
*/
# include <graphene/chain/database.hpp>
# include <graphene/chain/evaluator.hpp>
2015-07-08 18:26:59 +00:00
# include <graphene/chain/exceptions.hpp>
2015-10-30 18:22:02 +00:00
# include <graphene/chain/hardfork.hpp>
Make is_authorized_asset a free-floating method #566
The following sed commands were used to port existing call sites to the new interface:
sed -i -e 's/\([a-zA-Z0-9_]\+\)->is_authorized_asset[(] \([a-zA-Z0-9_*]\+\), d [)]/is_authorized_asset( d, *\1, \2 )/' libraries/chain/*.cpp
sed -i -e 's/\([a-zA-Z0-9_]\+\)[.]is_authorized_asset[(] \([a-zA-Z0-9_*]\+\), d [)]/is_authorized_asset( d, \1, \2 )/' libraries/chain/*.cpp
sed -i -e 's/\([a-zA-Z0-9_]\+\)[(]db[)][.]is_authorized_asset[(]\([a-zA-Z0-9_*]\+\)[(]db[)], db[)]/is_authorized_asset( db, \1(db), \2(db) )/' tests/tests/uia_tests.cpp
sed -i -e 's/\([a-zA-Z0-9_]\+\)[.]is_authorized_asset[(]\([a-zA-Z0-9_*]\+\), db[)]/is_authorized_asset( db, \1, \2 )/' tests/tests/uia_tests.cpp
No new functionality is added by this commit, it is simply re-organizing the existing code in a different place.
2016-02-10 21:24:56 +00:00
# include <graphene/chain/is_authorized_asset.hpp>
2015-06-08 15:50:35 +00:00
# include <graphene/chain/transaction_evaluation_state.hpp>
2015-07-08 18:26:59 +00:00
2015-06-08 15:50:35 +00:00
# include <graphene/chain/asset_object.hpp>
# include <graphene/chain/account_object.hpp>
2016-02-15 19:35:16 +00:00
# include <graphene/chain/fba_object.hpp>
2015-07-13 20:06:02 +00:00
# include <graphene/chain/committee_member_object.hpp>
2015-07-08 20:39:23 +00:00
# include <graphene/chain/market_evaluator.hpp>
2019-04-14 04:38:56 +00:00
# include <graphene/protocol/fee_schedule.hpp>
2015-06-08 15:50:35 +00:00
namespace graphene { namespace chain {
2015-06-30 20:42:41 +00:00
database & generic_evaluator : : db ( ) const { return trx_state - > db ( ) ; }
2015-06-08 15:50:35 +00:00
operation_result generic_evaluator : : start_evaluate ( transaction_evaluation_state & eval_state , const operation & op , bool apply )
2015-06-30 19:11:26 +00:00
{ try {
2015-06-08 15:50:35 +00:00
trx_state = & eval_state ;
2015-07-16 22:13:11 +00:00
//check_required_authorities(op);
2015-06-08 15:50:35 +00:00
auto result = evaluate ( op ) ;
if ( apply ) result = this - > apply ( op ) ;
return result ;
2015-06-30 19:11:26 +00:00
} FC_CAPTURE_AND_RETHROW ( ) }
2015-06-08 15:50:35 +00:00
void generic_evaluator : : prepare_fee ( account_id_type account_id , asset fee )
{
2015-10-30 18:22:02 +00:00
const database & d = db ( ) ;
2015-06-08 15:50:35 +00:00
fee_from_account = fee ;
FC_ASSERT ( fee . amount > = 0 ) ;
2015-10-30 18:22:02 +00:00
fee_paying_account = & account_id ( d ) ;
fee_paying_account_statistics = & fee_paying_account - > statistics ( d ) ;
2015-06-08 15:50:35 +00:00
2019-05-04 17:33:25 +00:00
fee_asset = & fee . asset_id ( d ) ;
2015-10-30 18:22:02 +00:00
fee_asset_dyn_data = & fee_asset - > dynamic_asset_data_id ( d ) ;
if ( d . head_block_time ( ) > HARDFORK_419_TIME )
{
Make is_authorized_asset a free-floating method #566
The following sed commands were used to port existing call sites to the new interface:
sed -i -e 's/\([a-zA-Z0-9_]\+\)->is_authorized_asset[(] \([a-zA-Z0-9_*]\+\), d [)]/is_authorized_asset( d, *\1, \2 )/' libraries/chain/*.cpp
sed -i -e 's/\([a-zA-Z0-9_]\+\)[.]is_authorized_asset[(] \([a-zA-Z0-9_*]\+\), d [)]/is_authorized_asset( d, \1, \2 )/' libraries/chain/*.cpp
sed -i -e 's/\([a-zA-Z0-9_]\+\)[(]db[)][.]is_authorized_asset[(]\([a-zA-Z0-9_*]\+\)[(]db[)], db[)]/is_authorized_asset( db, \1(db), \2(db) )/' tests/tests/uia_tests.cpp
sed -i -e 's/\([a-zA-Z0-9_]\+\)[.]is_authorized_asset[(]\([a-zA-Z0-9_*]\+\), db[)]/is_authorized_asset( db, \1, \2 )/' tests/tests/uia_tests.cpp
No new functionality is added by this commit, it is simply re-organizing the existing code in a different place.
2016-02-10 21:24:56 +00:00
FC_ASSERT ( is_authorized_asset ( d , * fee_paying_account , * fee_asset ) , " Account ${acct} '${name}' attempted to pay fee by using asset ${a} '${sym}', which is unauthorized due to whitelist / blacklist " ,
2015-10-30 18:22:02 +00:00
( " acct " , fee_paying_account - > id ) ( " name " , fee_paying_account - > name ) ( " a " , fee_asset - > id ) ( " sym " , fee_asset - > symbol ) ) ;
}
2015-06-08 15:50:35 +00:00
if ( fee_from_account . asset_id = = asset_id_type ( ) )
core_fee_paid = fee_from_account . amount ;
2015-10-30 18:22:02 +00:00
else
{
2015-06-08 15:50:35 +00:00
asset fee_from_pool = fee_from_account * fee_asset - > options . core_exchange_rate ;
FC_ASSERT ( fee_from_pool . asset_id = = asset_id_type ( ) ) ;
core_fee_paid = fee_from_pool . amount ;
2015-07-09 20:05:57 +00:00
FC_ASSERT ( core_fee_paid < = fee_asset_dyn_data - > fee_pool , " Fee pool balance of '${b}' is less than the ${r} required to convert ${c} " ,
( " r " , db ( ) . to_pretty_string ( fee_from_pool ) ) ( " b " , db ( ) . to_pretty_string ( fee_asset_dyn_data - > fee_pool ) ) ( " c " , db ( ) . to_pretty_string ( fee ) ) ) ;
2015-06-08 15:50:35 +00:00
}
}
2015-12-03 20:48:52 +00:00
void generic_evaluator : : convert_fee ( )
{
2016-01-29 01:02:37 +00:00
if ( ! trx_state - > skip_fee ) {
if ( fee_asset - > get_id ( ) ! = asset_id_type ( ) )
{
db ( ) . modify ( * fee_asset_dyn_data , [ this ] ( asset_dynamic_data_object & d ) {
d . accumulated_fees + = fee_from_account . amount ;
d . fee_pool - = core_fee_paid ;
} ) ;
}
2015-12-03 20:48:52 +00:00
}
}
void generic_evaluator : : pay_fee ( )
{ try {
2016-01-29 01:02:37 +00:00
if ( ! trx_state - > skip_fee ) {
database & d = db ( ) ;
/// TODO: db().pay_fee( account_id, core_fee );
d . modify ( * fee_paying_account_statistics , [ & ] ( account_statistics_object & s )
{
s . pay_fee ( core_fee_paid , d . get_global_properties ( ) . parameters . cashback_vesting_threshold ) ;
} ) ;
}
2015-06-08 15:50:35 +00:00
} FC_CAPTURE_AND_RETHROW ( ) }
2016-02-15 19:35:16 +00:00
void generic_evaluator : : pay_fba_fee ( uint64_t fba_id )
{
database & d = db ( ) ;
const fba_accumulator_object & fba = d . get < fba_accumulator_object > ( fba_accumulator_id_type ( fba_id ) ) ;
if ( ! fba . is_configured ( d ) )
{
generic_evaluator : : pay_fee ( ) ;
return ;
}
d . modify ( fba , [ & ] ( fba_accumulator_object & _fba )
{
_fba . accumulated_fba_fees + = core_fee_paid ;
} ) ;
}
2016-02-23 00:34:16 +00:00
share_type generic_evaluator : : calculate_fee_for_operation ( const operation & op ) const
{
return db ( ) . current_fee_schedule ( ) . calculate_fee ( op ) . amount ;
}
void generic_evaluator : : db_adjust_balance ( const account_id_type & fee_payer , asset fee_from_account )
{
db ( ) . adjust_balance ( fee_payer , fee_from_account ) ;
}
2017-03-16 22:38:35 +00:00
object_id_type generic_evaluator : : get_relative_id ( object_id_type rel_id ) const
{
if ( ! is_relative ( rel_id ) )
FC_THROW ( " get_relative_id() called for non-relative id ${id} " , ( " id " , rel_id ) ) ;
if ( rel_id . instance ( ) > = trx_state - > operation_results . size ( ) )
FC_THROW ( " get_relative_id() asked for id of operation ${op_num} (zero-based), but we only have ${count} operations " ,
( " op_num " , rel_id . instance ( ) ) ( " count " , trx_state - > operation_results . size ( ) ) ) ;
if ( trx_state - > operation_results [ rel_id . instance ( ) ] . which ( ) ! = operation_result : : tag < object_id_type > : : value )
FC_THROW ( " get_relative_id() asked for the result of operation ${op_num}, but that operation did not return an object_id " ,
( " op_num " , rel_id . instance ( ) ) ) ;
return trx_state - > operation_results [ rel_id . instance ( ) ] . get < object_id_type > ( ) ;
}
2015-06-08 15:50:35 +00:00
} }