Implemented top rewards

This commit is contained in:
Peter Conrad 2018-04-22 11:45:19 +02:00 committed by Fabian Schuh
parent ade7cf2d87
commit 8903a5a3af
No known key found for this signature in database
GPG key ID: F2538A4B282D6238
4 changed files with 257 additions and 15 deletions

View file

@ -37,7 +37,6 @@
#include <graphene/utilities/key_conversion.hpp>
#include <graphene/affiliate_stats/affiliate_stats_api.hpp>
#include <graphene/affiliate_stats/affiliate_stats_plugin.hpp>
namespace graphene { namespace affiliate_stats {
@ -48,6 +47,28 @@ class affiliate_stats_api_impl
public:
affiliate_stats_api_impl(graphene::app::application& _app);
std::vector<top_referred_account> list_top_referred_accounts( asset_id_type asset, uint16_t limit )const
{
std::vector<top_referred_account> result;
result.reserve( limit );
auto& idx = app.chain_database()->get_index_type<referral_reward_index>().indices().get<by_asset>();
auto itr = idx.find( asset );
while( itr != idx.end() && itr->get_asset_id() == asset && limit-- > 0 )
result.push_back( *itr );
return result;
}
std::vector<top_app> list_top_rewards_per_app( asset_id_type asset, uint16_t limit )const
{
std::vector<top_app> result;
result.reserve( limit );
auto& idx = app.chain_database()->get_index_type<app_reward_index>().indices().get<by_asset>();
auto itr = idx.find( asset );
while( itr != idx.end() && itr->get_asset_id() == asset && limit-- > 0 )
result.push_back( *itr );
return result;
}
graphene::app::application& app;
};
@ -56,9 +77,36 @@ affiliate_stats_api_impl::affiliate_stats_api_impl(graphene::app::application& _
} // detail
top_referred_account::top_referred_account() {}
top_referred_account::top_referred_account( const referral_reward_object& rro )
: referral( rro.referral ), total_payout( rro.total_payout ) {}
top_app::top_app() {}
top_app::top_app( const app_reward_object& aro )
: app( aro.app ), total_payout( aro.total_payout ) {}
affiliate_stats_api::affiliate_stats_api(graphene::app::application& app)
: my(std::make_shared<detail::affiliate_stats_api_impl>(app)) {}
std::vector<top_referred_account> affiliate_stats_api::list_top_referred_accounts( asset_id_type asset, uint16_t limit )const
{
FC_ASSERT( limit <= 100 );
return my->list_top_referred_accounts( asset, limit );
}
std::vector<top_app> affiliate_stats_api::list_top_rewards_per_app( asset_id_type asset, uint16_t limit )const
{
FC_ASSERT( limit <= 100 );
return my->list_top_rewards_per_app( asset, limit );
}
std::vector<referral_payment> affiliate_stats_api::list_historic_referral_rewards( account_id_type affiliate )const
{
FC_ASSERT( false, "Not implemented!" );
}
} } // graphene::affiliate_stats

View file

