Implement the apparently-unused feature allowing later operations in a transaction to
reference objects created by earlier operations. Change all betting operations to allow use of this feature, and test it in operation_tests2
This commit is contained in:
parent
43f91d83fc
commit
5aedb65e5c
14 changed files with 294 additions and 43 deletions
|
|
@ -35,6 +35,19 @@ void_result betting_market_group_create_evaluator::do_evaluate(const betting_mar
|
||||||
{ try {
|
{ try {
|
||||||
FC_ASSERT(trx_state->_is_proposed_trx);
|
FC_ASSERT(trx_state->_is_proposed_trx);
|
||||||
|
|
||||||
|
// the event_id in the operation can be a relative id. If it is,
|
||||||
|
// resolve it and verify that it is truly an event
|
||||||
|
object_id_type resolved_event_id = op.event_id;
|
||||||
|
if (is_relative(op.event_id))
|
||||||
|
resolved_event_id = get_relative_id(op.event_id);
|
||||||
|
|
||||||
|
FC_ASSERT(resolved_event_id.space() == event_id_type::space_id &&
|
||||||
|
resolved_event_id.type() == event_id_type::type_id,
|
||||||
|
"event_id must refer to a event_id_type");
|
||||||
|
event_id = resolved_event_id;
|
||||||
|
FC_ASSERT( db().find_object(event_id), "Invalid event specified" );
|
||||||
|
|
||||||
|
// TODO: should we prevent creating multiple identical betting market groups for an event (same type & options)?
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
|
@ -42,7 +55,7 @@ object_id_type betting_market_group_create_evaluator::do_apply(const betting_mar
|
||||||
{ try {
|
{ try {
|
||||||
const betting_market_group_object& new_betting_market_group =
|
const betting_market_group_object& new_betting_market_group =
|
||||||
db().create<betting_market_group_object>( [&]( betting_market_group_object& betting_market_group_obj ) {
|
db().create<betting_market_group_object>( [&]( betting_market_group_object& betting_market_group_obj ) {
|
||||||
betting_market_group_obj.event_id = op.event_id;
|
betting_market_group_obj.event_id = event_id;
|
||||||
betting_market_group_obj.options = op.options;
|
betting_market_group_obj.options = op.options;
|
||||||
});
|
});
|
||||||
return new_betting_market_group.id;
|
return new_betting_market_group.id;
|
||||||
|
|
@ -52,6 +65,19 @@ void_result betting_market_create_evaluator::do_evaluate(const betting_market_cr
|
||||||
{ try {
|
{ try {
|
||||||
FC_ASSERT(trx_state->_is_proposed_trx);
|
FC_ASSERT(trx_state->_is_proposed_trx);
|
||||||
|
|
||||||
|
// the betting_market_group_id in the operation can be a relative id. If it is,
|
||||||
|
// resolve it and verify that it is truly an betting_market_group
|
||||||
|
object_id_type resolved_betting_market_group_id = op.group_id;
|
||||||
|
if (is_relative(op.group_id))
|
||||||
|
resolved_betting_market_group_id = get_relative_id(op.group_id);
|
||||||
|
|
||||||
|
FC_ASSERT(resolved_betting_market_group_id.space() == betting_market_group_id_type::space_id &&
|
||||||
|
resolved_betting_market_group_id.type() == betting_market_group_id_type::type_id,
|
||||||
|
"betting_market_group_id must refer to a betting_market_group_id_type");
|
||||||
|
group_id = resolved_betting_market_group_id;
|
||||||
|
FC_ASSERT( db().find_object(group_id), "Invalid betting_market_group specified" );
|
||||||
|
|
||||||
|
// TODO: should we prevent creating multiple identical betting markets groups in a group (same asset and payout condition)?
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
|
@ -59,7 +85,7 @@ object_id_type betting_market_create_evaluator::do_apply(const betting_market_cr
|
||||||
{ try {
|
{ try {
|
||||||
const betting_market_object& new_betting_market =
|
const betting_market_object& new_betting_market =
|
||||||
db().create<betting_market_object>( [&]( betting_market_object& betting_market_obj ) {
|
db().create<betting_market_object>( [&]( betting_market_object& betting_market_obj ) {
|
||||||
betting_market_obj.group_id = op.group_id;
|
betting_market_obj.group_id = group_id;
|
||||||
betting_market_obj.payout_condition = op.payout_condition;
|
betting_market_obj.payout_condition = op.payout_condition;
|
||||||
betting_market_obj.asset_id = op.asset_id;
|
betting_market_obj.asset_id = op.asset_id;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
#include <graphene/chain/competitor_evaluator.hpp>
|
#include <graphene/chain/competitor_evaluator.hpp>
|
||||||
#include <graphene/chain/competitor_object.hpp>
|
#include <graphene/chain/competitor_object.hpp>
|
||||||
|
#include <graphene/chain/sport_object.hpp>
|
||||||
#include <graphene/chain/account_object.hpp>
|
#include <graphene/chain/account_object.hpp>
|
||||||
#include <graphene/chain/database.hpp>
|
#include <graphene/chain/database.hpp>
|
||||||
#include <graphene/chain/exceptions.hpp>
|
#include <graphene/chain/exceptions.hpp>
|
||||||
|
|
@ -35,6 +36,17 @@ void_result competitor_create_evaluator::do_evaluate(const competitor_create_ope
|
||||||
{ try {
|
{ try {
|
||||||
FC_ASSERT(trx_state->_is_proposed_trx);
|
FC_ASSERT(trx_state->_is_proposed_trx);
|
||||||
|
|
||||||
|
// the sport id in the operation can be a relative id. If it is,
|
||||||
|
// resolve it and verify that it is truly a sport
|
||||||
|
object_id_type resolved_id = op.sport_id;
|
||||||
|
if (is_relative(op.sport_id))
|
||||||
|
resolved_id = get_relative_id(op.sport_id);
|
||||||
|
|
||||||
|
FC_ASSERT(resolved_id.space() == sport_id_type::space_id &&
|
||||||
|
resolved_id.type() == sport_id_type::type_id, "sport_id must refer to a sport_id_type");
|
||||||
|
sport_id = resolved_id;
|
||||||
|
|
||||||
|
FC_ASSERT( db().find_object(sport_id), "Invalid sport specified" );
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
|
@ -43,7 +55,7 @@ object_id_type competitor_create_evaluator::do_apply(const competitor_create_ope
|
||||||
const competitor_object& new_competitor =
|
const competitor_object& new_competitor =
|
||||||
db().create<competitor_object>( [&]( competitor_object& competitor_obj ) {
|
db().create<competitor_object>( [&]( competitor_object& competitor_obj ) {
|
||||||
competitor_obj.name = op.name;
|
competitor_obj.name = op.name;
|
||||||
competitor_obj.sport_id = op.sport_id;
|
competitor_obj.sport_id = sport_id;
|
||||||
});
|
});
|
||||||
return new_competitor.id;
|
return new_competitor.id;
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
|
||||||
|
|
@ -128,4 +128,18 @@ database& generic_evaluator::db()const { return trx_state->db(); }
|
||||||
db().adjust_balance(fee_payer, fee_from_account);
|
db().adjust_balance(fee_payer, fee_from_account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_id_type generic_evaluator::get_relative_id( object_id_type rel_id )const
|
||||||
|
{
|
||||||
|
if (!is_relative(rel_id))
|
||||||
|
FC_THROW("get_relative_id() called for non-relative id ${id}", ("id", rel_id));
|
||||||
|
if (rel_id.instance() >= trx_state->operation_results.size())
|
||||||
|
FC_THROW("get_relative_id() asked for id of operation ${op_num} (zero-based), but we only have ${count} operations",
|
||||||
|
("op_num", rel_id.instance())("count", trx_state->operation_results.size()));
|
||||||
|
if (trx_state->operation_results[rel_id.instance()].which() != operation_result::tag<object_id_type>::value)
|
||||||
|
FC_THROW("get_relative_id() asked for the result of operation ${op_num}, but that operation did not return an object_id",
|
||||||
|
("op_num", rel_id.instance()));
|
||||||
|
return trx_state->operation_results[rel_id.instance()].get<object_id_type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} }
|
} }
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@
|
||||||
*/
|
*/
|
||||||
#include <graphene/chain/event_evaluator.hpp>
|
#include <graphene/chain/event_evaluator.hpp>
|
||||||
#include <graphene/chain/event_object.hpp>
|
#include <graphene/chain/event_object.hpp>
|
||||||
#include <graphene/chain/account_object.hpp>
|
#include <graphene/chain/event_group_object.hpp>
|
||||||
|
#include <graphene/chain/competitor_object.hpp>
|
||||||
#include <graphene/chain/database.hpp>
|
#include <graphene/chain/database.hpp>
|
||||||
#include <graphene/chain/exceptions.hpp>
|
#include <graphene/chain/exceptions.hpp>
|
||||||
#include <graphene/chain/hardfork.hpp>
|
#include <graphene/chain/hardfork.hpp>
|
||||||
|
|
@ -35,6 +36,37 @@ void_result event_create_evaluator::do_evaluate(const event_create_operation& op
|
||||||
{ try {
|
{ try {
|
||||||
FC_ASSERT(trx_state->_is_proposed_trx);
|
FC_ASSERT(trx_state->_is_proposed_trx);
|
||||||
|
|
||||||
|
database& d = db();
|
||||||
|
|
||||||
|
// the event_group_id in the operation can be a relative id. If it is,
|
||||||
|
// resolve it and verify that it is truly an event_group
|
||||||
|
object_id_type resolved_event_group_id = op.event_group_id;
|
||||||
|
if (is_relative(op.event_group_id))
|
||||||
|
resolved_event_group_id = get_relative_id(op.event_group_id);
|
||||||
|
|
||||||
|
FC_ASSERT(resolved_event_group_id.space() == event_group_id_type::space_id &&
|
||||||
|
resolved_event_group_id.type() == event_group_id_type::type_id,
|
||||||
|
"event_group_id must refer to a event_group_id_type");
|
||||||
|
event_group_id = resolved_event_group_id;
|
||||||
|
const event_group_object& event_group = event_group_id(d);
|
||||||
|
|
||||||
|
// Likewise for each competitor in the list
|
||||||
|
for (const object_id_type& raw_competitor_id : op.competitors)
|
||||||
|
{
|
||||||
|
object_id_type resolved_competitor_id = raw_competitor_id;
|
||||||
|
if (is_relative(raw_competitor_id))
|
||||||
|
resolved_competitor_id = get_relative_id(raw_competitor_id);
|
||||||
|
|
||||||
|
FC_ASSERT(resolved_competitor_id.space() == competitor_id_type::space_id &&
|
||||||
|
resolved_competitor_id.type() == competitor_id_type::type_id,
|
||||||
|
"competitor must refer to a competitor_id_type");
|
||||||
|
competitor_id_type competitor_id = resolved_competitor_id;
|
||||||
|
const competitor_object& competitor = competitor_id(d);
|
||||||
|
FC_ASSERT(competitor.sport_id == event_group.sport_id,
|
||||||
|
"competitor must compete in the same sport as the event they're competing in");
|
||||||
|
competitors.push_back(competitor_id);
|
||||||
|
}
|
||||||
|
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
|
@ -43,6 +75,10 @@ object_id_type event_create_evaluator::do_apply(const event_create_operation& op
|
||||||
const event_object& new_event =
|
const event_object& new_event =
|
||||||
db().create<event_object>( [&]( event_object& event_obj ) {
|
db().create<event_object>( [&]( event_object& event_obj ) {
|
||||||
event_obj.name = op.name;
|
event_obj.name = op.name;
|
||||||
|
event_obj.season = op.season;
|
||||||
|
event_obj.start_time = op.start_time;
|
||||||
|
event_obj.event_group_id = event_group_id;
|
||||||
|
event_obj.competitors = competitors;
|
||||||
});
|
});
|
||||||
return new_event.id;
|
return new_event.id;
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,18 @@ void_result event_group_create_evaluator::do_evaluate(const event_group_create_o
|
||||||
{ try {
|
{ try {
|
||||||
FC_ASSERT(trx_state->_is_proposed_trx);
|
FC_ASSERT(trx_state->_is_proposed_trx);
|
||||||
|
|
||||||
|
// the sport id in the operation can be a relative id. If it is,
|
||||||
|
// resolve it and verify that it is truly a sport
|
||||||
|
object_id_type resolved_id = op.sport_id;
|
||||||
|
if (is_relative(op.sport_id))
|
||||||
|
resolved_id = get_relative_id(op.sport_id);
|
||||||
|
|
||||||
|
FC_ASSERT(resolved_id.space() == sport_id_type::space_id &&
|
||||||
|
resolved_id.type() == sport_id_type::type_id, "sport_id must refer to a sport_id_type");
|
||||||
|
sport_id = resolved_id;
|
||||||
|
|
||||||
|
FC_ASSERT( db().find_object(sport_id), "Invalid sport specified" );
|
||||||
|
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
|
@ -43,7 +55,7 @@ object_id_type event_group_create_evaluator::do_apply(const event_group_create_o
|
||||||
const event_group_object& new_event_group =
|
const event_group_object& new_event_group =
|
||||||
db().create<event_group_object>( [&]( event_group_object& event_group_obj ) {
|
db().create<event_group_object>( [&]( event_group_object& event_group_obj ) {
|
||||||
event_group_obj.name = op.name;
|
event_group_obj.name = op.name;
|
||||||
event_group_obj.sport_id = op.sport_id;
|
event_group_obj.sport_id = sport_id;
|
||||||
});
|
});
|
||||||
return new_event_group.id;
|
return new_event_group.id;
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
void_result do_evaluate( const betting_market_group_create_operation& o );
|
void_result do_evaluate( const betting_market_group_create_operation& o );
|
||||||
object_id_type do_apply( const betting_market_group_create_operation& o );
|
object_id_type do_apply( const betting_market_group_create_operation& o );
|
||||||
|
private:
|
||||||
|
event_id_type event_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class betting_market_create_evaluator : public evaluator<betting_market_create_evaluator>
|
class betting_market_create_evaluator : public evaluator<betting_market_create_evaluator>
|
||||||
|
|
@ -45,6 +47,8 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
void_result do_evaluate( const betting_market_create_operation& o );
|
void_result do_evaluate( const betting_market_create_operation& o );
|
||||||
object_id_type do_apply( const betting_market_create_operation& o );
|
object_id_type do_apply( const betting_market_create_operation& o );
|
||||||
|
private:
|
||||||
|
betting_market_group_id_type group_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
void_result do_evaluate( const competitor_create_operation& o );
|
void_result do_evaluate( const competitor_create_operation& o );
|
||||||
object_id_type do_apply( const competitor_create_operation& o );
|
object_id_type do_apply( const competitor_create_operation& o );
|
||||||
|
private:
|
||||||
|
sport_id_type sport_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
void_result do_evaluate( const event_create_operation& o );
|
void_result do_evaluate( const event_create_operation& o );
|
||||||
object_id_type do_apply( const event_create_operation& o );
|
object_id_type do_apply( const event_create_operation& o );
|
||||||
|
private:
|
||||||
|
event_group_id_type event_group_id;
|
||||||
|
vector<competitor_id_type> competitors;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
void_result do_evaluate( const event_group_create_operation& o );
|
void_result do_evaluate( const event_group_create_operation& o );
|
||||||
object_id_type do_apply( const event_group_create_operation& o );
|
object_id_type do_apply( const event_group_create_operation& o );
|
||||||
|
|
||||||
|
private:
|
||||||
|
sport_id_type sport_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,11 @@ struct betting_market_group_create_operation : public base_operation
|
||||||
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
|
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
|
||||||
asset fee;
|
asset fee;
|
||||||
|
|
||||||
event_id_type event_id;
|
/**
|
||||||
|
* This can be a event_id_type, or a
|
||||||
|
* relative object id that resolves to a event_id_type
|
||||||
|
*/
|
||||||
|
object_id_type event_id;
|
||||||
|
|
||||||
betting_market_options_type options;
|
betting_market_options_type options;
|
||||||
|
|
||||||
|
|
@ -68,7 +72,11 @@ struct betting_market_create_operation : public base_operation
|
||||||
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
|
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
|
||||||
asset fee;
|
asset fee;
|
||||||
|
|
||||||
betting_market_group_id_type group_id;
|
/**
|
||||||
|
* This can be a betting_market_group_id_type, or a
|
||||||
|
* relative object id that resolves to a betting_market_group_id_type
|
||||||
|
*/
|
||||||
|
object_id_type group_id;
|
||||||
|
|
||||||
internationalized_string_type payout_condition;
|
internationalized_string_type payout_condition;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,10 @@ struct competitor_create_operation : public base_operation
|
||||||
internationalized_string_type name;
|
internationalized_string_type name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sport the competitor, um, competes in
|
* The sport the competitor, um, competes in. This can be a sport_id_type, or a
|
||||||
|
* relative object id that resolves to a sport_id_type
|
||||||
*/
|
*/
|
||||||
sport_id_type sport_id;
|
object_id_type sport_id;
|
||||||
|
|
||||||
extensions_type extensions;
|
extensions_type extensions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,17 @@ struct event_create_operation : public base_operation
|
||||||
|
|
||||||
optional<time_point_sec> start_time;
|
optional<time_point_sec> start_time;
|
||||||
|
|
||||||
event_group_id_type event_group_id;
|
/**
|
||||||
|
* This can be a event_group_id_type, or a
|
||||||
|
* relative object id that resolves to a event_group_id_type
|
||||||
|
*/
|
||||||
|
object_id_type event_group_id;
|
||||||
|
|
||||||
vector<competitor_id_type> competitors;
|
/**
|
||||||
|
* Each entry in this vector can be a competitor_id_type, or a relative object id that
|
||||||
|
* resolves to a competitor_id_type
|
||||||
|
*/
|
||||||
|
vector<object_id_type> competitors;
|
||||||
|
|
||||||
extensions_type extensions;
|
extensions_type extensions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,11 @@ struct event_group_create_operation : public base_operation
|
||||||
*/
|
*/
|
||||||
internationalized_string_type name;
|
internationalized_string_type name;
|
||||||
|
|
||||||
sport_id_type sport_id;
|
/**
|
||||||
|
* This can be a sport_id_type, or a
|
||||||
|
* relative object id that resolves to a sport_id_type
|
||||||
|
*/
|
||||||
|
object_id_type sport_id;
|
||||||
|
|
||||||
extensions_type extensions;
|
extensions_type extensions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include <graphene/chain/witness_object.hpp>
|
#include <graphene/chain/witness_object.hpp>
|
||||||
#include <graphene/chain/worker_object.hpp>
|
#include <graphene/chain/worker_object.hpp>
|
||||||
#include <graphene/chain/sport_object.hpp>
|
#include <graphene/chain/sport_object.hpp>
|
||||||
|
#include <graphene/chain/competitor_object.hpp>
|
||||||
#include <graphene/chain/proposal_object.hpp>
|
#include <graphene/chain/proposal_object.hpp>
|
||||||
|
|
||||||
#include <graphene/utilities/tempdir.hpp>
|
#include <graphene/utilities/tempdir.hpp>
|
||||||
|
|
@ -1631,14 +1632,17 @@ BOOST_AUTO_TEST_CASE( peerplays_sport_create_test )
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
const flat_set<witness_id_type>& active_witnesses = db.get_global_properties().active_witnesses;
|
const flat_set<witness_id_type>& active_witnesses = db.get_global_properties().active_witnesses;
|
||||||
// Propose the create_sport operation
|
|
||||||
|
BOOST_TEST_MESSAGE("Propose the create_sport operation");
|
||||||
{
|
{
|
||||||
sport_create_operation create_op;
|
sport_create_operation sport_create_op;
|
||||||
create_op.name.insert(internationalized_string_type::value_type("en", "Ice Hockey"));
|
sport_create_op.name.insert(internationalized_string_type::value_type("en", "Football"));
|
||||||
|
sport_create_op.name.insert(internationalized_string_type::value_type("en_US", "Soccer"));
|
||||||
|
sport_create_op.name.insert(internationalized_string_type::value_type("zh_Hans", "足球"));
|
||||||
|
sport_create_op.name.insert(internationalized_string_type::value_type("ja", "サッカー"));
|
||||||
proposal_create_operation proposal_op;
|
proposal_create_operation proposal_op;
|
||||||
proposal_op.fee_paying_account = (*active_witnesses.begin())(db).witness_account;
|
proposal_op.fee_paying_account = (*active_witnesses.begin())(db).witness_account;
|
||||||
proposal_op.proposed_ops.emplace_back(create_op);
|
proposal_op.proposed_ops.emplace_back(sport_create_op);
|
||||||
proposal_op.expiration_time = db.head_block_time() + fc::days(1);
|
proposal_op.expiration_time = db.head_block_time() + fc::days(1);
|
||||||
|
|
||||||
signed_transaction tx;
|
signed_transaction tx;
|
||||||
|
|
@ -1651,39 +1655,153 @@ BOOST_AUTO_TEST_CASE( peerplays_sport_create_test )
|
||||||
db.push_transaction(tx);
|
db.push_transaction(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_TEST_MESSAGE( "Witness account: " << fc::json::to_pretty_string(GRAPHENE_WITNESS_ACCOUNT(db)));
|
|
||||||
|
|
||||||
BOOST_TEST_MESSAGE("There are now " << db.get_index_type<proposal_index>().indices().size() << " proposals");
|
|
||||||
const proposal_object& prop = *db.get_index_type<proposal_index>().indices().begin();
|
|
||||||
BOOST_TEST_MESSAGE("Just created sport creation proposal " << fc::variant(prop.id).as<std::string>());
|
|
||||||
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(prop.required_active_approvals.size(), 1); // should require GRAPHENE_WITNESS_ACCOUNT only
|
|
||||||
BOOST_CHECK_EQUAL(prop.required_owner_approvals.size(), 0);
|
|
||||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
|
||||||
|
|
||||||
for (const witness_id_type& witness_id : active_witnesses)
|
|
||||||
{
|
{
|
||||||
BOOST_TEST_MESSAGE("Approving sport creation from witness " << fc::variant(witness_id).as<std::string>());
|
//BOOST_TEST_MESSAGE( "Witness account: " << fc::json::to_pretty_string(GRAPHENE_WITNESS_ACCOUNT(db)));
|
||||||
const witness_object& witness = witness_id(db);
|
|
||||||
const account_object& witness_account = witness.witness_account(db);
|
|
||||||
|
|
||||||
proposal_update_operation pup;
|
BOOST_TEST_MESSAGE("There are now " << db.get_index_type<proposal_index>().indices().size() << " proposals");
|
||||||
pup.proposal = prop.id;
|
const proposal_object& prop = *db.get_index_type<proposal_index>().indices().begin();
|
||||||
pup.fee_paying_account = witness_account.id;
|
BOOST_TEST_MESSAGE("Just created sport creation proposal " << fc::variant(prop.id).as<std::string>());
|
||||||
//pup.key_approvals_to_add.insert(witness.signing_key);
|
|
||||||
pup.active_approvals_to_add.insert(witness_account.id);
|
|
||||||
|
BOOST_CHECK_EQUAL(prop.required_active_approvals.size(), 1); // should require GRAPHENE_WITNESS_ACCOUNT only
|
||||||
|
BOOST_CHECK_EQUAL(prop.required_owner_approvals.size(), 0);
|
||||||
|
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||||
|
|
||||||
|
for (const witness_id_type& witness_id : active_witnesses)
|
||||||
|
{
|
||||||
|
BOOST_TEST_MESSAGE("Approving sport creation from witness " << fc::variant(witness_id).as<std::string>());
|
||||||
|
const witness_object& witness = witness_id(db);
|
||||||
|
const account_object& witness_account = witness.witness_account(db);
|
||||||
|
|
||||||
|
proposal_update_operation pup;
|
||||||
|
pup.proposal = prop.id;
|
||||||
|
pup.fee_paying_account = witness_account.id;
|
||||||
|
//pup.key_approvals_to_add.insert(witness.signing_key);
|
||||||
|
pup.active_approvals_to_add.insert(witness_account.id);
|
||||||
|
|
||||||
|
signed_transaction tx;
|
||||||
|
tx.operations.push_back( pup );
|
||||||
|
set_expiration( db, tx );
|
||||||
|
sign(tx, init_account_priv_key);
|
||||||
|
|
||||||
|
db.push_transaction(tx, ~0);
|
||||||
|
if (db.get_index_type<sport_object_index>().indices().size() > 0)
|
||||||
|
{
|
||||||
|
BOOST_TEST_MESSAGE("The sport creation operation has been approved, new sport object on the blockchain is " << fc::json::to_pretty_string(*db.get_index_type<sport_object_index>().indices().begin()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_REQUIRE_EQUAL(db.get_index_type<sport_object_index>().indices().size(), 1);
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE("Creating a sport and competitors in the same proposal");
|
||||||
|
{
|
||||||
|
// operation 0 in the transaction
|
||||||
|
sport_create_operation sport_create_op;
|
||||||
|
sport_create_op.name.insert(internationalized_string_type::value_type("en", "Ice Hockey"));
|
||||||
|
sport_create_op.name.insert(internationalized_string_type::value_type("zh_Hans", "冰球"));
|
||||||
|
sport_create_op.name.insert(internationalized_string_type::value_type("ja", "アイスホッケー"));
|
||||||
|
|
||||||
|
// operation 1
|
||||||
|
competitor_create_operation competitor1_create_op;
|
||||||
|
competitor1_create_op.sport_id = object_id_type(relative_protocol_ids, 0, 0);
|
||||||
|
competitor1_create_op.name.insert(internationalized_string_type::value_type("en", "Washington Capitals"));
|
||||||
|
competitor1_create_op.name.insert(internationalized_string_type::value_type("zh_Hans", "華盛頓首都隊"));
|
||||||
|
competitor1_create_op.name.insert(internationalized_string_type::value_type("ja", "ワシントン・キャピタルズ"));
|
||||||
|
//BOOST_TEST_MESSAGE("Just constructed competitor_create_operation " << fc::json::to_pretty_string(competitor1_create_op));
|
||||||
|
|
||||||
|
// operation 2
|
||||||
|
competitor_create_operation competitor2_create_op;
|
||||||
|
competitor2_create_op.sport_id = object_id_type(relative_protocol_ids, 0, 0);
|
||||||
|
competitor2_create_op.name.insert(internationalized_string_type::value_type("en", "Chicago Blackhawks"));
|
||||||
|
competitor2_create_op.name.insert(internationalized_string_type::value_type("zh_Hans", "芝加哥黑鷹"));
|
||||||
|
competitor2_create_op.name.insert(internationalized_string_type::value_type("ja", "シカゴ・ブラックホークス"));
|
||||||
|
|
||||||
|
// operation 3
|
||||||
|
event_group_create_operation event_group_create_op;
|
||||||
|
event_group_create_op.name.insert(internationalized_string_type::value_type("en", "NHL"));
|
||||||
|
event_group_create_op.name.insert(internationalized_string_type::value_type("zh_Hans", "國家冰球聯盟"));
|
||||||
|
event_group_create_op.name.insert(internationalized_string_type::value_type("ja", "ナショナルホッケーリーグ"));
|
||||||
|
event_group_create_op.sport_id = object_id_type(relative_protocol_ids, 0, 0);
|
||||||
|
|
||||||
|
// operation 4
|
||||||
|
// leave name and start time blank
|
||||||
|
event_create_operation event_create_op;
|
||||||
|
event_create_op.season.insert(internationalized_string_type::value_type("en", "2016-17"));
|
||||||
|
event_create_op.event_group_id = object_id_type(relative_protocol_ids, 0, 3);
|
||||||
|
event_create_op.competitors.push_back(object_id_type(relative_protocol_ids, 0, 1));
|
||||||
|
event_create_op.competitors.push_back(object_id_type(relative_protocol_ids, 0, 2));
|
||||||
|
|
||||||
|
// operation 5
|
||||||
|
betting_market_group_create_operation betting_market_group_create_op;
|
||||||
|
betting_market_group_create_op.event_id = object_id_type(relative_protocol_ids, 0, 4);
|
||||||
|
betting_market_group_create_op.options = moneyline_market_options{};
|
||||||
|
|
||||||
|
// operation 6
|
||||||
|
betting_market_create_operation caps_win_betting_market_create_op;
|
||||||
|
caps_win_betting_market_create_op.group_id = object_id_type(relative_protocol_ids, 0, 5);
|
||||||
|
caps_win_betting_market_create_op.payout_condition.insert(internationalized_string_type::value_type("en", "Washington Capitals win"));
|
||||||
|
caps_win_betting_market_create_op.asset_id = asset_id_type();
|
||||||
|
|
||||||
|
// operation 7
|
||||||
|
betting_market_create_operation blackhawks_win_betting_market_create_op;
|
||||||
|
blackhawks_win_betting_market_create_op.group_id = object_id_type(relative_protocol_ids, 0, 5);
|
||||||
|
blackhawks_win_betting_market_create_op.payout_condition.insert(internationalized_string_type::value_type("en", "Chicago Blackhawks win"));
|
||||||
|
blackhawks_win_betting_market_create_op.asset_id = asset_id_type();
|
||||||
|
|
||||||
|
|
||||||
|
proposal_create_operation proposal_op;
|
||||||
|
proposal_op.fee_paying_account = (*active_witnesses.begin())(db).witness_account;
|
||||||
|
proposal_op.proposed_ops.emplace_back(sport_create_op);
|
||||||
|
proposal_op.proposed_ops.emplace_back(competitor1_create_op);
|
||||||
|
proposal_op.proposed_ops.emplace_back(competitor2_create_op);
|
||||||
|
proposal_op.proposed_ops.emplace_back(event_group_create_op);
|
||||||
|
proposal_op.proposed_ops.emplace_back(event_create_op);
|
||||||
|
proposal_op.proposed_ops.emplace_back(betting_market_group_create_op);
|
||||||
|
proposal_op.proposed_ops.emplace_back(caps_win_betting_market_create_op);
|
||||||
|
proposal_op.proposed_ops.emplace_back(blackhawks_win_betting_market_create_op);
|
||||||
|
proposal_op.expiration_time = db.head_block_time() + fc::days(1);
|
||||||
|
|
||||||
signed_transaction tx;
|
signed_transaction tx;
|
||||||
tx.operations.push_back( pup );
|
tx.operations.push_back(proposal_op);
|
||||||
set_expiration( db, tx );
|
set_expiration(db, tx);
|
||||||
sign(tx, init_account_priv_key);
|
sign(tx, init_account_priv_key);
|
||||||
|
//sign( tx, philbin_private_key );
|
||||||
|
|
||||||
db.push_transaction(tx, ~0);
|
// Alice and Philbin signed, but asset issuer is invalid
|
||||||
if (db.get_index_type<sport_object_index>().indices().size() > 0)
|
db.push_transaction(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_REQUIRE_EQUAL(db.get_index_type<proposal_index>().indices().size(), 1);
|
||||||
|
{
|
||||||
|
const proposal_object& prop = *db.get_index_type<proposal_index>().indices().begin();
|
||||||
|
|
||||||
|
for (const witness_id_type& witness_id : active_witnesses)
|
||||||
{
|
{
|
||||||
BOOST_TEST_MESSAGE("The sport creation operation has been approved, new sport object on the blockchain is " << fc::json::to_pretty_string(*db.get_index_type<sport_object_index>().indices().begin()));
|
BOOST_TEST_MESSAGE("Approving sport+competitors creation from witness " << fc::variant(witness_id).as<std::string>());
|
||||||
break;
|
const witness_object& witness = witness_id(db);
|
||||||
|
const account_object& witness_account = witness.witness_account(db);
|
||||||
|
|
||||||
|
proposal_update_operation pup;
|
||||||
|
pup.proposal = prop.id;
|
||||||
|
pup.fee_paying_account = witness_account.id;
|
||||||
|
//pup.key_approvals_to_add.insert(witness.signing_key);
|
||||||
|
pup.active_approvals_to_add.insert(witness_account.id);
|
||||||
|
|
||||||
|
signed_transaction tx;
|
||||||
|
tx.operations.push_back( pup );
|
||||||
|
set_expiration( db, tx );
|
||||||
|
sign(tx, init_account_priv_key);
|
||||||
|
|
||||||
|
db.push_transaction(tx, ~0);
|
||||||
|
if (db.get_index_type<sport_object_index>().indices().size() > 1)
|
||||||
|
{
|
||||||
|
BOOST_REQUIRE_EQUAL(db.get_index_type<competitor_object_index>().indices().size(), 2);
|
||||||
|
//BOOST_TEST_MESSAGE("The sport creation operation has been approved, new sport object on the blockchain is " << fc::json::to_pretty_string(*db.get_index_type<sport_object_index>().indices().rbegin()));
|
||||||
|
//BOOST_TEST_MESSAGE("The first competitor object on the blockchain is " << fc::json::to_pretty_string(*db.get_index_type<competitor_object_index>().indices().begin()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue