From 8ff25b813feeb95b2b7ffde12ed95c1e47ff6065 Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Tue, 7 Jul 2015 21:43:58 -0400 Subject: [PATCH] Begin implementation of new exception framework #113 --- libraries/chain/balance_evaluator.cpp | 35 +++++++---- .../include/graphene/chain/exceptions.hpp | 63 +++++++++++++++++-- tests/tests/basic_tests.cpp | 2 +- tests/tests/operation_tests2.cpp | 8 +-- 4 files changed, 86 insertions(+), 22 deletions(-) diff --git a/libraries/chain/balance_evaluator.cpp b/libraries/chain/balance_evaluator.cpp index 1a5dee52..d69003f5 100644 --- a/libraries/chain/balance_evaluator.cpp +++ b/libraries/chain/balance_evaluator.cpp @@ -7,27 +7,38 @@ void_result balance_claim_evaluator::do_evaluate(const balance_claim_operation& database& d = db(); balance = &op.balance_to_claim(d); - FC_ASSERT(op.balance_owner_key == balance->owner || + GRAPHENE_ASSERT( + op.balance_owner_key == balance->owner || pts_address(op.balance_owner_key, false, 56) == balance->owner || pts_address(op.balance_owner_key, true, 56) == balance->owner || pts_address(op.balance_owner_key, false, 0) == balance->owner || pts_address(op.balance_owner_key, true, 0) == balance->owner, - "balance_owner_key does not match balance's owner"); + balance_claim_owner_mismatch, + "Balance owner key was specified as '${op}' but balance's actual owner is '${bal}'", + ("op", op.balance_owner_key) + ("bal", balance->owner) + ); if( !(d.get_node_properties().skip_flags & (database::skip_authority_check | database::skip_transaction_signatures)) ) FC_ASSERT(op.total_claimed.asset_id == balance->asset_type()); - if( balance->is_vesting_balance() ) { - if( !balance->vesting_policy->is_withdraw_allowed({balance->balance, - d.head_block_time(), - op.total_claimed}) ) - FC_THROW_EXCEPTION(invalid_claim_amount, - "Attempted to claim ${c} from a vesting balance with ${a} available", - ("c", op.total_claimed)("a", balance->available(d.head_block_time()))); - if( d.head_block_time() - balance->last_claim_date < fc::days(1) ) - FC_THROW_EXCEPTION(balance_claimed_too_often, - "Genesis vesting balances may not be claimed more than once per day."); + if( balance->is_vesting_balance() ) + { + GRAPHENE_ASSERT( + balance->vesting_policy->is_withdraw_allowed( + { balance->balance, + d.head_block_time(), + op.total_claimed } ), + balance_claim_invalid_claim_amount, + "Attempted to claim ${c} from a vesting balance with ${a} available", + ("c", op.total_claimed)("a", balance->available(d.head_block_time())) + ); + GRAPHENE_ASSERT( + d.head_block_time() - balance->last_claim_date >= fc::days(1), + balance_claim_claimed_too_often, + "Genesis vesting balances may not be claimed more than once per day." + ); return {}; } diff --git a/libraries/chain/include/graphene/chain/exceptions.hpp b/libraries/chain/include/graphene/chain/exceptions.hpp index f06ecb02..ebd1ff91 100644 --- a/libraries/chain/include/graphene/chain/exceptions.hpp +++ b/libraries/chain/include/graphene/chain/exceptions.hpp @@ -18,12 +18,66 @@ #pragma once #include +#include + +#define GRAPHENE_ASSERT( expr, exc_type, ... ) \ + if( !(expr) ) \ + { \ + FC_THROW_EXCEPTION( exc_type, __VA_ARGS__ ); \ + } + +#define GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _validate_exception, \ + graphene::chain::operation_validate_exception, \ + 3040000 + 100 * operation::tag< op_name ## _operation >::value, \ + #op_name "_operation validation exception" \ + ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _evaluate_exception, \ + graphene::chain::operation_evaluate_exception, \ + 3050000 + 100 * operation::tag< op_name ## _operation >::value, \ + #op_name "_operation evaluation exception" \ + ) + +#define GRAPHENE_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _ ## exc_name, \ + graphene::chain::op_name ## _validate_exception, \ + 3040000 + 100 * operation::tag< op_name ## _operation >::value \ + + seqnum, \ + msg \ + ) + +#define GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + op_name ## _ ## exc_name, \ + graphene::chain::op_name ## _evaluate_exception, \ + 3050000 + 100 * operation::tag< op_name ## _operation >::value \ + + seqnum, \ + msg \ + ) namespace graphene { namespace chain { - // registered in chain_database.cpp - FC_DECLARE_EXCEPTION( chain_exception, 30000, "Blockchain Exception" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_pts_address, graphene::chain::chain_exception, 30001, "invalid pts address" ) + FC_DECLARE_EXCEPTION( chain_exception, 3000000, "blockchain exception" ) + FC_DECLARE_DERIVED_EXCEPTION( database_query_exception, graphene::chain::chain_exception, 3010000, "database query exception" ) + FC_DECLARE_DERIVED_EXCEPTION( block_validate_exception, graphene::chain::chain_exception, 3020000, "block validation exception" ) + FC_DECLARE_DERIVED_EXCEPTION( transaction_exception, graphene::chain::chain_exception, 3030000, "transaction validation exception" ) + FC_DECLARE_DERIVED_EXCEPTION( operation_validate_exception, graphene::chain::chain_exception, 3040000, "operation validation exception" ) + FC_DECLARE_DERIVED_EXCEPTION( operation_evaluate_exception, graphene::chain::chain_exception, 3050000, "operation evaluation exception" ) + FC_DECLARE_DERIVED_EXCEPTION( utility_exception, graphene::chain::chain_exception, 3060000, "utility method exception" ) + + FC_DECLARE_DERIVED_EXCEPTION( invalid_pts_address, graphene::chain::utility_exception, 3060001, "invalid pts address" ) + FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::chain_exception, 37006, "insufficient feeds" ) + + 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" ) + + /* FC_DECLARE_DERIVED_EXCEPTION( addition_overflow, graphene::chain::chain_exception, 30002, "addition overflow" ) FC_DECLARE_DERIVED_EXCEPTION( subtraction_overflow, graphene::chain::chain_exception, 30003, "subtraction overflow" ) FC_DECLARE_DERIVED_EXCEPTION( asset_type_mismatch, graphene::chain::chain_exception, 30004, "asset/price mismatch" ) @@ -63,8 +117,6 @@ namespace graphene { namespace chain { FC_DECLARE_DERIVED_EXCEPTION( expired_transaction, graphene::chain::evaluation_error, 31010, "expired transaction" ) FC_DECLARE_DERIVED_EXCEPTION( invalid_transaction_expiration, graphene::chain::evaluation_error, 31011, "invalid transaction expiration" ) FC_DECLARE_DERIVED_EXCEPTION( oversized_transaction, graphene::chain::evaluation_error, 31012, "transaction exceeded the maximum transaction size" ) - FC_DECLARE_DERIVED_EXCEPTION( balance_claimed_too_often, graphene::chain::evaluation_error, 31013, "balance claimed too often" ) - FC_DECLARE_DERIVED_EXCEPTION( invalid_claim_amount, graphene::chain::evaluation_error, 31013, "invalid claim amount" ) FC_DECLARE_DERIVED_EXCEPTION( invalid_account_name, graphene::chain::evaluation_error, 32001, "invalid account name" ) FC_DECLARE_DERIVED_EXCEPTION( unknown_account_id, graphene::chain::evaluation_error, 32002, "unknown account id" ) @@ -111,5 +163,6 @@ namespace graphene { namespace chain { FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_overflow, graphene::chain::evaluation_error, 38001, "price multiplication overflow" ) FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_underflow, graphene::chain::evaluation_error, 38002, "price multiplication underflow" ) FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_undefined, graphene::chain::evaluation_error, 38003, "price multiplication undefined product 0*inf" ) + */ } } // graphene::chain diff --git a/tests/tests/basic_tests.cpp b/tests/tests/basic_tests.cpp index 1b9621ce..727a0690 100644 --- a/tests/tests/basic_tests.cpp +++ b/tests/tests/basic_tests.cpp @@ -330,7 +330,7 @@ BOOST_AUTO_TEST_CASE( data_fees ) BOOST_AUTO_TEST_CASE( exceptions ) { - GRAPHENE_CHECK_THROW(FC_THROW_EXCEPTION(invalid_claim_amount, "Etc"), invalid_claim_amount); + GRAPHENE_CHECK_THROW(FC_THROW_EXCEPTION(balance_claim_invalid_claim_amount, "Etc"), balance_claim_invalid_claim_amount); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/operation_tests2.cpp b/tests/tests/operation_tests2.cpp index 49c7637d..da81c72d 100644 --- a/tests/tests/operation_tests2.cpp +++ b/tests/tests/operation_tests2.cpp @@ -1048,7 +1048,7 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) trx.sign(n_key); trx.sign(v1_key); // Attempting to claim 1 from a balance with 0 available - GRAPHENE_CHECK_THROW(db.push_transaction(trx), invalid_claim_amount); + GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claim_invalid_claim_amount); op.balance_to_claim = vesting_balance_2.id; op.total_claimed.amount = 151; @@ -1058,7 +1058,7 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) trx.sign(n_key); trx.sign(v2_key); // Attempting to claim 151 from a balance with 150 available - GRAPHENE_CHECK_THROW(db.push_transaction(trx), invalid_claim_amount); + GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claim_invalid_claim_amount); op.balance_to_claim = vesting_balance_2.id; op.total_claimed.amount = 100; @@ -1077,7 +1077,7 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) trx.sign(n_key); trx.sign(v2_key); // Attempting to claim twice within a day - GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claimed_too_often); + GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claim_claimed_too_often); db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1).first, delegate_priv_key, database::skip_nothing); slot = db.get_slot_at_time(vesting_balance_1.vesting_policy->begin_timestamp + 60); @@ -1103,7 +1103,7 @@ BOOST_AUTO_TEST_CASE( balance_object_test ) trx.sign(n_key); trx.sign(v2_key); // Attempting to claim twice within a day - GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claimed_too_often); + GRAPHENE_CHECK_THROW(db.push_transaction(trx), balance_claim_claimed_too_often); db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1).first, delegate_priv_key, database::skip_nothing); slot = db.get_slot_at_time(db.head_block_time() + fc::days(1));