From ee8429938cc1047f229aebf3057ab7382cc518e2 Mon Sep 17 00:00:00 2001 From: dimfred Date: Mon, 28 Jan 2019 11:51:26 +0100 Subject: [PATCH] moved check_trx_for_duplicate_operation and digest_accumulator to database api --- libraries/app/database_api.cpp | 68 +++++++++++++++++++ .../app/include/graphene/app/database_api.hpp | 7 ++ libraries/chain/db_block.cpp | 61 ----------------- .../chain/include/graphene/chain/database.hpp | 2 - 4 files changed, 75 insertions(+), 63 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index d3af2f29..7a485091 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -45,6 +45,42 @@ typedef std::map< std::pair, std::vector > market_queue_type; + +namespace { + + struct proposed_operations_digest_accumulator + { + typedef void result_type; + + void operator()(const graphene::chain::proposal_create_operation& proposal) + { + for (auto& operation: proposal.proposed_ops) + { + proposed_operations_digests.push_back(fc::digest(operation.op)); + } + } + + //empty template method is needed for all other operation types + //we can ignore them, we are interested in only proposal_create_operation + template + void operator()(const T&) + {} + + std::vector proposed_operations_digests; + }; + + std::vector gather_proposed_operations_digests(const graphene::chain::transaction& trx) + { + proposed_operations_digest_accumulator digest_accumulator; + for (auto& operation: trx.operations) + { + operation.visit(digest_accumulator); + } + + return digest_accumulator.proposed_operations_digests; + } +} + namespace graphene { namespace app { class database_api_impl; @@ -70,6 +106,7 @@ class database_api_impl : public std::enable_shared_from_this map> get_block_header_batch(const vector block_nums)const; optional get_block(uint32_t block_num)const; processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const; + void check_transaction_for_duplicated_operations(const signed_transaction& trx); // Globals chain_property_object get_chain_properties()const; @@ -429,6 +466,37 @@ processed_transaction database_api_impl::get_transaction(uint32_t block_num, uin return opt_block->transactions[trx_num]; } +void database_api::check_transaction_for_duplicated_operations(const signed_transaction& trx) +{ + my->check_transaction_for_duplicated_operations(trx); +} + +void database_api_impl::check_transaction_for_duplicated_operations(const signed_transaction& trx) +{ + const auto& proposal_index = get_index(); + std::set existed_operations_digests; + + proposal_index.inspect_all_objects( [&](const object& obj){ + const proposal_object& proposal = static_cast(obj); + for (auto& operation: proposal.proposed_transaction.operations) + { + existed_operations_digests.insert(fc::digest(operation)); + } + }); + + for (auto& pending_transaction: _pending_tx) + { + auto proposed_operations_digests = gather_proposed_operations_digests(pending_transaction); + existed_operations_digests.insert(proposed_operations_digests.begin(), proposed_operations_digests.end()); + } + + auto proposed_operations_digests = gather_proposed_operations_digests(trx); + for (auto& digest: proposed_operations_digests) + { + FC_ASSERT(existed_operations_digests.count(digest) == 0, "Proposed operation is already pending for approval."); + } +} + ////////////////////////////////////////////////////////////////////// // // // Globals // diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 7b0943e4..2b70d965 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -192,6 +192,12 @@ class database_api */ optional get_recent_transaction_by_id( const transaction_id_type& id )const; + /** + * TODO + * + */ + void check_transaction_for_duplicated_operations(const signed_transaction& trx); + ///////////// // Globals // ///////////// @@ -645,6 +651,7 @@ class database_api */ vector get_registered_tournaments(account_id_type account_filter, uint32_t limit) const; + private: std::shared_ptr< database_api_impl > my; }; diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 66126dbf..0203911c 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -40,41 +40,6 @@ #include -namespace { - - struct proposed_operations_digest_accumulator - { - typedef void result_type; - - void operator()(const graphene::chain::proposal_create_operation& proposal) - { - for (auto& operation: proposal.proposed_ops) - { - proposed_operations_digests.push_back(fc::digest(operation.op)); - } - } - - //empty template method is needed for all other operation types - //we can ignore them, we are interested in only proposal_create_operation - template - void operator()(const T&) - {} - - std::vector proposed_operations_digests; - }; - - std::vector gather_proposed_operations_digests(const graphene::chain::transaction& trx) - { - proposed_operations_digest_accumulator digest_accumulator; - for (auto& operation: trx.operations) - { - operation.visit(digest_accumulator); - } - - return digest_accumulator.proposed_operations_digests; - } -} - namespace graphene { namespace chain { bool database::is_known_block( const block_id_type& id )const @@ -140,32 +105,6 @@ std::vector database::get_block_ids_on_fork(block_id_type head_of result.emplace_back(branches.first.back()->previous_id()); return result; } - -void database::check_tansaction_for_duplicated_operations(const signed_transaction& trx) -{ - const auto& proposal_index = get_index(); - std::set existed_operations_digests; - - proposal_index.inspect_all_objects( [&](const object& obj){ - const proposal_object& proposal = static_cast(obj); - for (auto& operation: proposal.proposed_transaction.operations) - { - existed_operations_digests.insert(fc::digest(operation)); - } - }); - - for (auto& pending_transaction: _pending_tx) - { - auto proposed_operations_digests = gather_proposed_operations_digests(pending_transaction); - existed_operations_digests.insert(proposed_operations_digests.begin(), proposed_operations_digests.end()); - } - - auto proposed_operations_digests = gather_proposed_operations_digests(trx); - for (auto& digest: proposed_operations_digests) - { - FC_ASSERT(existed_operations_digests.count(digest) == 0, "Proposed operation is already pending for approval."); - } -} /** * Push block "may fail" in which case every partial change is unwound. After diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index af50a94b..02fe64f6 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -136,8 +136,6 @@ namespace graphene { namespace chain { void add_checkpoints( const flat_map& checkpts ); const flat_map get_checkpoints()const { return _checkpoints; } bool before_last_checkpoint()const; - - void check_tansaction_for_duplicated_operations(const signed_transaction& trx); bool push_block( const signed_block& b, uint32_t skip = skip_nothing ); processed_transaction push_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );