From 1b5a7cb213a028d4fa981063e507503dfdf9414f Mon Sep 17 00:00:00 2001 From: theoreticalbts Date: Tue, 28 Jul 2015 17:08:21 -0400 Subject: [PATCH] Implement max_auth_exceeded exception, internal exc framework, small refactor Refactor tasks: - Delete obsolete, commented-out implementation of verify_authority - Make verify_authority_accounts an implementation detail of account_evaluator.cpp - Create internal_exception macros / header - Implement max_auth_exceeded and auth_account_not_found exceptions --- libraries/chain/account_evaluator.cpp | 39 +++++++++++--- libraries/chain/evaluator.cpp | 51 ------------------- .../include/graphene/chain/evaluator.hpp | 3 -- .../include/graphene/chain/exceptions.hpp | 21 ++++---- .../graphene/chain/internal_exceptions.hpp | 38 ++++++++++++++ libraries/fc | 2 +- tests/tests/authority_tests.cpp | 2 +- 7 files changed, 85 insertions(+), 71 deletions(-) create mode 100644 libraries/chain/include/graphene/chain/internal_exceptions.hpp diff --git a/libraries/chain/account_evaluator.cpp b/libraries/chain/account_evaluator.cpp index c7e38452..9b1e6bda 100644 --- a/libraries/chain/account_evaluator.cpp +++ b/libraries/chain/account_evaluator.cpp @@ -16,11 +16,29 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include +#include #include #include namespace graphene { namespace chain { +void verify_authority_accounts( const database& db, const authority& a ) +{ + const auto& chain_params = db.get_global_properties().parameters; + GRAPHENE_ASSERT( + a.num_auths() <= chain_params.maximum_authority_membership, + internal_verify_auth_max_auth_exceeded, + "Maximum authority membership exceeded" ); + for( const auto& acnt : a.account_auths ) + { + GRAPHENE_ASSERT( db.find_object( acnt.first ) != nullptr, + internal_verify_auth_account_not_found, + "Account ${a} specified in authority does not exist", + ("a", acnt.first) ); + } +} + void_result account_create_evaluator::do_evaluate( const account_create_operation& op ) { try { database& d = db(); @@ -31,9 +49,13 @@ void_result account_create_evaluator::do_evaluate( const account_create_operatio const auto& global_props = d.get_global_properties(); const auto& chain_params = global_props.parameters; - - verify_authority_accounts( op.owner ); - verify_authority_accounts( op.active ); + try + { + verify_authority_accounts( d, op.owner ); + verify_authority_accounts( d, op.active ); + } + GRAPHENE_RECODE_EXC( internal_verify_auth_max_auth_exceeded, account_create_max_auth_exceeded ) + GRAPHENE_RECODE_EXC( internal_verify_auth_account_not_found, account_create_auth_account_not_found ) uint32_t max_vote_id = global_props.next_available_vote_id; FC_ASSERT( op.options.num_witness <= chain_params.maximum_witness_count ); @@ -104,10 +126,15 @@ void_result account_update_evaluator::do_evaluate( const account_update_operatio { try { database& d = db(); - const auto& chain_params = db().get_global_properties().parameters; + const auto& chain_params = d.get_global_properties().parameters; - if( o.owner ) verify_authority_accounts( *o.owner ); - if( o.active ) verify_authority_accounts( *o.active ); + try + { + if( o.owner ) verify_authority_accounts( d, *o.owner ); + if( o.active ) verify_authority_accounts( d, *o.active ); + } + GRAPHENE_RECODE_EXC( internal_verify_auth_max_auth_exceeded, account_update_max_auth_exceeded ) + GRAPHENE_RECODE_EXC( internal_verify_auth_account_not_found, account_update_auth_account_not_found ) acnt = &o.account(d); diff --git a/libraries/chain/evaluator.cpp b/libraries/chain/evaluator.cpp index b396611e..cb8a7afb 100644 --- a/libraries/chain/evaluator.cpp +++ b/libraries/chain/evaluator.cpp @@ -77,55 +77,4 @@ database& generic_evaluator::db()const { return trx_state->db(); } }); } FC_CAPTURE_AND_RETHROW() } - /* - bool generic_evaluator::verify_authority( const account_object& a, authority::classification c ) - { try { - return trx_state->check_authority( a, c ); - } FC_CAPTURE_AND_RETHROW( (a)(c) ) } - - void generic_evaluator::check_required_authorities(const operation& op) - { try { - flat_set active_auths; - flat_set owner_auths; - vector other_auths; - - operation_get_required_authorities( op, active_auths, owner_auths, other_auths ); - - for( auto id : active_auths ) - { - GRAPHENE_ASSERT( - verify_authority(id(db()), authority::active) || - verify_authority(id(db()), authority::owner), - tx_missing_active_auth, - "missing required active authority ${id}", ("id", id)); - } - - for( auto id : owner_auths ) - { - GRAPHENE_ASSERT( - verify_authority(id(db()), authority::owner), - tx_missing_owner_auth, - "missing required owner authority ${id}", ("id", id)); - } - - for( const auto& auth : other_auths ) - { - GRAPHENE_ASSERT( - trx_state->check_authority(auth), - tx_missing_other_auth, - "missing required authority ${auth}", - ("auth",auth)("sigs",trx_state->_sigs)); - } - - } FC_CAPTURE_AND_RETHROW( (op) ) } - */ - - void generic_evaluator::verify_authority_accounts( const authority& a )const - { - const auto& chain_params = db().get_global_properties().parameters; - FC_ASSERT( a.num_auths() <= chain_params.maximum_authority_membership ); - for( const auto& acnt : a.account_auths ) - acnt.first(db()); - } - } } diff --git a/libraries/chain/include/graphene/chain/evaluator.hpp b/libraries/chain/include/graphene/chain/evaluator.hpp index 218d2224..5f58efb9 100644 --- a/libraries/chain/include/graphene/chain/evaluator.hpp +++ b/libraries/chain/include/graphene/chain/evaluator.hpp @@ -98,11 +98,8 @@ namespace graphene { namespace chain { /// Pays the fee and returns the number of CORE asset that were paid. void pay_fee(); - //bool verify_authority(const account_object&, authority::classification); object_id_type get_relative_id( object_id_type rel_id )const; - void verify_authority_accounts( const authority& a )const; - asset fee_from_account; share_type core_fee_paid; const account_object* fee_paying_account = nullptr; diff --git a/libraries/chain/include/graphene/chain/exceptions.hpp b/libraries/chain/include/graphene/chain/exceptions.hpp index 228e218a..1a55862d 100644 --- a/libraries/chain/include/graphene/chain/exceptions.hpp +++ b/libraries/chain/include/graphene/chain/exceptions.hpp @@ -81,7 +81,6 @@ namespace graphene { namespace chain { FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::chain_exception, 37006, "insufficient feeds" ) 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" ) @@ -89,11 +88,16 @@ namespace graphene { namespace chain { //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_BASE_EXCEPTIONS( account_create ); - //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( account_update ); + 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_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_BASE_EXCEPTIONS( account_whitelist ); //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( account_upgrade ); //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( account_transfer ); @@ -104,7 +108,6 @@ 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_BASE_EXCEPTIONS( asset_fund_fee_pool ); @@ -115,7 +118,6 @@ 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" ) @@ -134,16 +136,13 @@ 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_BASE_EXCEPTIONS( override_transfer ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( not_permitted, override_transfer, 1, "not permitted" ) - GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( blind_transfer ); GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" ); @@ -235,4 +234,8 @@ namespace graphene { namespace chain { FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_undefined, graphene::chain::evaluation_error, 38003, "price multiplication undefined product 0*inf" ) */ + #define GRAPHENE_RECODE_EXC( cause_type, effect_type ) \ + catch( const cause_type& e ) \ + { throw( effect_type( e.what(), e.get_log() ) ); } + } } // graphene::chain diff --git a/libraries/chain/include/graphene/chain/internal_exceptions.hpp b/libraries/chain/include/graphene/chain/internal_exceptions.hpp new file mode 100644 index 00000000..ad9378d5 --- /dev/null +++ b/libraries/chain/include/graphene/chain/internal_exceptions.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015, Cryptonomex, Inc. + * All rights reserved. + * + * This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and + * the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification, + * are permitted until September 8, 2015, provided that the following conditions are met: + * + * 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once + +#include +#include + +#define GRAPHENE_DECLARE_INTERNAL_EXCEPTION( exc_name, seqnum, msg ) \ + FC_DECLARE_DERIVED_EXCEPTION( \ + internal_ ## exc_name, \ + graphene::chain::internal_exception, \ + 3990000 + seqnum, \ + msg \ + ) + +namespace graphene { namespace chain { + +FC_DECLARE_DERIVED_EXCEPTION( internal_exception, graphene::chain::chain_exception, 3990000, "internal exception" ) + +GRAPHENE_DECLARE_INTERNAL_EXCEPTION( verify_auth_max_auth_exceeded, 1, "Exceeds max authority fan-out" ) +GRAPHENE_DECLARE_INTERNAL_EXCEPTION( verify_auth_account_not_found, 2, "Auth account not found" ) + +} } // graphene::chain diff --git a/libraries/fc b/libraries/fc index a31f0f50..d11b48a0 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit a31f0f503df4d70ebb5960803c7092dc170bee92 +Subproject commit d11b48a015e0c339cc20f739ef1f8a5b3c57b913 diff --git a/tests/tests/authority_tests.cpp b/tests/tests/authority_tests.cpp index 674844c3..d0dcb41f 100644 --- a/tests/tests/authority_tests.cpp +++ b/tests/tests/authority_tests.cpp @@ -951,7 +951,7 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture ) if( num_keys > max_authority_membership ) { - GRAPHENE_REQUIRE_THROW(PUSH_TX( db, tx, ~0 ), fc::exception); + GRAPHENE_REQUIRE_THROW( PUSH_TX( db, tx, ~0 ), account_create_max_auth_exceeded ); } else {