@ -23,6 +23,7 @@
*/
#include <graphene/affiliate_stats/affiliate_stats_plugin.hpp>
#include <graphene/affiliate_stats/affiliate_stats_objects.hpp>
#include <graphene/app/impacted.hpp>
@ -45,11 +46,9 @@ class affiliate_stats_plugin_impl
{
public:
affiliate_stats_plugin_impl(affiliate_stats_plugin& _plugin)
: _self( _plugin )
{ }
: _self( _plugin ) { }
virtual ~affiliate_stats_plugin_impl();
/** this method is called as a callback after a block is applied
* and will process/index all operations that were applied in the block.
*/
@ -60,23 +59,67 @@ class affiliate_stats_plugin_impl
return _self.database();
}
typedef void result_type;
template<typename Operation>
void operator()( const Operation& op ) {}
affiliate_stats_plugin& _self;
app_reward_index* _ar_index;
referral_reward_index* _rr_index;
private:
};
affiliate_stats_plugin_impl::~affiliate_stats_plugin_impl() {}
template<>
void affiliate_stats_plugin_impl::operator()( const affiliate_payout_operation& op )
{
auto& by_app = _ar_index->indices().get<by_app_asset>();
auto itr = by_app.find( boost::make_tuple( op.tag, op.payout.asset_id ) );
if( itr == by_app.end() )
{
database().create<app_reward_object>( [&op]( app_reward_object& aro ) {
aro.app = op.tag;
aro.total_payout = op.payout;
});
}
else
{
database().modify( *itr, [&op]( app_reward_object& aro ) {
aro.total_payout += op.payout;
});
}
}
template<>
void affiliate_stats_plugin_impl::operator()( const affiliate_referral_payout_operation& op )
{
auto& by_referral = _rr_index->indices().get<by_referral_asset>();
auto itr = by_referral.find( boost::make_tuple( op.player, op.payout.asset_id ) );
if( itr == by_referral.end() )
{
database().create<referral_reward_object>( [&op]( referral_reward_object& rro ) {
rro.referral = op.player;
rro.total_payout = op.payout;
});
}
else
{
database().modify( *itr, [&op]( referral_reward_object& rro ) {
rro.total_payout += op.payout;
});
}
}
void affiliate_stats_plugin_impl::update_affiliate_stats( const signed_block& b )
{
graphene::chain::database& db = database();
vector<optional< operation_history_object > >& hist = db.get_applied_operations();
vector<optional< operation_history_object > >& hist = database().get_applied_operations();
for( optional< operation_history_object >& o_op : hist )
{
if( !o_op.valid() )
continue;
const operation_history_object& op = *o_op;
o_op->op.visit( *this );
}
}
@ -107,9 +150,9 @@ void affiliate_stats_plugin::plugin_initialize(const boost::program_options::var
{
database().applied_block.connect( [this]( const signed_block& b){ my->update_affiliate_stats(b); } );
// FIXME
// my->_oho_index = database().add_index< primary_index< simple_index< operation_history_object > > >();
// database().add_index< primary_index< account_transaction_history_index > >();
my->_ar_index = database().add_index< primary_index< app_reward_index > >();
my->_rr_index = database().add_index< primary_index< referral_reward_index > >();
}
void affiliate_stats_plugin::plugin_startup() {}

View file

@ -31,6 +31,8 @@
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/affiliate_stats/affiliate_stats_objects.hpp>
using namespace graphene::chain;
namespace graphene { namespace app {
@ -43,19 +45,51 @@ namespace detail {
class affiliate_stats_api_impl;
}
class referral_payment {
public:
};
class top_referred_account {
public:
top_referred_account();
top_referred_account( const referral_reward_object& rro );
account_id_type referral;
asset total_payout;
};
class top_app {
public:
top_app();
top_app( const app_reward_object& rro );
app_tag app;
asset total_payout;
};
class affiliate_stats_api
{
public:
affiliate_stats_api(graphene::app::application& app);
std::vector<referral_payment> list_historic_referral_rewards( account_id_type affiliate )const;
// get_pending_referral_reward() - not implemented because we have continuous payouts
// get_previous_referral_reward() - not implemented because we have continuous payouts
std::vector<top_referred_account> list_top_referred_accounts( asset_id_type asset, uint16_t limit = 100 )const;
std::vector<top_app> list_top_rewards_per_app( asset_id_type asset, uint16_t limit = 100 )const;
std::shared_ptr<detail::affiliate_stats_api_impl> my;
};
} } // graphene::affiliate_stats
/*
FC_REFLECT(graphene::bookie::order_bin, (amount_to_bet)(backer_multiplier))
FC_REFLECT(graphene::bookie::binned_order_book, (aggregated_back_bets)(aggregated_lay_bets))
FC_REFLECT(graphene::bookie::matched_bet_object, (id)(bettor_id)(betting_market_id)(amount_to_bet)(backer_multiplier)(back_or_lay)(end_of_delay)(amount_matched)(associated_operations))
*/
FC_REFLECT(graphene::affiliate_stats::referral_payment, )
FC_REFLECT(graphene::affiliate_stats::top_referred_account, (referral)(total_payout) )
FC_REFLECT(graphene::affiliate_stats::top_app, (app)(total_payout) )
FC_API(graphene::affiliate_stats::affiliate_stats_api,
(list_historic_referral_rewards)
(list_top_referred_accounts)
(list_top_rewards_per_app)
)

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2018 Peerplays Blockchain Standards Association, and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/database.hpp>
#include <graphene/affiliate_stats/affiliate_stats_plugin.hpp>
namespace graphene { namespace affiliate_stats {
using namespace chain;
enum stats_object_type
{
app_reward_object_type,
referral_reward_object_type,
STATS_OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
};
class app_reward_object : public graphene::db::abstract_object<app_reward_object>
{
public:
static const uint8_t space_id = AFFILIATE_STATS_SPACE_ID;
static const uint8_t type_id = app_reward_object_type;
app_tag app;
asset total_payout;
inline share_type get_amount()const { return total_payout.amount; }
inline asset_id_type get_asset_id()const { return total_payout.asset_id; }
};
typedef object_id<AFFILIATE_STATS_SPACE_ID, app_reward_object_type, app_reward_object> app_reward_id_type;
struct by_asset;
struct by_app_asset;
typedef multi_index_container<
app_reward_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_non_unique<tag<by_asset>,
composite_key<
app_reward_object,
const_mem_fun<app_reward_object, asset_id_type, &app_reward_object::get_asset_id>,
const_mem_fun<app_reward_object, share_type, &app_reward_object::get_amount> >,
composite_key_compare<
std::less<asset_id_type>,
std::greater<share_type> >
>,
ordered_unique<tag<by_app_asset>,
composite_key<
app_reward_object,
member<app_reward_object, app_tag, &app_reward_object::app>,
const_mem_fun<app_reward_object, asset_id_type, &app_reward_object::get_asset_id> >
> > > app_reward_multi_index_type;
typedef generic_index<app_reward_object, app_reward_multi_index_type> app_reward_index;
class referral_reward_object : public graphene::db::abstract_object<referral_reward_object>
{
public:
static const uint8_t space_id = AFFILIATE_STATS_SPACE_ID;
static const uint8_t type_id = referral_reward_object_type;
account_id_type referral;
asset total_payout;
inline share_type get_amount()const { return total_payout.amount; }
inline asset_id_type get_asset_id()const { return total_payout.asset_id; }
};
typedef object_id<AFFILIATE_STATS_SPACE_ID, referral_reward_object_type, referral_reward_object> referral_reward_id_type;
struct by_referral_asset;
typedef multi_index_container<
referral_reward_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id> >,
ordered_non_unique<tag<by_asset>,
composite_key<
referral_reward_object,
const_mem_fun<referral_reward_object, asset_id_type, &referral_reward_object::get_asset_id>,
const_mem_fun<referral_reward_object, share_type, &referral_reward_object::get_amount> >,
composite_key_compare<
std::less<asset_id_type>,
std::greater<share_type> >
>,
ordered_unique<tag<by_referral_asset>,
composite_key<
referral_reward_object,
member<referral_reward_object, account_id_type, &referral_reward_object::referral>,
const_mem_fun<referral_reward_object, asset_id_type, &referral_reward_object::get_asset_id> >
> > > referral_reward_multi_index_type;
typedef generic_index<referral_reward_object, referral_reward_multi_index_type> referral_reward_index;
} } //graphene::affiliate_stats
FC_REFLECT_DERIVED( graphene::affiliate_stats::app_reward_object, (graphene::db::object), (app)(total_payout) )
FC_REFLECT_DERIVED( graphene::affiliate_stats::referral_reward_object, (graphene::db::object), (referral)(total_payout) )