Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions libraries/chain/db_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include <graphene/chain/db_with.hpp>
#include <graphene/chain/hardfork.hpp>

#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/betting_market.hpp>

#include <graphene/chain/block_summary_object.hpp>
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
Expand Down Expand Up @@ -66,9 +69,14 @@ namespace {
std::vector<fc::sha256> gather_proposed_operations_digests(const graphene::chain::transaction& trx)
{
proposed_operations_digest_accumulator digest_accumulator;

for (auto& operation: trx.operations)
{
operation.visit(digest_accumulator);
if( operation.which() != graphene::chain::operation::tag<graphene::chain::betting_market_group_create_operation>::value
&& operation.which() != graphene::chain::operation::tag<graphene::chain::betting_market_create_operation>::value )
operation.visit(digest_accumulator);
else
edump( ("Found dup"));
}

return digest_accumulator.proposed_operations_digests;
Expand Down Expand Up @@ -148,10 +156,8 @@ void database::check_tansaction_for_duplicated_operations(const signed_transacti

proposal_index.inspect_all_objects( [&](const object& obj){
const proposal_object& proposal = static_cast<const proposal_object&>(obj);
for (auto& operation: proposal.proposed_transaction.operations)
{
existed_operations_digests.insert(fc::digest(operation));
}
auto proposed_operations_digests = gather_proposed_operations_digests( proposal.proposed_transaction );
existed_operations_digests.insert( proposed_operations_digests.begin(), proposed_operations_digests.end() );
});

for (auto& pending_transaction: _pending_tx)
Expand Down
62 changes: 61 additions & 1 deletion tests/betting/betting_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include <fc/log/appender.hpp>
#include <openssl/rand.h>

#include <graphene/chain/protocol/proposal.hpp>

#include <graphene/utilities/tempdir.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/is_authorized_asset.hpp>
Expand Down Expand Up @@ -2937,6 +2939,64 @@ BOOST_AUTO_TEST_CASE( wimbledon_2017_gentelmen_singles_final_test )
} FC_LOG_AND_RETHROW()
}

// reworked check_transasction for duplicate
// now should not through an exception when there are different events with the same betting_market_group
// and or the same betting_market
BOOST_AUTO_TEST_CASE( check_transaction_for_duplicate_reworked_test )
{
std::vector<internationalized_string_type> names_vec(104);

// create 104 pattern for first name
for( char co = 'A'; co <= 'D'; ++co ) {
for( char ci = 'A'; ci <= 'Z'; ++ci ) {
std::string first_name = std::to_string(co) + std::to_string(ci);
std::string second_name = first_name + first_name;
names_vec.push_back( {{ first_name, second_name }} );
}
}

sport_id_type sport_id = create_sport( {{"SN","SPORT_NAME"}} ).id;

event_group_id_type event_group_id = create_event_group( {{"EG", "EVENT_GROUP"}}, sport_id ).id;

betting_market_rules_id_type betting_market_rules_id =
create_betting_market_rules( {{"EN", "Rules"}}, {{"EN", "Some rules"}} ).id;

for( const auto& name : names_vec )
{
proposal_create_operation pcop = proposal_create_operation::committee_proposal(
db.get_global_properties().parameters,
db.head_block_time()
);
pcop.review_period_seconds.reset();

event_create_operation evcop;
evcop.event_group_id = event_group_id;
evcop.name = name;
evcop.season = name;

betting_market_group_create_operation bmgcop;
bmgcop.description = name;
bmgcop.event_id = object_id_type(relative_protocol_ids, 0, 0);
bmgcop.rules_id = betting_market_rules_id;
bmgcop.asset_id = asset_id_type();

betting_market_create_operation bmcop;
bmcop.group_id = object_id_type(relative_protocol_ids, 0, 1);
bmcop.payout_condition.insert( internationalized_string_type::value_type( "CN", "CONDI_NAME" ) );

pcop.proposed_ops.emplace_back( evcop );
pcop.proposed_ops.emplace_back( bmgcop );
pcop.proposed_ops.emplace_back( bmcop );

signed_transaction trx;
set_expiration( db, trx );
trx.operations.push_back( pcop );

process_operation_by_witnesses( pcop );
}
}

BOOST_AUTO_TEST_SUITE_END()


Expand All @@ -2951,7 +3011,7 @@ boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
std::cout << "Random number generator seeded to " << time(NULL) << std::endl;

// betting operations don't take effect until HARDFORK 1000
GRAPHENE_TESTING_GENESIS_TIMESTAMP = HARDFORK_1000_TIME.sec_since_epoch();
GRAPHENE_TESTING_GENESIS_TIMESTAMP = HARDFORK_1000_TIME.sec_since_epoch() + 2;

return nullptr;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/common/database_fixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

using namespace graphene::chain::test;

uint32_t GRAPHENE_TESTING_GENESIS_TIMESTAMP = 1431700000;
uint32_t GRAPHENE_TESTING_GENESIS_TIMESTAMP = 1431700002;

namespace graphene { namespace chain {

Expand Down
63 changes: 63 additions & 0 deletions tests/tests/network_broadcast_api_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include <boost/test/unit_test.hpp>

#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/sport_object.hpp>
#include <graphene/chain/event_group_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/protocol/proposal.hpp>
#include <graphene/chain/proposal_object.hpp>
Expand Down Expand Up @@ -349,4 +353,63 @@ BOOST_AUTO_TEST_CASE( check_fails_for_several_transactions_with_duplicates_in_pe
}
}

BOOST_AUTO_TEST_CASE( check_passes_for_duplicated_betting_market_or_group )
{
generate_blocks( HARDFORK_1000_TIME + fc::seconds(300) );

try
{
const sport_id_type sport_id = create_sport( {{"SN","SPORT_NAME"}} ).id;
const event_group_id_type event_group_id = create_event_group( {{"EG", "EVENT_GROUP"}}, sport_id ).id;
const betting_market_rules_id_type betting_market_rules_id =
create_betting_market_rules( {{"EN", "Rules"}}, {{"EN", "Some rules"}} ).id;

event_create_operation evcop1;
evcop1.event_group_id = event_group_id;
evcop1.name = {{"NO", "NAME_ONE"}};
evcop1.season = {{"NO", "NAME_ONE"}};

event_create_operation evcop2;
evcop2.event_group_id = event_group_id;
evcop2.name = {{"NT", "NAME_TWO"}};
evcop2.season = {{"NT", "NAME_TWO"}};

betting_market_group_create_operation bmgcop;
bmgcop.description = {{"NN", "NO_NAME"}};
bmgcop.event_id = object_id_type(relative_protocol_ids, 0, 0);
bmgcop.rules_id = betting_market_rules_id;
bmgcop.asset_id = asset_id_type();

betting_market_create_operation bmcop;
bmcop.group_id = object_id_type(relative_protocol_ids, 0, 1);
bmcop.payout_condition.insert( internationalized_string_type::value_type( "CN", "CONDI_NAME" ) );

proposal_create_operation pcop1 = proposal_create_operation::committee_proposal(
db.get_global_properties().parameters,
db.head_block_time()
);
pcop1.review_period_seconds.reset();

proposal_create_operation pcop2 = pcop1;

pcop1.proposed_ops.emplace_back( evcop1 );
pcop1.proposed_ops.emplace_back( bmgcop );
pcop1.proposed_ops.emplace_back( bmcop );

pcop2.proposed_ops.emplace_back( evcop2 );
pcop2.proposed_ops.emplace_back( bmgcop );
pcop2.proposed_ops.emplace_back( bmcop );

create_proposal(*this, { pcop1, pcop2 });

auto trx = make_signed_transaction_with_proposed_operation(*this, { pcop1, pcop2 });
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_SUITE_END()