Compare commits

...

7 commits

Author SHA1 Message Date
dimfred
ab4749d4ce
added test 2019-03-26 16:53:21 +01:00
dimfred
2d388452d9
manager sport, event_grp, event, bett_grp, bett_mark 2019-03-26 14:12:11 +01:00
dimfred
1fed05a85a
added HARDFORK_MANAGER.hf 2019-03-26 14:11:20 +01:00
dimfred
a6a00308f8
clean some errors 2019-03-26 14:11:20 +01:00
dimfred
2eaa843d26
more test updates (temp) 2019-03-26 14:11:20 +01:00
dimfred
cce5dcf6d0
added manger to sports + test (temp) 2019-03-26 14:11:20 +01:00
dimfred
38272423c7
Initital commit 2019-03-26 14:11:20 +01:00
18 changed files with 1465 additions and 61 deletions

View file

@ -108,7 +108,7 @@ add_library( graphene_chain
betting_market_evaluator.cpp
betting_market_object.cpp
betting_market_group_object.cpp
manager.cpp
affiliate_payout.cpp
${HEADERS}

View file

@ -31,6 +31,7 @@
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/manager.hpp>
namespace graphene { namespace chain {
@ -75,8 +76,6 @@ void_result betting_market_group_create_evaluator::do_evaluate(const betting_mar
{ try {
database& d = db();
FC_ASSERT(d.head_block_time() >= HARDFORK_1000_TIME);
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;
@ -89,6 +88,15 @@ void_result betting_market_group_create_evaluator::do_evaluate(const betting_mar
_event_id = resolved_event_id;
FC_ASSERT(d.find_object(_event_id), "Invalid event specified");
if( d.head_block_time() < HARDFORK_MANAGER_TIME ) {
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), _event_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
FC_ASSERT(d.find_object(op.asset_id), "Invalid asset specified");
// the rules_id in the operation can be a relative id. If it is,
@ -123,7 +131,16 @@ void_result betting_market_group_update_evaluator::do_evaluate(const betting_mar
{ try {
database& d = db();
FC_ASSERT(d.head_block_time() >= HARDFORK_1000_TIME);
FC_ASSERT(trx_state->_is_proposed_trx);
if( d.head_block_time() < HARDFORK_MANAGER_TIME ) {
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), op.betting_market_group_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
_betting_market_group = &op.betting_market_group_id(d);
FC_ASSERT(op.new_description || op.new_rules_id || op.status, "nothing to change");
@ -197,7 +214,6 @@ void_result betting_market_group_update_evaluator::do_apply(const betting_market
void_result betting_market_create_evaluator::do_evaluate(const betting_market_create_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1000_TIME);
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
@ -211,6 +227,15 @@ void_result betting_market_create_evaluator::do_evaluate(const betting_market_cr
_group_id = resolved_betting_market_group_id;
FC_ASSERT(db().find_object(_group_id), "Invalid betting_market_group specified");
if( db().head_block_time() < HARDFORK_MANAGER_TIME ) {
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), _group_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -229,7 +254,16 @@ void_result betting_market_update_evaluator::do_evaluate(const betting_market_up
{ try {
database& d = db();
FC_ASSERT(d.head_block_time() >= HARDFORK_1000_TIME);
FC_ASSERT(trx_state->_is_proposed_trx);
if( d.head_block_time() < HARDFORK_MANAGER_TIME ) {
FC_ASSERT(trx_state->_is_proposed_trx);
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), op.betting_market_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
_betting_market = &op.betting_market_id(d);
FC_ASSERT(op.new_group_id.valid() || op.new_description.valid() || op.new_payout_condition.valid(), "nothing to change");
@ -245,6 +279,13 @@ void_result betting_market_update_evaluator::do_evaluate(const betting_market_up
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;
if( db().head_block_time() >= HARDFORK_MANAGER_TIME )
{
FC_ASSERT( is_manager( db(), _group_id, op.fee_payer() ),
"no manager permission for the new_betting_market_group_id" );
}
FC_ASSERT(d.find_object(_group_id), "invalid betting_market_group specified");
}
@ -365,6 +406,16 @@ void_result betting_market_group_resolve_evaluator::do_evaluate(const betting_ma
{ try {
database& d = db();
FC_ASSERT(d.head_block_time() >= HARDFORK_1000_TIME);
if( d.head_block_time() <= HARDFORK_MANAGER_TIME ) {
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( d, op.betting_market_group_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
_betting_market_group = &op.betting_market_group_id(d);
d.validate_betting_market_group_resolutions(*_betting_market_group, op.resolutions);
return void_result();
@ -379,6 +430,14 @@ void_result betting_market_group_resolve_evaluator::do_apply(const betting_marke
void_result betting_market_group_cancel_unmatched_bets_evaluator::do_evaluate(const betting_market_group_cancel_unmatched_bets_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1000_TIME);
if( db().head_block_time() <= HARDFORK_MANAGER_TIME ) {
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), op.betting_market_group_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
_betting_market_group = &op.betting_market_group_id(db());
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

View file

@ -476,7 +476,8 @@ int match_bet(database& db, const bet_object& taker_bet, const bet_object& maker
share_type maximum_factor = std::min(maximum_taker_factor, maximum_maker_factor);
share_type maker_amount_to_match = maximum_factor * maker_odds_ratio;
share_type taker_amount_to_match = maximum_factor * taker_odds_ratio;
fc_idump(fc::logger::get("betting"), (maker_amount_to_match)(taker_amount_to_match));
//TODO
//fc_idump(fc::logger::get("betting"), (maker_amount_to_match)(taker_amount_to_match));
// TODO: analyze whether maximum_maker_amount_to_match can ever be zero here
assert(maker_amount_to_match != 0);
@ -554,7 +555,8 @@ int match_bet(database& db, const bet_object& taker_bet, const bet_object& maker
("taker_refund_amount", taker_refund_amount)
("maker_odds", maker_bet.backer_multiplier)
("taker_odds", taker_bet.backer_multiplier));
fc_ddump(fc::logger::get("betting"), (taker_bet));
// TODO
//fc_ddump(fc::logger::get("betting"), (taker_bet));
db.adjust_balance(taker_bet.bettor_id, asset(taker_refund_amount, taker_bet.amount_to_bet.asset_id));
// TODO: update global statistics
@ -635,8 +637,9 @@ bool database::place_bet(const bet_object& new_bet_object)
// we continue if the maker bet was completely consumed AND the taker bet was not
finished = orders_matched_flags != 2;
}
if (!(orders_matched_flags & 1))
fc_ddump(fc::logger::get("betting"), (new_bet_object));
//TODO
//if (!(orders_matched_flags & 1))
// fc_ddump(fc::logger::get("betting"), (new_bet_object));
// return true if the taker bet was completely consumed

View file

@ -24,18 +24,19 @@
#include <graphene/chain/event_evaluator.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/chain/event_group_object.hpp>
#include <graphene/chain/sport_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/global_betting_statistics_object.hpp>
#include <graphene/chain/manager.hpp>
namespace graphene { namespace chain {
void_result event_create_evaluator::do_evaluate(const event_create_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1000_TIME);
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,
@ -48,7 +49,15 @@ void_result event_create_evaluator::do_evaluate(const event_create_operation& op
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);
if( db().head_block_time() < HARDFORK_MANAGER_TIME ) { // remove after HARDFORK_MANAGER_TIME
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.new_manager && !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), event_group_id, op.fee_payer() ),
"trx is not proposed and fee_payer is not the manager of this object" );
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -62,7 +71,10 @@ object_id_type event_create_evaluator::do_apply(const event_create_operation& op
event_obj.season = op.season;
event_obj.start_time = op.start_time;
event_obj.event_group_id = event_group_id;
if( op.extensions.value.new_manager )
event_obj.manager = *op.extensions.value.new_manager;
});
//increment number of active events in global betting statistics object
const global_betting_statistics_object& betting_statistics = global_betting_statistics_id_type()(d);
d.modify( betting_statistics, [&](global_betting_statistics_object& bso) {
@ -74,10 +86,20 @@ object_id_type event_create_evaluator::do_apply(const event_create_operation& op
void_result event_update_evaluator::do_evaluate(const event_update_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1000_TIME);
FC_ASSERT(trx_state->_is_proposed_trx);
FC_ASSERT(op.new_event_group_id || op.new_name || op.new_season ||
op.new_start_time || op.new_status, "nothing to change");
if( db().head_block_time() < HARDFORK_MANAGER_TIME ) { // remove after HARDFORK_MANAGER_TIME
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.new_manager && !op.extensions.value.fee_paying_account );
FC_ASSERT( op.new_event_group_id || op.new_name || op.new_season ||
op.new_start_time || op.new_status, "nothing to change");
}
else {
FC_ASSERT( is_manager( db(), op.event_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
FC_ASSERT( op.new_event_group_id || op.new_name || op.new_season ||
op.new_start_time || op.new_status || op.extensions.value.new_manager,
"nothing to change" );
}
if (op.new_event_group_id)
{
object_id_type resolved_event_group_id = *op.new_event_group_id;
@ -88,6 +110,12 @@ void_result event_update_evaluator::do_evaluate(const event_update_operation& op
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;
if( db().head_block_time() >= HARDFORK_MANAGER_TIME )
{
FC_ASSERT( is_manager( db(), event_group_id, *op.extensions.value.fee_paying_account ),
"no manager permission for the new_event_group_id" );
}
}
return void_result();
@ -108,16 +136,25 @@ void_result event_update_evaluator::do_apply(const event_update_operation& op)
eo.event_group_id = event_group_id;
if( op.new_status )
eo.dispatch_new_status(_db, *op.new_status);
if( op.extensions.value.new_manager )
eo.manager = *op.extensions.value.new_manager;
});
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
void_result event_update_status_evaluator::do_evaluate(const event_update_status_operation& op)
{ try {
FC_ASSERT(trx_state->_is_proposed_trx);
database& d = db();
FC_ASSERT(d.head_block_time() >= HARDFORK_1000_TIME);
if( d.head_block_time() < HARDFORK_MANAGER_TIME ) { // remove after HARDFORK_MANAGER_TIME
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), op.event_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
//check that the event to update exists
_event_to_update = &op.event_id(d);

View file

@ -24,18 +24,19 @@
#include <graphene/chain/event_group_evaluator.hpp>
#include <graphene/chain/event_group_object.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/chain/sport_object.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/manager.hpp>
namespace graphene { namespace chain {
void_result event_group_create_evaluator::do_evaluate(const event_group_create_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1000_TIME);
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
@ -49,6 +50,15 @@ void_result event_group_create_evaluator::do_evaluate(const event_group_create_o
FC_ASSERT( db().find_object(sport_id), "Invalid sport specified" );
if( db().head_block_time() < HARDFORK_MANAGER_TIME ) { // remove after HARDFORK_MANAGER_TIME
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.new_manager && !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), sport_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -58,6 +68,8 @@ object_id_type event_group_create_evaluator::do_apply(const event_group_create_o
db().create<event_group_object>( [&]( event_group_object& event_group_obj ) {
event_group_obj.name = op.name;
event_group_obj.sport_id = sport_id;
if( op.extensions.value.new_manager )
event_group_obj.manager = *op.extensions.value.new_manager;
});
return new_event_group.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -65,9 +77,18 @@ object_id_type event_group_create_evaluator::do_apply(const event_group_create_o
void_result event_group_update_evaluator::do_evaluate(const event_group_update_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1000_TIME);
FC_ASSERT(trx_state->_is_proposed_trx);
FC_ASSERT(op.new_sport_id.valid() || op.new_name.valid(), "nothing to change");
if( op.new_sport_id.valid() )
if( db().head_block_time() < HARDFORK_MANAGER_TIME ) { // remove after HARDFORK_MANAGER_TIME
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.new_manager && !op.extensions.value.fee_paying_account );
FC_ASSERT( op.new_sport_id || op.new_name, "nothing to change" );
}
else {
FC_ASSERT( is_manager( db(), op.event_group_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
FC_ASSERT( op.new_sport_id || op.new_name || op.extensions.value.new_manager, "nothing to change" );
}
if( op.new_sport_id )
{
object_id_type resolved_id = *op.new_sport_id;
if (is_relative(*op.new_sport_id))
@ -78,6 +99,12 @@ void_result event_group_update_evaluator::do_evaluate(const event_group_update_o
sport_id = resolved_id;
FC_ASSERT( db().find_object(sport_id), "invalid sport specified" );
if( db().head_block_time() >= HARDFORK_MANAGER_TIME )
{
FC_ASSERT( is_manager( db(), sport_id, op.fee_payer() ),
"no manager permission for the new_sport_id" );
}
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -93,6 +120,8 @@ void_result event_group_update_evaluator::do_apply(const event_group_update_oper
ego.name = *op.new_name;
if( op.new_sport_id.valid() )
ego.sport_id = sport_id;
if( op.extensions.value.new_manager )
ego.manager = *op.extensions.value.new_manager;
});
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -101,8 +130,15 @@ void_result event_group_update_evaluator::do_apply(const event_group_update_oper
void_result event_group_delete_evaluator::do_evaluate(const event_group_delete_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1001_TIME);
FC_ASSERT(trx_state->_is_proposed_trx);
if( db().head_block_time() < HARDFORK_MANAGER_TIME ) { // remove after HARDFORK_MANAGER_TIME
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), op.event_group_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
//check for event group existence
_event_group = &op.event_group_id(db());

View file

@ -370,6 +370,7 @@ namespace graphene { namespace chain {
at_least_one_betting_market_group_settled(false),
my(new impl(this))
{
manager = account_id_type(1);
}
event_object::event_object(const event_object& rhs) :
@ -380,6 +381,7 @@ namespace graphene { namespace chain {
event_group_id(rhs.event_group_id),
at_least_one_betting_market_group_settled(rhs.at_least_one_betting_market_group_settled),
scores(rhs.scores),
manager(rhs.manager),
my(new impl(this))
{
my->state_machine = rhs.my->state_machine;
@ -396,6 +398,7 @@ namespace graphene { namespace chain {
event_group_id = rhs.event_group_id;
at_least_one_betting_market_group_settled = rhs.at_least_one_betting_market_group_settled;
scores = rhs.scores;
manager = rhs.manager;
my->state_machine = rhs.my->state_machine;
my->state_machine.event_obj = this;

View file

@ -0,0 +1,4 @@
// added manager
#ifndef HARDFORK_MANAGER_TIME
#define HARDFORK_MANAGER_TIME (fc::time_point_sec( 1858752402 ))
#endif

View file

@ -41,7 +41,8 @@ class event_group_object : public graphene::db::abstract_object< event_group_obj
internationalized_string_type name;
sport_id_type sport_id;
account_id_type manager = account_id_type(1);
void cancel_events(database& db) const;
};
@ -55,4 +56,4 @@ typedef multi_index_container<
typedef generic_index<event_group_object, event_group_object_multi_index_type> event_group_object_index;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::event_group_object, (graphene::db::object), (name)(sport_id) )
FC_REFLECT_DERIVED( graphene::chain::event_group_object, (graphene::db::object), (name)(sport_id)(manager) )

View file

@ -60,6 +60,8 @@ class event_object : public graphene::db::abstract_object< event_object >
event_group_id_type event_group_id;
account_id_type manager = account_id_type(1);
bool at_least_one_betting_market_group_settled;
event_status get_status() const;
@ -151,5 +153,5 @@ typedef generic_index<event_object, event_object_multi_index_type> event_object_
return s;
}
} } // graphene::chain
FC_REFLECT(graphene::chain::event_object, (name))
FC_REFLECT(graphene::chain::event_object, (name) (manager) )

View file

@ -0,0 +1,25 @@
#pragma once
#include <graphene/chain/database.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace chain {
/**
* Determine whether the fee_paying_account for certain operations, in the context of
* sport_obj, event_group_obj, event_obj, betting_market_group_obj and betting_market_obj
* is the manager of this, or of the objects hierarchically above.
*/
bool is_manager( const database& db, const sport_id_type& sport_id, const account_id_type& manager_id );
bool is_manager( const database& db, const event_group_id_type& event_group_id, const account_id_type& manager_id );
bool is_manager( const database& db, const event_id_type& event_id, const account_id_type& manager_id );
bool is_manager( const database& db, const betting_market_group_id_type& betting_market_group_id_type,
const account_id_type& manager_id );
bool is_manager( const database& db, const betting_market_id_type& betting_market_id_type,
const account_id_type& manager_id );
} } // graphene::chain

View file

@ -25,6 +25,7 @@
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/ext.hpp>
namespace graphene { namespace chain {
@ -100,6 +101,11 @@ enum class betting_market_group_status
struct betting_market_group_create_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -140,14 +146,19 @@ struct betting_market_group_create_operation : public base_operation
*/
uint32_t delay_before_settling;
extensions_type extensions;
extension<ext> extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const { return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
};
struct betting_market_group_update_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -159,14 +170,19 @@ struct betting_market_group_update_operation : public base_operation
optional<betting_market_group_status> status;
extensions_type extensions;
extension<ext> extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const { return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
};
struct betting_market_create_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -180,14 +196,19 @@ struct betting_market_create_operation : public base_operation
internationalized_string_type payout_condition;
extensions_type extensions;
extension<ext> extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const { return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
};
struct betting_market_update_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -199,9 +220,9 @@ struct betting_market_update_operation : public base_operation
optional<internationalized_string_type> new_payout_condition;
extensions_type extensions;
extension<ext> extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const { return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
};
@ -214,6 +235,11 @@ enum class betting_market_resolution_type {
struct betting_market_group_resolve_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -221,9 +247,9 @@ struct betting_market_group_resolve_operation : public base_operation
std::map<betting_market_id_type, betting_market_resolution_type> resolutions;
extensions_type extensions;
extension<ext> extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const { return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
};
@ -262,14 +288,19 @@ struct betting_market_group_resolved_operation : public base_operation
struct betting_market_group_cancel_unmatched_bets_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
betting_market_group_id_type betting_market_group_id;
extensions_type extensions;
extension<ext> extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const { return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
};
@ -448,24 +479,29 @@ FC_REFLECT( graphene::chain::betting_market_group_create_operation,
(fee)(description)(event_id)(rules_id)(asset_id)
(never_in_play)(delay_before_settling)
(extensions) )
FC_REFLECT( graphene::chain::betting_market_group_create_operation::ext, (fee_paying_account) );
FC_REFLECT( graphene::chain::betting_market_group_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::betting_market_group_update_operation,
(fee)(betting_market_group_id)(new_description)(new_rules_id)(status)(extensions) )
FC_REFLECT( graphene::chain::betting_market_group_update_operation::ext, (fee_paying_account) );
FC_REFLECT( graphene::chain::betting_market_create_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::betting_market_create_operation,
(fee)(group_id)(description)(payout_condition)(extensions) )
FC_REFLECT( graphene::chain::betting_market_create_operation::ext, (fee_paying_account) );
FC_REFLECT( graphene::chain::betting_market_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::betting_market_update_operation,
(fee)(betting_market_id)(new_group_id)(new_description)(new_payout_condition)(extensions) )
FC_REFLECT( graphene::chain::betting_market_update_operation::ext, (fee_paying_account) );
FC_REFLECT_ENUM( graphene::chain::betting_market_resolution_type, (win)(not_win)(cancel)(BETTING_MARKET_RESOLUTION_COUNT) )
FC_REFLECT( graphene::chain::betting_market_group_resolve_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::betting_market_group_resolve_operation,
(fee)(betting_market_group_id)(resolutions)(extensions) )
FC_REFLECT( graphene::chain::betting_market_group_resolve_operation::ext, (fee_paying_account) );
FC_REFLECT( graphene::chain::betting_market_group_resolved_operation::fee_parameters_type, )
FC_REFLECT( graphene::chain::betting_market_group_resolved_operation,
@ -474,6 +510,7 @@ FC_REFLECT( graphene::chain::betting_market_group_resolved_operation,
FC_REFLECT( graphene::chain::betting_market_group_cancel_unmatched_bets_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::betting_market_group_cancel_unmatched_bets_operation,
(fee)(betting_market_group_id)(extensions) )
FC_REFLECT( graphene::chain::betting_market_group_cancel_unmatched_bets_operation::ext, (fee_paying_account) );
FC_REFLECT_ENUM( graphene::chain::bet_type, (back)(lay) )
FC_REFLECT( graphene::chain::bet_place_operation::fee_parameters_type, (fee) )

View file

@ -25,11 +25,18 @@
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/ext.hpp>
namespace graphene { namespace chain {
struct event_create_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account; // manager of sport || event_group
optional< account_id_type > new_manager; // new manager to set
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -48,9 +55,11 @@ struct event_create_operation : public base_operation
*/
object_id_type event_group_id;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const {
return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT;
}
void validate()const;
};
@ -76,6 +85,12 @@ enum class event_status
struct event_update_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account; // manager of sport || event_group || event
optional< account_id_type > new_manager; // new manager to set
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -91,9 +106,11 @@ struct event_update_operation : public base_operation
optional<event_status> new_status;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const {
return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT;
}
void validate()const;
};
@ -107,6 +124,11 @@ struct event_update_operation : public base_operation
*/
struct event_update_status_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account; // manager of sport || event_group || event
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -124,24 +146,29 @@ struct event_update_status_operation : public base_operation
*/
vector<string> scores;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const {
return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT;
}
void validate()const;
};
} }
FC_REFLECT( graphene::chain::event_create_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::event_create_operation::ext, (fee_paying_account)(new_manager) )
FC_REFLECT( graphene::chain::event_create_operation,
(fee)(name)(season)(start_time)(event_group_id)(extensions) )
FC_REFLECT( graphene::chain::event_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::event_update_operation::ext, (fee_paying_account)(new_manager) )
FC_REFLECT( graphene::chain::event_update_operation,
(fee)(event_id)(new_event_group_id)(new_name)(new_season)(new_start_time)(new_status)(extensions) )
FC_REFLECT_ENUM( graphene::chain::event_status, (upcoming)(in_progress)(frozen)(finished)(canceled)(settled)(STATUS_COUNT) )
FC_REFLECT( graphene::chain::event_update_status_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::event_update_status_operation::ext, (fee_paying_account) )
FC_REFLECT( graphene::chain::event_update_status_operation,
(fee)(event_id)(status)(scores)(extensions) )

View file

@ -25,11 +25,18 @@
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/ext.hpp>
namespace graphene { namespace chain {
struct event_group_create_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account; // manager of sport
optional< account_id_type > new_manager; // the new_manager for this object
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -44,14 +51,22 @@ struct event_group_create_operation : public base_operation
*/
object_id_type sport_id;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const {
return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT;
}
void validate()const;
};
struct event_group_update_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account; // manager of sport || event_group
optional< account_id_type > new_manager;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -65,35 +80,47 @@ struct event_group_update_operation : public base_operation
optional<internationalized_string_type> new_name;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const {
return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT;
}
void validate()const;
};
struct event_group_delete_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account; // manager of sport || event_group
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
event_group_id_type event_group_id;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const {
return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT;
}
void validate()const;
};
} }
FC_REFLECT( graphene::chain::event_group_create_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::event_group_create_operation::ext, (new_manager) (fee_paying_account) )
FC_REFLECT( graphene::chain::event_group_create_operation,
(fee)(name)(sport_id)(extensions) )
FC_REFLECT( graphene::chain::event_group_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::event_group_update_operation::ext, (new_manager) (fee_paying_account) )
FC_REFLECT( graphene::chain::event_group_update_operation,
(fee)(new_sport_id)(new_name)(event_group_id)(extensions) )
FC_REFLECT( graphene::chain::event_group_delete_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::event_group_delete_operation::ext, (fee_paying_account) )
FC_REFLECT( graphene::chain::event_group_delete_operation,
(fee)(event_group_id)(extensions) )

View file

@ -25,11 +25,17 @@
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/ext.hpp>
namespace graphene { namespace chain {
struct sport_create_operation : public base_operation
{
struct ext
{
optional< account_id_type > manager;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -38,7 +44,7 @@ struct sport_create_operation : public base_operation
*/
internationalized_string_type name;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
void validate()const;
@ -46,6 +52,12 @@ struct sport_create_operation : public base_operation
struct sport_update_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account; // manager of sport
optional< account_id_type > new_manager;
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
@ -53,35 +65,47 @@ struct sport_update_operation : public base_operation
optional<internationalized_string_type> new_name;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const {
return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT;
}
void validate()const;
};
struct sport_delete_operation : public base_operation
{
struct ext
{
optional< account_id_type > fee_paying_account; // manager of sport
};
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
sport_id_type sport_id;
extensions_type extensions;
extension< ext > extensions;
account_id_type fee_payer()const { return GRAPHENE_WITNESS_ACCOUNT; }
account_id_type fee_payer()const {
return extensions.value.fee_paying_account ? *extensions.value.fee_paying_account : GRAPHENE_WITNESS_ACCOUNT;
}
void validate()const;
};
} }
FC_REFLECT( graphene::chain::sport_create_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::sport_create_operation::ext, (manager) )
FC_REFLECT( graphene::chain::sport_create_operation,
(fee)(name)(extensions) )
FC_REFLECT( graphene::chain::sport_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::sport_update_operation::ext, (new_manager) (fee_paying_account) )
FC_REFLECT( graphene::chain::sport_update_operation,
(fee)(sport_id)(new_name)(extensions) )
FC_REFLECT( graphene::chain::sport_delete_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::sport_delete_operation::ext, (fee_paying_account) )
FC_REFLECT( graphene::chain::sport_delete_operation,
(fee)(sport_id)(extensions) )

View file

@ -38,6 +38,10 @@ class sport_object : public graphene::db::abstract_object< sport_object >
static const uint8_t type_id = sport_object_type;
internationalized_string_type name;
/// manager account can modify the sportobject without the permission
/// of the witness_account, also he can modify all objects beneath (event_group etc.)
account_id_type manager = account_id_type(1);
};
typedef multi_index_container<
@ -48,4 +52,4 @@ typedef multi_index_container<
typedef generic_index<sport_object, sport_object_multi_index_type> sport_object_index;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::sport_object, (graphene::db::object), (name) )
FC_REFLECT_DERIVED( graphene::chain::sport_object, (graphene::db::object), (name) (manager) )

View file

@ -0,0 +1,44 @@
#include <graphene/chain/manager.hpp>
#include <graphene/chain/sport_object.hpp>
#include <graphene/chain/event_group_object.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
namespace graphene { namespace chain {
bool is_manager( const database& db, const sport_id_type& sport_id, const account_id_type& manager_id )
{
return sport_id(db).manager == manager_id || GRAPHENE_WITNESS_ACCOUNT == manager_id;
}
bool is_manager( const database& db, const event_group_id_type& event_group_id, const account_id_type& manager_id )
{
const event_group_object& event_group_obj = event_group_id(db);
if( event_group_obj.manager == manager_id || GRAPHENE_WITNESS_ACCOUNT == manager_id )
return true;
return is_manager( db, event_group_obj.sport_id, manager_id );
}
bool is_manager( const database& db, const event_id_type& event_id, const account_id_type& manager_id )
{
const event_object& event_obj = event_id(db);
if( event_obj.manager == manager_id || GRAPHENE_WITNESS_ACCOUNT == manager_id )
return true;
return is_manager( db, event_obj.event_group_id, manager_id );
}
bool is_manager( const database& db, const betting_market_group_id_type& betting_market_group_id,
const account_id_type& manager_id )
{
return GRAPHENE_WITNESS_ACCOUNT == manager_id || is_manager( db, betting_market_group_id(db).event_id, manager_id );
}
bool is_manager( const database& db, const betting_market_id_type& betting_market_id,
const account_id_type& manager_id )
{
return GRAPHENE_WITNESS_ACCOUNT == manager_id || is_manager( db, betting_market_id(db).group_id, manager_id );
}
} } // graphene::chain

View file

@ -29,13 +29,16 @@
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/manager.hpp>
namespace graphene { namespace chain {
void_result sport_create_evaluator::do_evaluate(const sport_create_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1000_TIME);
FC_ASSERT(trx_state->_is_proposed_trx);
FC_ASSERT( trx_state->_is_proposed_trx );
if( db().head_block_time() <= HARDFORK_MANAGER_TIME )
FC_ASSERT( !op.extensions.value.manager );
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -45,6 +48,8 @@ object_id_type sport_create_evaluator::do_apply(const sport_create_operation& op
const sport_object& new_sport =
db().create<sport_object>( [&]( sport_object& sport_obj ) {
sport_obj.name = op.name;
if( op.extensions.value.manager )
sport_obj.manager = *op.extensions.value.manager;
});
return new_sport.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -53,8 +58,18 @@ object_id_type sport_create_evaluator::do_apply(const sport_create_operation& op
void_result sport_update_evaluator::do_evaluate(const sport_update_operation& op)
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1000_TIME);
FC_ASSERT(trx_state->_is_proposed_trx);
FC_ASSERT(op.new_name.valid());
if( db().head_block_time() < HARDFORK_MANAGER_TIME ) { // remove after HARDFORK_MANAGER_TIME
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( op.new_name, "nothing to change");
FC_ASSERT( !op.extensions.value.new_manager && !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), op.sport_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
FC_ASSERT( op.new_name || op.extensions.value.new_manager, "nothing to change" );
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -67,6 +82,8 @@ void_result sport_update_evaluator::do_apply(const sport_update_operation& op)
{
if( op.new_name.valid() )
spo.name = *op.new_name;
if( op.extensions.value.new_manager )
spo.manager = *op.extensions.value.new_manager;
});
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
@ -75,7 +92,14 @@ void_result sport_update_evaluator::do_apply(const sport_update_operation& op)
void_result sport_delete_evaluator::do_evaluate( const sport_delete_operation& op )
{ try {
FC_ASSERT(db().head_block_time() >= HARDFORK_1001_TIME);
FC_ASSERT(trx_state->_is_proposed_trx);
if( db().head_block_time() < HARDFORK_MANAGER_TIME ) { // remove after HARDFORK_MANAGER_TIME
FC_ASSERT( trx_state->_is_proposed_trx );
FC_ASSERT( !op.extensions.value.fee_paying_account );
}
else {
FC_ASSERT( is_manager( db(), op.sport_id, op.fee_payer() ),
"fee_payer is not the manager of this object" );
}
//check for sport existence
_sport = &op.sport_id(db());

File diff suppressed because it is too large Load diff