Skip to content

Commit

Permalink
implement payment splitter proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
bytemaster committed Jul 18, 2015
1 parent e4c29cb commit c6b848e
Show file tree
Hide file tree
Showing 6 changed files with 399 additions and 2 deletions.
7 changes: 7 additions & 0 deletions libraries/chain/db_init.cpp
Expand Up @@ -44,6 +44,7 @@
#include <graphene/chain/witness_evaluator.hpp>
#include <graphene/chain/worker_evaluator.hpp>
#include <graphene/chain/balance_evaluator.hpp>
#include <graphene/chain/splitter_evaluator.hpp>

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

Expand Down Expand Up @@ -150,6 +151,11 @@ void database::initialize_evaluators()
register_evaluator<withdraw_permission_delete_evaluator>();
register_evaluator<worker_create_evaluator>();
register_evaluator<balance_claim_evaluator>();
register_evaluator<splitter_create_evaluator>();
register_evaluator<splitter_update_evaluator>();
register_evaluator<splitter_pay_evaluator>();
register_evaluator<splitter_payout_evaluator>();
register_evaluator<splitter_delete_evaluator>();
}

void database::initialize_indexes()
Expand Down Expand Up @@ -177,6 +183,7 @@ void database::initialize_indexes()
add_index< primary_index<vesting_balance_index> >();
add_index< primary_index<worker_index> >();
add_index< primary_index<balance_index> >();
add_index< primary_index<splitter_index> >();

//Implementation object indexes
add_index< primary_index<transaction_index > >();
Expand Down
Expand Up @@ -14,6 +14,7 @@
#include <graphene/chain/protocol/withdraw_permission.hpp>
#include <graphene/chain/protocol/witness.hpp>
#include <graphene/chain/protocol/worker.hpp>
#include <graphene/chain/protocol/splitter.hpp>

namespace graphene { namespace chain {

Expand Down Expand Up @@ -59,7 +60,12 @@ namespace graphene { namespace chain {
custom_operation,
assert_operation,
balance_claim_operation,
override_transfer_operation
override_transfer_operation,
splitter_create_operation,
splitter_update_operation,
splitter_pay_operation,
splitter_payout_operation,
splitter_delete_operation
> operation;

/// @} // operations group
Expand Down
147 changes: 147 additions & 0 deletions libraries/chain/include/graphene/chain/protocol/splitter.hpp
@@ -0,0 +1,147 @@
/* Copyright (c) 2015, Cryptonomex, Inc. */
#pragma once
#include <graphene/chain/protocol/base.hpp>

namespace graphene { namespace chain {

struct market_buyback
{
asset_id_type asset_to_buy;
price limit_price;
void validate()const {
limit_price.validate();
FC_ASSERT( limit_price.quote.asset_id == asset_to_buy );
}
};

typedef static_variant<account_id_type,market_buyback> payment_target_type;

struct payment_target
{
uint16_t weight = 0;
payment_target_type target;
};

struct payment_target_validate
{
typedef void result_type;
void operator()( const account_id_type& id )const { }
void operator()( const market_buyback& t )const
{
FC_ASSERT( t.asset_to_buy == t.limit_price.quote.asset_id );
t.limit_price.validate();
}
};

struct splitter_create_operation : public base_operation
{
/// TODO: charge fee based upon size
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };

asset fee;
account_id_type payer;
account_id_type owner;
vector<payment_target> targets;
asset min_payment;
share_type max_payment; ///< same asset_id as min_payment
share_type payout_threshold; ///< same asset_id as min_payment

void validate()const
{
FC_ASSERT( fee.amount >= 0 );
FC_ASSERT( min_payment.amount > 0 );
FC_ASSERT( min_payment.amount <= max_payment );
FC_ASSERT( payout_threshold >= 0 );
for( const auto& t : targets )
{
FC_ASSERT( t.weight > 0 );
t.target.visit( payment_target_validate() );
}
}
account_id_type fee_payer()const { return payer; }
};

struct splitter_update_operation : public base_operation
{
/// TODO: charge fee based upon size
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };

asset fee;
splitter_id_type splitter_id;
account_id_type owner; ///< must match splitter_id->owner
account_id_type new_owner;
vector<payment_target> targets;
asset min_payment;
share_type max_payment; ///< same asset_id as min_payment
share_type payout_threshold; ///< same asset_id as min_payment

void validate()const
{
FC_ASSERT( fee.amount >= 0 );
FC_ASSERT( min_payment.amount > 0 );
FC_ASSERT( min_payment.amount <= max_payment );
FC_ASSERT( payout_threshold >= 0 );
for( const auto& t : targets ) FC_ASSERT( t.weight > 0 );
}

account_id_type fee_payer()const { return owner; }
};

struct splitter_pay_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };

asset fee;
splitter_id_type splitter_id;
account_id_type paying_account; ///< also fee payer
asset payment;

void validate()const
{
FC_ASSERT( payment.amount > 0 );
FC_ASSERT( fee.amount >= 0 );
}

account_id_type fee_payer()const { return paying_account; }
};

struct splitter_payout_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };

asset fee;
splitter_id_type splitter_id;
account_id_type owner; ///< must match splitter_id->owner

void validate()const { FC_ASSERT( fee.amount >= 0 ); }
account_id_type fee_payer()const { return owner; }
};


