From 63f4c7f2c5921f097a6b706f924ba6ad4e3da213 Mon Sep 17 00:00:00 2001 From: Apr Team Date: Thu, 12 Jul 2018 17:18:55 +0300 Subject: [PATCH] Added pending list check. --- libraries/chain/db_block.cpp | 13 ++- tests/tests/network_broadcast_api_tests.cpp | 99 +++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 29b0eeaf..bd917960 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -143,12 +143,23 @@ void database::check_tansaction_for_duplicated_operations(const signed_transacti } }); + for (auto& pending_transaction: _pending_tx) + { + proposed_operations_digest_accumulator digest_accumulator; + for (auto& operation: pending_transaction.operations) + { + operation.visit(digest_accumulator); + } + + existed_operations_digests.insert(digest_accumulator.proposed_operations_digests.begin(), digest_accumulator.proposed_operations_digests.end()); + } + proposed_operations_digest_accumulator digest_accumulator; for (auto& operation: trx.operations) { operation.visit(digest_accumulator); } - + for (auto& digest: digest_accumulator.proposed_operations_digests) { FC_ASSERT(existed_operations_digests.count(digest) == 0, "Proposed operation is already pending for approval."); diff --git a/tests/tests/network_broadcast_api_tests.cpp b/tests/tests/network_broadcast_api_tests.cpp index a4aad6aa..b0fc81b0 100644 --- a/tests/tests/network_broadcast_api_tests.cpp +++ b/tests/tests/network_broadcast_api_tests.cpp @@ -86,6 +86,26 @@ namespace return transaction; } + + void push_proposal(database_fixture& fixture, const account_object& fee_payer, const std::vector& operations) + { + proposal_create_operation operation_proposal; + operation_proposal.fee_paying_account = fee_payer.id; + + for (auto& operation: operations) + { + operation_proposal.proposed_ops.push_back(op_wrapper(operation)); + } + + operation_proposal.expiration_time = fixture.db.head_block_time() + fc::days(1); + + signed_transaction transaction; + transaction.operations.push_back(operation_proposal); + set_expiration( fixture.db, transaction ); + + fixture.sign( transaction, fixture.init_account_priv_key ); + PUSH_TX( fixture.db, transaction ); + } } BOOST_FIXTURE_TEST_SUITE( check_tansaction_for_duplicated_operations, database_fixture ) @@ -274,4 +294,83 @@ BOOST_AUTO_TEST_CASE( check_failes_for_several_operations_of_mixed_type ) } } +BOOST_AUTO_TEST_CASE( check_failes_for_duplicates_in_pending_transactions_list ) +{ + try + { + ACTORS((alice)) + + fc::ecc::private_key committee_key = init_account_priv_key; + + const account_object& moneyman = create_account("moneyman", init_account_pub_key); + const asset_object& core = asset_id_type()(db); + + transfer(account_id_type()(db), moneyman, core.amount(1000000)); + + auto duplicate = make_transfer_operation(alice.id, moneyman.get_id(), asset(100)); + push_proposal(*this, moneyman, {duplicate}); + + auto trx = make_signed_transaction_with_proposed_operation(*this, {duplicate}); + BOOST_CHECK_THROW(db.check_tansaction_for_duplicated_operations(trx), fc::exception); + } + catch( const fc::exception& e ) + { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( check_passes_for_no_duplicates_in_pending_transactions_list ) +{ + try + { + ACTORS((alice)) + + fc::ecc::private_key committee_key = init_account_priv_key; + + const account_object& moneyman = create_account("moneyman", init_account_pub_key); + const asset_object& core = asset_id_type()(db); + + transfer(account_id_type()(db), moneyman, core.amount(1000000)); + + push_proposal(*this, moneyman, {make_transfer_operation(alice.id, moneyman.get_id(), asset(100))}); + + auto trx = make_signed_transaction_with_proposed_operation(*this, {make_transfer_operation(alice.id, moneyman.get_id(), asset(101))}); + BOOST_CHECK_NO_THROW(db.check_tansaction_for_duplicated_operations(trx)); + } + catch( const fc::exception& e ) + { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE( check_fails_for_several_trаnsactions_with_duplicates_in_pending_list ) +{ + try + { + ACTORS((alice)) + + fc::ecc::private_key committee_key = init_account_priv_key; + + const account_object& moneyman = create_account("moneyman", init_account_pub_key); + const asset_object& core = asset_id_type()(db); + + transfer(account_id_type()(db), moneyman, core.amount(1000000)); + + auto duplicate = make_transfer_operation(alice.id, moneyman.get_id(), asset(100)); + push_proposal(*this, moneyman, {make_transfer_operation(alice.id, moneyman.get_id(), asset(101)), + duplicate}); + + auto trx = make_signed_transaction_with_proposed_operation(*this, {duplicate, + make_transfer_operation(alice.id, moneyman.get_id(), asset(102))}); + BOOST_CHECK_THROW(db.check_tansaction_for_duplicated_operations(trx), fc::exception); + } + catch( const fc::exception& e ) + { + edump((e.to_detail_string())); + throw; + } +} + BOOST_AUTO_TEST_SUITE_END()