diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index a7f8b76b3b..4f835ff10d 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -568,7 +568,9 @@ bool application_impl::handle_block(const graphene::net::block_message& blk_msg, ("w",witness_account.name) ("i",last_irr)("d",blk_msg.block.block_num()-last_irr) ); } - FC_ASSERT( (latency.count()/1000) > -5000, "Rejecting block with timestamp in the future" ); + GRAPHENE_ASSERT( latency.count()/1000 > -5000, + graphene::net::block_timestamp_in_future_exception, + "Rejecting block with timestamp in the future", ); try { const uint32_t skip = (_is_block_producer | _force_validate) ? diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index ace071ec0d..7eb518d181 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -636,7 +636,12 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx auto& trx_idx = get_mutable_index_type(); const chain_id_type& chain_id = get_chain_id(); if( !(skip & skip_transaction_dupe_check) ) - FC_ASSERT( trx_idx.indices().get().find(trx.id()) == trx_idx.indices().get().end() ); + { + GRAPHENE_ASSERT( trx_idx.indices().get().find(trx.id()) == trx_idx.indices().get().end(), + duplicate_transaction, + "Transaction '${txid}' is already in the database", + ("txid",trx.id()) ); + } transaction_evaluation_state eval_state(this); const chain_parameters& chain_parameters = get_global_properties().parameters; eval_state._trx = &trx; diff --git a/libraries/chain/exceptions.cpp b/libraries/chain/exceptions.cpp index 68606a91f6..37f72607dd 100644 --- a/libraries/chain/exceptions.cpp +++ b/libraries/chain/exceptions.cpp @@ -29,7 +29,7 @@ namespace graphene { namespace chain { // Internal exceptions - FC_IMPLEMENT_DERIVED_EXCEPTION( internal_exception, graphene::chain::chain_exception, 3990000, "internal exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( internal_exception, chain_exception, 3990000, "internal exception" ) GRAPHENE_IMPLEMENT_INTERNAL_EXCEPTION( verify_auth_max_auth_exceeded, 1, "Exceeds max authority fan-out" ) GRAPHENE_IMPLEMENT_INTERNAL_EXCEPTION( verify_auth_account_not_found, 2, "Auth account not found" ) @@ -39,35 +39,66 @@ namespace graphene { namespace chain { FC_IMPLEMENT_EXCEPTION( chain_exception, 3000000, "blockchain exception" ) - FC_IMPLEMENT_DERIVED_EXCEPTION( database_query_exception, chain_exception, 3010000, "database query exception" ) - FC_IMPLEMENT_DERIVED_EXCEPTION( block_validate_exception, chain_exception, 3020000, "block validation exception" ) - FC_IMPLEMENT_DERIVED_EXCEPTION( operation_validate_exception, chain_exception, 3040000, "operation validation exception" ) - FC_IMPLEMENT_DERIVED_EXCEPTION( operation_evaluate_exception, chain_exception, 3050000, "operation evaluation exception" ) - FC_IMPLEMENT_DERIVED_EXCEPTION( utility_exception, chain_exception, 3060000, "utility method exception" ) - FC_IMPLEMENT_DERIVED_EXCEPTION( undo_database_exception, chain_exception, 3070000, "undo database exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( database_query_exception, chain_exception, 3010000, + "database query exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( block_validate_exception, chain_exception, 3020000, + "block validation exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( transaction_process_exception,chain_exception, 3030000, + "transaction processing exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( operation_validate_exception, chain_exception, 3040000, + "operation validation exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( operation_evaluate_exception, chain_exception, 3050000, + "operation evaluation exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( utility_exception, chain_exception, 3060000, + "utility method exception" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( undo_database_exception, chain_exception, 3070000, + "undo database exception" ) FC_IMPLEMENT_DERIVED_EXCEPTION( unlinkable_block_exception, chain_exception, 3080000, "unlinkable block" ) FC_IMPLEMENT_DERIVED_EXCEPTION( black_swan_exception, chain_exception, 3090000, "black swan" ) FC_IMPLEMENT_DERIVED_EXCEPTION( plugin_exception, chain_exception, 3100000, "plugin exception" ) FC_IMPLEMENT_DERIVED_EXCEPTION( insufficient_feeds, chain_exception, 37006, "insufficient feeds" ) - FC_IMPLEMENT_DERIVED_EXCEPTION( pop_empty_chain, undo_database_exception, 3070001, "there are no blocks to pop" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( duplicate_transaction, transaction_process_exception, 3030001, + "duplicate transaction" ) + + FC_IMPLEMENT_DERIVED_EXCEPTION( pop_empty_chain, undo_database_exception, 3070001, + "there are no blocks to pop" ) GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( transfer ); GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( from_account_not_whitelisted, transfer, 1, "owner mismatch" ) GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( to_account_not_whitelisted, transfer, 2, "owner mismatch" ) GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( restricted_transfer_asset, transfer, 3, "restricted transfer asset" ) - //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( limit_order_create ); - //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( limit_order_cancel ); + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( limit_order_create ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( kill_unfilled, limit_order_create, 1, + "Killing limit order due to unable to fill" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( market_not_whitelisted, limit_order_create, 2, + "The market has not been whitelisted by the selling asset" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( market_blacklisted, limit_order_create, 3, + "The market has been blacklisted by the selling asset" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( selling_asset_unauthorized, limit_order_create, 4, + "The account is not allowed to transact the selling asset" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( receiving_asset_unauthorized, limit_order_create, 5, + "The account is not allowed to transact the receiving asset" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( insufficient_balance, limit_order_create, 6, + "Insufficient balance" ) + + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( limit_order_cancel ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( nonexist_order, limit_order_cancel, 1, "Order does not exist" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( owner_mismatch, limit_order_cancel, 2, "Order owned by someone else" ) + GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( call_order_update ); - GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( unfilled_margin_call, call_order_update, 1, "Updating call order would trigger a margin call that cannot be fully filled" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( unfilled_margin_call, call_order_update, 1, + "Updating call order would trigger a margin call that cannot be fully filled" ) GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_create ); GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_create, 1, "Exceeds max authority fan-out" ) GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_create, 2, "Auth account not found" ) - GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_incorrect_issuer, account_create, 3, "Incorrect issuer specified for account" ) - GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_already_exists, account_create, 4, "Cannot create buyback for asset which already has buyback" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_incorrect_issuer, account_create, 3, + "Incorrect issuer specified for account" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_already_exists, account_create, 4, + "Cannot create buyback for asset which already has buyback" ) GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_too_many_markets, account_create, 5, "Too many buyback markets" ) GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_update ); @@ -95,7 +126,8 @@ namespace graphene { namespace chain { GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_create ); GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( review_period_required, proposal_create, 1, "review_period required" ) - GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( review_period_insufficient, proposal_create, 2, "review_period insufficient" ) + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( review_period_insufficient, proposal_create, 2, + "review_period insufficient" ) //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_update ); //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_delete ); @@ -120,7 +152,8 @@ namespace graphene { namespace chain { GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( not_permitted, override_transfer, 1, "not permitted" ) GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( blind_transfer ); - GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" ); + GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, + "Attempting to claim an unknown prior commitment" ); //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( transfer_from_blind_operation ) //GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_claim_fees_operation ) diff --git a/libraries/chain/include/graphene/chain/exceptions.hpp b/libraries/chain/include/graphene/chain/exceptions.hpp index 0aa9b3db4a..e2100bdfe8 100644 --- a/libraries/chain/include/graphene/chain/exceptions.hpp +++ b/libraries/chain/include/graphene/chain/exceptions.hpp @@ -55,7 +55,7 @@ #op_name "_operation evaluation exception" \ ) -#define GRAPHENE_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ +#define GRAPHENE_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum ) \ FC_DECLARE_DERIVED_EXCEPTION( \ op_name ## _ ## exc_name, \ graphene::chain::op_name ## _validate_exception, \ @@ -72,7 +72,7 @@ msg \ ) -#define GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ +#define GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum ) \ FC_DECLARE_DERIVED_EXCEPTION( \ op_name ## _ ## exc_name, \ graphene::chain::op_name ## _evaluate_exception, \ @@ -110,6 +110,7 @@ namespace graphene { namespace chain { FC_DECLARE_DERIVED_EXCEPTION( database_query_exception, chain_exception, 3010000 ) FC_DECLARE_DERIVED_EXCEPTION( block_validate_exception, chain_exception, 3020000 ) + FC_DECLARE_DERIVED_EXCEPTION( transaction_process_exception,chain_exception, 3030000 ) FC_DECLARE_DERIVED_EXCEPTION( operation_validate_exception, chain_exception, 3040000 ) FC_DECLARE_DERIVED_EXCEPTION( operation_evaluate_exception, chain_exception, 3050000 ) FC_DECLARE_DERIVED_EXCEPTION( utility_exception, chain_exception, 3060000 ) @@ -120,28 +121,40 @@ namespace graphene { namespace chain { FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, chain_exception, 37006 ) + FC_DECLARE_DERIVED_EXCEPTION( duplicate_transaction, transaction_process_exception, 3030001 ) + FC_DECLARE_DERIVED_EXCEPTION( pop_empty_chain, undo_database_exception, 3070001 ) GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( from_account_not_whitelisted, transfer, 1, "owner mismatch" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( to_account_not_whitelisted, transfer, 2, "owner mismatch" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( restricted_transfer_asset, transfer, 3, "restricted transfer asset" ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( from_account_not_whitelisted, transfer, 1 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( to_account_not_whitelisted, transfer, 2 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( restricted_transfer_asset, transfer, 3 ) + + GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( limit_order_create ); + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( kill_unfilled, limit_order_create, 1 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( market_not_whitelisted, limit_order_create, 2 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( market_blacklisted, limit_order_create, 3 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( selling_asset_unauthorized, limit_order_create, 4 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( receiving_asset_unauthorized, limit_order_create, 5 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( insufficient_balance, limit_order_create, 6 ) + + GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( limit_order_cancel ); + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( nonexist_order, limit_order_cancel, 1 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( owner_mismatch, limit_order_cancel, 2 ) - //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( limit_order_create ); - //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( limit_order_cancel ); GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( call_order_update ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unfilled_margin_call, call_order_update, 1, "Updating call order would trigger a margin call that cannot be fully filled" ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unfilled_margin_call, call_order_update, 1 ) GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( account_create ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_create, 1, "Exceeds max authority fan-out" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_create, 2, "Auth account not found" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( buyback_incorrect_issuer, account_create, 3, "Incorrect issuer specified for account" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( buyback_already_exists, account_create, 4, "Cannot create buyback for asset which already has buyback" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( buyback_too_many_markets, account_create, 5, "Too many buyback markets" ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_create, 1 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_create, 2 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( buyback_incorrect_issuer, account_create, 3 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( buyback_already_exists, account_create, 4 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( buyback_too_many_markets, account_create, 5 ) GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( account_update ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_update, 1, "Exceeds max authority fan-out" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_update, 2, "Auth account not found" ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_update, 1 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_update, 2 ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( account_whitelist ); //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( account_upgrade ); @@ -153,7 +166,7 @@ namespace graphene { namespace chain { //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_issue ); GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_reserve ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( invalid_on_mia, asset_reserve, 1, "invalid on mia" ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( invalid_on_mia, asset_reserve, 1 ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_fund_fee_pool ); //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_settle ); @@ -163,8 +176,8 @@ namespace graphene { namespace chain { //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( witness_create ); GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( proposal_create ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( review_period_required, proposal_create, 1, "review_period required" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( review_period_insufficient, proposal_create, 2, "review_period insufficient" ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( review_period_required, proposal_create, 1 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( review_period_insufficient, proposal_create, 2 ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( proposal_update ); //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( proposal_delete ); @@ -181,15 +194,15 @@ namespace graphene { namespace chain { //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( assert ); GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( balance_claim ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( claimed_too_often, balance_claim, 1, "balance claimed too often" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( invalid_claim_amount, balance_claim, 2, "invalid claim amount" ) - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( owner_mismatch, balance_claim, 3, "owner mismatch" ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( claimed_too_often, balance_claim, 1 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( invalid_claim_amount, balance_claim, 2 ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( owner_mismatch, balance_claim, 3 ) GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( override_transfer ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( not_permitted, override_transfer, 1, "not permitted" ) + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( not_permitted, override_transfer, 1 ) GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( blind_transfer ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" ); + GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1 ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer_from_blind_operation ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_claim_fees_operation ) diff --git a/libraries/chain/market_evaluator.cpp b/libraries/chain/market_evaluator.cpp index 18ebbe0180..4b6d9af928 100644 --- a/libraries/chain/market_evaluator.cpp +++ b/libraries/chain/market_evaluator.cpp @@ -48,19 +48,32 @@ void_result limit_order_create_evaluator::do_evaluate(const limit_order_create_o _receive_asset = &op.min_to_receive.asset_id(d); if( _sell_asset->options.whitelist_markets.size() ) - FC_ASSERT( _sell_asset->options.whitelist_markets.find(_receive_asset->id) - != _sell_asset->options.whitelist_markets.end(), - "This market has not been whitelisted." ); + { + GRAPHENE_ASSERT( _sell_asset->options.whitelist_markets.find(_receive_asset->id) + != _sell_asset->options.whitelist_markets.end(), + limit_order_create_market_not_whitelisted, + "This market has not been whitelisted by the selling asset", ); + } if( _sell_asset->options.blacklist_markets.size() ) - FC_ASSERT( _sell_asset->options.blacklist_markets.find(_receive_asset->id) - == _sell_asset->options.blacklist_markets.end(), - "This market has been blacklisted." ); + { + GRAPHENE_ASSERT( _sell_asset->options.blacklist_markets.find(_receive_asset->id) + == _sell_asset->options.blacklist_markets.end(), + limit_order_create_market_blacklisted, + "This market has been blacklisted by the selling asset", ); + } - FC_ASSERT( is_authorized_asset( d, *_seller, *_sell_asset ) ); - FC_ASSERT( is_authorized_asset( d, *_seller, *_receive_asset ) ); + GRAPHENE_ASSERT( is_authorized_asset( d, *_seller, *_sell_asset ), + limit_order_create_selling_asset_unauthorized, + "The account is not allowed to transact the selling asset", ); - FC_ASSERT( d.get_balance( *_seller, *_sell_asset ) >= op.amount_to_sell, "insufficient balance", - ("balance",d.get_balance(*_seller,*_sell_asset))("amount_to_sell",op.amount_to_sell) ); + GRAPHENE_ASSERT( is_authorized_asset( d, *_seller, *_receive_asset ), + limit_order_create_receiving_asset_unauthorized, + "The account is not allowed to transact the receiving asset", ); + + GRAPHENE_ASSERT( d.get_balance( *_seller, *_sell_asset ) >= op.amount_to_sell, + limit_order_create_insufficient_balance, + "insufficient balance", + ("balance",d.get_balance(*_seller,*_sell_asset))("amount_to_sell",op.amount_to_sell) ); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -119,7 +132,10 @@ object_id_type limit_order_create_evaluator::do_apply(const limit_order_create_o else filled = db().apply_order( new_order_object ); - FC_ASSERT( !op.fill_or_kill || filled ); + GRAPHENE_ASSERT( !op.fill_or_kill || filled, + limit_order_create_kill_unfilled, + "Killing limit order ${op} due to unable to fill", + ("op",op) ); return order_id; } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -128,8 +144,17 @@ void_result limit_order_cancel_evaluator::do_evaluate(const limit_order_cancel_o { try { database& d = db(); - _order = &o.order(d); - FC_ASSERT( _order->seller == o.fee_paying_account ); + _order = d.find( o.order ); + + GRAPHENE_ASSERT( _order != nullptr, + limit_order_cancel_nonexist_order, + "Limit order ${oid} does not exist", + ("oid", o.order) ); + + GRAPHENE_ASSERT( _order->seller == o.fee_paying_account, + limit_order_cancel_owner_mismatch, + "Limit order ${oid} is owned by someone else", + ("oid", o.order) ); return void_result(); } FC_CAPTURE_AND_RETHROW( (o) ) } diff --git a/libraries/net/exceptions.cpp b/libraries/net/exceptions.cpp index 7b6e23dc5d..5900eec66f 100644 --- a/libraries/net/exceptions.cpp +++ b/libraries/net/exceptions.cpp @@ -37,5 +37,7 @@ namespace graphene { namespace net { FC_IMPLEMENT_DERIVED_EXCEPTION( peer_is_on_an_unreachable_fork, net_exception, 90005, "peer is on another fork" ) FC_IMPLEMENT_DERIVED_EXCEPTION( unlinkable_block_exception, net_exception, 90006, "unlinkable block" ) + FC_IMPLEMENT_DERIVED_EXCEPTION( block_timestamp_in_future_exception, net_exception, 90007, + "block timestamp in the future" ) } } diff --git a/libraries/net/include/graphene/net/exceptions.hpp b/libraries/net/include/graphene/net/exceptions.hpp index e95eea8759..2a47d333eb 100644 --- a/libraries/net/include/graphene/net/exceptions.hpp +++ b/libraries/net/include/graphene/net/exceptions.hpp @@ -34,5 +34,6 @@ namespace graphene { namespace net { FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, net_exception, 90004 ) FC_DECLARE_DERIVED_EXCEPTION( peer_is_on_an_unreachable_fork, net_exception, 90005 ) FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, net_exception, 90006 ) + FC_DECLARE_DERIVED_EXCEPTION( block_timestamp_in_future_exception, net_exception, 90007 ) } } diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index f570dac5bf..fc2a086ee2 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -79,6 +79,7 @@ #include #include +#include // Nasty hack: A circular dependency around fee_schedule is resolved by fwd-declaring it and using a shared_ptr // to it in chain_parameters, which is used in an operation and thus must be serialized by the net library. // Resolving that forward declaration doesn't happen until now: @@ -2417,7 +2418,8 @@ namespace graphene { namespace net { namespace detail { } - void node_impl::on_closing_connection_message( peer_connection* originating_peer, const closing_connection_message& closing_connection_message_received ) + void node_impl::on_closing_connection_message( peer_connection* originating_peer, + const closing_connection_message& closing_connection_message_received ) { VERIFY_CORRECT_THREAD(); originating_peer->they_have_requested_close = true; @@ -2429,12 +2431,14 @@ namespace graphene { namespace net { namespace detail { ( "msg", closing_connection_message_received.reason_for_closing ) ( "error", closing_connection_message_received.error ) ); std::ostringstream message; - message << "Peer " << fc::variant( originating_peer->get_remote_endpoint(), GRAPHENE_NET_MAX_NESTED_OBJECTS ).as_string() << + message << "Peer " << fc::variant( originating_peer->get_remote_endpoint(), + GRAPHENE_NET_MAX_NESTED_OBJECTS ).as_string() << " disconnected us: " << closing_connection_message_received.reason_for_closing; - fc::exception detailed_error(FC_LOG_MESSAGE(warn, "Peer ${peer} is disconnecting us because of an error: ${msg}, exception: ${error}", - ( "peer", originating_peer->get_remote_endpoint() ) - ( "msg", closing_connection_message_received.reason_for_closing ) - ( "error", closing_connection_message_received.error ) )); + fc::exception detailed_error(FC_LOG_MESSAGE(warn, + "Peer ${peer} is disconnecting us because of an error: ${msg}, exception: ${error}", + ( "peer", originating_peer->get_remote_endpoint() ) + ( "msg", closing_connection_message_received.reason_for_closing ) + ( "error", closing_connection_message_received.error ) )); _delegate->error_encountered( message.str(), detailed_error ); } @@ -2571,11 +2575,20 @@ namespace graphene { namespace net { namespace detail { } catch (const fc::exception& e) { + auto block_num = block_message_to_send.block.block_num(); wlog("Failed to push sync block ${num} (id:${id}): client rejected sync block sent by peer: ${e}", - ("num", block_message_to_send.block.block_num()) + ("num", block_num) ("id", block_message_to_send.block_id) ("e", e)); - handle_message_exception = e; + if( e.code() == block_timestamp_in_future_exception::code_enum::code_value ) + { + handle_message_exception = block_timestamp_in_future_exception( FC_LOG_MESSAGE( warn, "", + ("block_header", static_cast(block_message_to_send.block)) + ("block_num", block_num) + ("block_id", block_message_to_send.block_id) ) ); + } + else + handle_message_exception = e; } // build up lists for any potentially-blocking operations we need to do, then do them @@ -2667,7 +2680,8 @@ namespace graphene { namespace net { namespace detail { { ASSERT_TASK_NOT_PREEMPTED(); // don't yield while iterating over _active_connections - if (peer->ids_of_items_being_processed.find(block_message_to_send.block_id) != peer->ids_of_items_being_processed.end()) + if (peer->ids_of_items_being_processed.find(block_message_to_send.block_id) + != peer->ids_of_items_being_processed.end()) { if (discontinue_fetching_blocks_from_peer) { @@ -2676,7 +2690,9 @@ namespace graphene { namespace net { namespace detail { peer->inhibit_fetching_sync_blocks = true; } else - peers_to_disconnect[peer] = std::make_pair(std::string("You offered us a block that we reject as invalid"), fc::oexception(handle_message_exception)); + peers_to_disconnect[peer] = std::make_pair( + std::string("You offered us a block that we reject as invalid"), + fc::oexception(handle_message_exception)); } } } @@ -2985,11 +3001,21 @@ namespace graphene { namespace net { namespace detail { catch (const fc::exception& e) { // client rejected the block. Disconnect the client and any other clients that offered us this block - wlog("Failed to push block ${num} (id:${id}), client rejected block sent by peer", - ("num", block_message_to_process.block.block_num()) - ("id", block_message_to_process.block_id)); + auto block_num = block_message_to_process.block.block_num(); + wlog("Failed to push block ${num} (id:${id}), client rejected block sent by peer: ${e}", + ("num", block_num) + ("id", block_message_to_process.block_id) + ("e",e)); - disconnect_exception = e; + if( e.code() == block_timestamp_in_future_exception::code_enum::code_value ) + { + disconnect_exception = block_timestamp_in_future_exception( FC_LOG_MESSAGE( warn, "", + ("block_header", static_cast(block_message_to_process.block)) + ("block_num", block_num) + ("block_id", block_message_to_process.block_id) ) ); + } + else + disconnect_exception = e; disconnect_reason = "You offered me a block that I have deemed to be invalid"; peers_to_disconnect.insert( originating_peer->shared_from_this() ); @@ -3346,7 +3372,7 @@ namespace graphene { namespace net { namespace detail { } void node_impl::on_get_current_connections_reply_message(peer_connection* originating_peer, - const get_current_connections_reply_message& get_current_connections_reply_message_received) + const get_current_connections_reply_message& get_current_connections_reply_message_received) { VERIFY_CORRECT_THREAD(); } @@ -3358,19 +3384,22 @@ namespace graphene { namespace net { namespace detail { // this just passes the message to the client, and does the bookkeeping // related to requesting and rebroadcasting the message. void node_impl::process_ordinary_message( peer_connection* originating_peer, - const message& message_to_process, const message_hash_type& message_hash ) + const message& message_to_process, + const message_hash_type& message_hash ) { VERIFY_CORRECT_THREAD(); fc::time_point message_receive_time = fc::time_point::now(); // only process it if we asked for it - auto iter = originating_peer->items_requested_from_peer.find( item_id(message_to_process.msg_type.value(), message_hash) ); + auto iter = originating_peer->items_requested_from_peer.find( + item_id(message_to_process.msg_type.value(), message_hash) ); if( iter == originating_peer->items_requested_from_peer.end() ) { wlog( "received a message I didn't ask for from peer ${endpoint}, disconnecting from peer", ( "endpoint", originating_peer->get_remote_endpoint() ) ); - fc::exception detailed_error( FC_LOG_MESSAGE(error, "You sent me a message that I didn't ask for, message_hash: ${message_hash}", - ( "message_hash", message_hash ) ) ); + fc::exception detailed_error( FC_LOG_MESSAGE(error, + "You sent me a message that I didn't ask for, message_hash: ${message_hash}", + ( "message_hash", message_hash ) ) ); disconnect_from_peer( originating_peer, "You sent me a message that I didn't request", true, detailed_error ); return; } @@ -3387,7 +3416,8 @@ namespace graphene { namespace net { namespace detail { if (message_to_process.msg_type.value() == trx_message_type) { trx_message transaction_message_to_process = message_to_process.as(); - dlog("passing message containing transaction ${trx} to client", ("trx", transaction_message_to_process.trx.id())); + dlog( "passing message containing transaction ${trx} to client", + ("trx", transaction_message_to_process.trx.id()) ); _delegate->handle_transaction(transaction_message_to_process); } else @@ -3400,14 +3430,36 @@ namespace graphene { namespace net { namespace detail { } catch ( const fc::exception& e ) { - wlog( "client rejected message sent by peer ${peer}, ${e}", ("peer", originating_peer->get_remote_endpoint() )("e", e) ); + switch( e.code() ) + { + // log common exceptions in debug level + case graphene::chain::duplicate_transaction::code_enum::code_value : + case graphene::chain::limit_order_create_kill_unfilled::code_enum::code_value : + case graphene::chain::limit_order_create_market_not_whitelisted::code_enum::code_value : + case graphene::chain::limit_order_create_market_blacklisted::code_enum::code_value : + case graphene::chain::limit_order_create_selling_asset_unauthorized::code_enum::code_value : + case graphene::chain::limit_order_create_receiving_asset_unauthorized::code_enum::code_value : + case graphene::chain::limit_order_create_insufficient_balance::code_enum::code_value : + case graphene::chain::limit_order_cancel_nonexist_order::code_enum::code_value : + case graphene::chain::limit_order_cancel_owner_mismatch::code_enum::code_value : + dlog( "client rejected message sent by peer ${peer}, ${e}", + ("peer", originating_peer->get_remote_endpoint() )("e", e) ); + break; + // log rarer exceptions in warn level + default: + wlog( "client rejected message sent by peer ${peer}, ${e}", + ("peer", originating_peer->get_remote_endpoint() )("e", e) ); + break; + } // record it so we don't try to fetch this item again - _recently_failed_items.insert(peer_connection::timestamped_item_id(item_id(message_to_process.msg_type.value(), message_hash ), fc::time_point::now())); + _recently_failed_items.insert( peer_connection::timestamped_item_id( + item_id( message_to_process.msg_type.value(), message_hash ), fc::time_point::now() ) ); return; } // finally, if the delegate validated the message, broadcast it to our other peers - message_propagation_data propagation_data{message_receive_time, message_validated_time, originating_peer->node_id}; + message_propagation_data propagation_data { message_receive_time, message_validated_time, + originating_peer->node_id }; broadcast( message_to_process, propagation_data ); } }