struct splitter_delete_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };

asset fee;
splitter_id_type splitter_id;
account_id_type owner; ///< must match splitter_id->owner

void validate()const { FC_ASSERT( fee.amount >= 0 ); }
account_id_type fee_payer()const { return owner; }
};

} }

FC_REFLECT( graphene::chain::market_buyback, (asset_to_buy)(limit_price) )
FC_REFLECT( graphene::chain::payment_target, (weight)(target) )
FC_REFLECT( graphene::chain::splitter_create_operation, (fee)(payer)(owner)(targets)(min_payment)(max_payment)(payout_threshold) )
FC_REFLECT( graphene::chain::splitter_update_operation, (fee)(owner)(new_owner)(targets)(min_payment)(max_payment)(payout_threshold) )
FC_REFLECT( graphene::chain::splitter_pay_operation, (fee)(splitter_id)(paying_account)(payment) )
FC_REFLECT( graphene::chain::splitter_payout_operation, (fee)(splitter_id)(owner) )
FC_REFLECT( graphene::chain::splitter_delete_operation, (fee)(splitter_id)(owner) )
FC_REFLECT( graphene::chain::splitter_create_operation::fee_parameters_type, (fee) );
FC_REFLECT( graphene::chain::splitter_update_operation::fee_parameters_type, (fee) );
FC_REFLECT( graphene::chain::splitter_pay_operation::fee_parameters_type, (fee) );
FC_REFLECT( graphene::chain::splitter_payout_operation::fee_parameters_type, (fee) );
FC_REFLECT( graphene::chain::splitter_delete_operation::fee_parameters_type, (fee) );

6 changes: 5 additions & 1 deletion libraries/chain/include/graphene/chain/protocol/types.hpp
Expand Up @@ -123,6 +123,7 @@ namespace graphene { namespace chain {
vesting_balance_object_type,
worker_object_type,
balance_object_type,
splitter_object_type,
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
};

Expand Down Expand Up @@ -169,11 +170,12 @@ namespace graphene { namespace chain {
class witness_schedule_object;
class worker_object;
class balance_object;
class splitter_object;

typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
typedef object_id< protocol_ids, force_settlement_object_type, force_settlement_object> force_settlement_id_type;
typedef object_id< protocol_ids, committee_member_object_type, committee_member_object> committee_member_id_type;
typedef object_id< protocol_ids, committee_member_object_type, committee_member_object> committee_member_id_type;
typedef object_id< protocol_ids, witness_object_type, witness_object> witness_id_type;
typedef object_id< protocol_ids, limit_order_object_type, limit_order_object> limit_order_id_type;
typedef object_id< protocol_ids, call_order_object_type, call_order_object> call_order_id_type;
Expand All @@ -184,6 +186,7 @@ namespace graphene { namespace chain {
typedef object_id< protocol_ids, vesting_balance_object_type, vesting_balance_object> vesting_balance_id_type;
typedef object_id< protocol_ids, worker_object_type, worker_object> worker_id_type;
typedef object_id< protocol_ids, balance_object_type, balance_object> balance_id_type;
typedef object_id< protocol_ids, splitter_object_type, splitter_object> splitter_id_type;

// implementation types
class global_property_object;
Expand Down Expand Up @@ -376,6 +379,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
(vesting_balance_object_type)
(worker_object_type)
(balance_object_type)
(splitter_object_type)
(OBJECT_TYPE_COUNT)
)
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
Expand Down

0 comments on commit c6b848e

Please sign in to comment.