ppy marketplace 2 - batch sale, offer_object escrow
This commit is contained in:
parent
3b4350b1c7
commit
5093b94128
8 changed files with 401 additions and 386 deletions
|
|
@ -720,7 +720,7 @@ void database::finalize_expired_offers(){
|
||||||
++itr;
|
++itr;
|
||||||
|
|
||||||
finalize_offer_operation finalize;
|
finalize_offer_operation finalize;
|
||||||
finalize.fee_paying_account = offer.transfer_agent_id;
|
finalize.fee_paying_account = offer.issuer;
|
||||||
finalize.offer_id = offer.id;
|
finalize.offer_id = offer.id;
|
||||||
finalize.fee = current_fee_schedule().calculate_fee( finalize );
|
finalize.fee = current_fee_schedule().calculate_fee( finalize );
|
||||||
finalize.result = offer.bidder ? result_type::Expired : result_type::ExpiredNoBid;
|
finalize.result = offer.bidder ? result_type::Expired : result_type::ExpiredNoBid;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@
|
||||||
#include <graphene/chain/evaluator.hpp>
|
#include <graphene/chain/evaluator.hpp>
|
||||||
#include <graphene/chain/database.hpp>
|
#include <graphene/chain/database.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene
|
||||||
|
{
|
||||||
|
namespace chain
|
||||||
|
{
|
||||||
|
|
||||||
class offer_evaluator : public evaluator<offer_evaluator>
|
class offer_evaluator : public evaluator<offer_evaluator>
|
||||||
{
|
{
|
||||||
|
|
@ -31,4 +34,5 @@ namespace graphene { namespace chain {
|
||||||
void_result do_apply(const finalize_offer_operation &op);
|
void_result do_apply(const finalize_offer_operation &op);
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
} // namespace chain
|
||||||
|
} // namespace graphene
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@
|
||||||
#include <graphene/chain/protocol/operations.hpp>
|
#include <graphene/chain/protocol/operations.hpp>
|
||||||
#include <graphene/db/generic_index.hpp>
|
#include <graphene/db/generic_index.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene
|
||||||
|
{
|
||||||
|
namespace chain
|
||||||
|
{
|
||||||
class database;
|
class database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -11,7 +14,9 @@ namespace graphene { namespace chain {
|
||||||
* @ingroup protocol
|
* @ingroup protocol
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct by_expiration_date{};
|
struct by_expiration_date
|
||||||
|
{
|
||||||
|
};
|
||||||
class offer_object : public graphene::db::abstract_object<offer_object>
|
class offer_object : public graphene::db::abstract_object<offer_object>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -20,8 +25,7 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
account_id_type issuer;
|
account_id_type issuer;
|
||||||
|
|
||||||
account_id_type transfer_agent_id;
|
set<uint32_t> item_ids;
|
||||||
uint32_t item_id;
|
|
||||||
optional<account_id_type> bidder;
|
optional<account_id_type> bidder;
|
||||||
optional<asset> bid_price;
|
optional<asset> bid_price;
|
||||||
asset minimum_price;
|
asset minimum_price;
|
||||||
|
|
@ -41,8 +45,7 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
account_id_type issuer;
|
account_id_type issuer;
|
||||||
|
|
||||||
account_id_type transfer_agent_id;
|
set<uint32_t> item_ids;
|
||||||
uint32_t item_id;
|
|
||||||
optional<account_id_type> bidder;
|
optional<account_id_type> bidder;
|
||||||
optional<asset> bid_price;
|
optional<asset> bid_price;
|
||||||
asset minimum_price;
|
asset minimum_price;
|
||||||
|
|
@ -54,8 +57,10 @@ namespace graphene { namespace chain {
|
||||||
offer_history_id_type get_id() const { return id; }
|
offer_history_id_type get_id() const { return id; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct compare_by_expiration_date {
|
struct compare_by_expiration_date
|
||||||
bool operator()( const fc::time_point_sec& o1, const fc::time_point_sec& o2 ) const {
|
{
|
||||||
|
bool operator()(const fc::time_point_sec &o1, const fc::time_point_sec &o2) const
|
||||||
|
{
|
||||||
return o1 > o2;
|
return o1 > o2;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -70,10 +75,8 @@ namespace graphene { namespace chain {
|
||||||
ordered_non_unique<
|
ordered_non_unique<
|
||||||
tag<by_expiration_date>,
|
tag<by_expiration_date>,
|
||||||
member<offer_object, fc::time_point_sec, &offer_object::offer_expiration_date>,
|
member<offer_object, fc::time_point_sec, &offer_object::offer_expiration_date>,
|
||||||
compare_by_expiration_date
|
compare_by_expiration_date>>>
|
||||||
>
|
offer_multi_index_type;
|
||||||
>
|
|
||||||
> offer_multi_index_type;
|
|
||||||
|
|
||||||
typedef multi_index_container<
|
typedef multi_index_container<
|
||||||
offer_history_object,
|
offer_history_object,
|
||||||
|
|
@ -82,10 +85,8 @@ namespace graphene { namespace chain {
|
||||||
ordered_non_unique<
|
ordered_non_unique<
|
||||||
tag<by_expiration_date>,
|
tag<by_expiration_date>,
|
||||||
member<offer_history_object, fc::time_point_sec, &offer_history_object::offer_expiration_date>,
|
member<offer_history_object, fc::time_point_sec, &offer_history_object::offer_expiration_date>,
|
||||||
compare_by_expiration_date
|
compare_by_expiration_date>>>
|
||||||
>
|
offer_history_multi_index_type;
|
||||||
>
|
|
||||||
> offer_history_multi_index_type;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup object_index
|
* @ingroup object_index
|
||||||
|
|
@ -94,24 +95,13 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
typedef generic_index<offer_history_object, offer_history_multi_index_type> offer_history_index;
|
typedef generic_index<offer_history_object, offer_history_multi_index_type> offer_history_index;
|
||||||
|
|
||||||
}}
|
} // namespace chain
|
||||||
|
} // namespace graphene
|
||||||
|
|
||||||
FC_REFLECT_DERIVED(graphene::chain::offer_object,
|
FC_REFLECT_DERIVED(graphene::chain::offer_object,
|
||||||
(graphene::db::object),
|
(graphene::db::object),
|
||||||
(issuer)
|
(issuer)(item_ids)(bidder)(bid_price)(minimum_price)(maximum_price)(buying_item)(offer_expiration_date))
|
||||||
(transfer_agent_id)(item_id)
|
|
||||||
(bidder)(bid_price)
|
|
||||||
(minimum_price)(maximum_price)
|
|
||||||
(buying_item)
|
|
||||||
(offer_expiration_date)
|
|
||||||
)
|
|
||||||
|
|
||||||
FC_REFLECT_DERIVED(graphene::chain::offer_history_object,
|
FC_REFLECT_DERIVED(graphene::chain::offer_history_object,
|
||||||
(graphene::db::object),
|
(graphene::db::object),
|
||||||
(issuer)
|
(issuer)(item_ids)(bidder)(bid_price)(minimum_price)(maximum_price)(buying_item)(offer_expiration_date))
|
||||||
(transfer_agent_id)(item_id)
|
|
||||||
(bidder)(bid_price)
|
|
||||||
(minimum_price)(maximum_price)
|
|
||||||
(buying_item)
|
|
||||||
(offer_expiration_date)
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@
|
||||||
#include <graphene/chain/protocol/base.hpp>
|
#include <graphene/chain/protocol/base.hpp>
|
||||||
#include <graphene/chain/protocol/memo.hpp>
|
#include <graphene/chain/protocol/memo.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene
|
||||||
|
{
|
||||||
|
namespace chain
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @class offer_operation
|
* @class offer_operation
|
||||||
|
|
@ -13,13 +16,13 @@ namespace graphene { namespace chain {
|
||||||
*/
|
*/
|
||||||
struct offer_operation : public base_operation
|
struct offer_operation : public base_operation
|
||||||
{
|
{
|
||||||
struct fee_parameters_type {
|
struct fee_parameters_type
|
||||||
|
{
|
||||||
uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION;
|
uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION;
|
||||||
uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos.
|
uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos.
|
||||||
};
|
};
|
||||||
|
|
||||||
account_id_type transfer_agent_id;
|
set<uint32_t> item_ids;
|
||||||
uint32_t item_id;
|
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * minimum_price.asset_id == maximum_price.asset_id.
|
// * minimum_price.asset_id == maximum_price.asset_id.
|
||||||
|
|
@ -45,14 +48,15 @@ namespace graphene { namespace chain {
|
||||||
optional<memo_data> memo;
|
optional<memo_data> memo;
|
||||||
extensions_type extensions;
|
extensions_type extensions;
|
||||||
|
|
||||||
account_id_type fee_payer()const { return transfer_agent_id; }
|
account_id_type fee_payer() const { return issuer; }
|
||||||
void validate() const;
|
void validate() const;
|
||||||
share_type calculate_fee(const fee_parameters_type &k) const;
|
share_type calculate_fee(const fee_parameters_type &k) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bid_operation : public base_operation
|
struct bid_operation : public base_operation
|
||||||
{
|
{
|
||||||
struct fee_parameters_type {
|
struct fee_parameters_type
|
||||||
|
{
|
||||||
uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION;
|
uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION;
|
||||||
uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos.
|
uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos.
|
||||||
};
|
};
|
||||||
|
|
@ -70,11 +74,16 @@ namespace graphene { namespace chain {
|
||||||
share_type calculate_fee(const fee_parameters_type &k) const;
|
share_type calculate_fee(const fee_parameters_type &k) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class result_type {Expired = 0, ExpiredNoBid = 1};
|
enum class result_type
|
||||||
|
{
|
||||||
|
Expired = 0,
|
||||||
|
ExpiredNoBid = 1
|
||||||
|
};
|
||||||
|
|
||||||
struct finalize_offer_operation : public base_operation
|
struct finalize_offer_operation : public base_operation
|
||||||
{
|
{
|
||||||
struct fee_parameters_type {
|
struct fee_parameters_type
|
||||||
|
{
|
||||||
uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION;
|
uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION;
|
||||||
uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos.
|
uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos.
|
||||||
};
|
};
|
||||||
|
|
@ -93,10 +102,11 @@ namespace graphene { namespace chain {
|
||||||
share_type calculate_fee(const fee_parameters_type &k) const;
|
share_type calculate_fee(const fee_parameters_type &k) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}} // graphene::chain
|
} // namespace chain
|
||||||
|
} // namespace graphene
|
||||||
|
|
||||||
FC_REFLECT(graphene::chain::offer_operation::fee_parameters_type, (fee)(price_per_kbyte));
|
FC_REFLECT(graphene::chain::offer_operation::fee_parameters_type, (fee)(price_per_kbyte));
|
||||||
FC_REFLECT( graphene::chain::offer_operation, (fee)(issuer)(memo)(minimum_price)(maximum_price)(buying_item)(transfer_agent_id)(item_id)(offer_expiration_date)(extensions) );
|
FC_REFLECT(graphene::chain::offer_operation, (fee)(issuer)(memo)(minimum_price)(maximum_price)(buying_item)(item_ids)(offer_expiration_date)(extensions));
|
||||||
|
|
||||||
FC_REFLECT(graphene::chain::bid_operation::fee_parameters_type, (fee)(price_per_kbyte));
|
FC_REFLECT(graphene::chain::bid_operation::fee_parameters_type, (fee)(price_per_kbyte));
|
||||||
FC_REFLECT(graphene::chain::bid_operation, (fee)(bidder)(bid_price)(offer_id)(extensions));
|
FC_REFLECT(graphene::chain::bid_operation, (fee)(bidder)(bid_price)(offer_id)(extensions));
|
||||||
|
|
|
||||||
|
|
@ -6,37 +6,43 @@
|
||||||
#include <graphene/chain/is_authorized_asset.hpp>
|
#include <graphene/chain/is_authorized_asset.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene
|
||||||
|
{
|
||||||
|
namespace chain
|
||||||
|
{
|
||||||
|
|
||||||
void_result offer_evaluator::do_evaluate(const offer_operation &op)
|
void_result offer_evaluator::do_evaluate(const offer_operation &op)
|
||||||
{ try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
database &d = db();
|
database &d = db();
|
||||||
|
|
||||||
FC_ASSERT(op.offer_expiration_date > d.head_block_time());
|
FC_ASSERT(op.offer_expiration_date > d.head_block_time());
|
||||||
FC_ASSERT( op.item_id > 0 );
|
|
||||||
FC_ASSERT(op.fee.amount >= 0);
|
FC_ASSERT(op.fee.amount >= 0);
|
||||||
FC_ASSERT(op.minimum_price.amount >= 0 && op.maximum_price.amount > 0);
|
FC_ASSERT(op.minimum_price.amount >= 0 && op.maximum_price.amount > 0);
|
||||||
FC_ASSERT(op.minimum_price.asset_id == op.maximum_price.asset_id);
|
FC_ASSERT(op.minimum_price.asset_id == op.maximum_price.asset_id);
|
||||||
FC_ASSERT(op.maximum_price >= op.minimum_price);
|
FC_ASSERT(op.maximum_price >= op.minimum_price);
|
||||||
|
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
object_id_type offer_evaluator::do_apply(const offer_operation &o)
|
object_id_type offer_evaluator::do_apply(const offer_operation &o)
|
||||||
{ try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
database &d = db();
|
database &d = db();
|
||||||
|
|
||||||
if (o.buying_item)
|
if (o.buying_item)
|
||||||
{
|
{
|
||||||
d.adjust_balance(o.issuer, -o.maximum_price);
|
d.adjust_balance(o.issuer, -o.maximum_price);
|
||||||
d.adjust_balance( o.transfer_agent_id, o.maximum_price );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &offer_obj = db().create<offer_object>([&](offer_object &obj) {
|
const auto &offer_obj = db().create<offer_object>([&](offer_object &obj) {
|
||||||
obj.issuer = o.issuer;
|
obj.issuer = o.issuer;
|
||||||
|
|
||||||
obj.transfer_agent_id = o.transfer_agent_id;
|
obj.item_ids = o.item_ids;
|
||||||
obj.item_id = o.item_id;
|
|
||||||
|
|
||||||
obj.minimum_price = o.minimum_price;
|
obj.minimum_price = o.minimum_price;
|
||||||
obj.maximum_price = o.maximum_price;
|
obj.maximum_price = o.maximum_price;
|
||||||
|
|
@ -46,29 +52,36 @@ object_id_type offer_evaluator::do_apply( const offer_operation& o )
|
||||||
auto &idx = d.get_index_type<account_index>().indices().get<by_id>();
|
auto &idx = d.get_index_type<account_index>().indices().get<by_id>();
|
||||||
auto acc = idx.find(o.issuer);
|
auto acc = idx.find(o.issuer);
|
||||||
FC_ASSERT(acc != idx.end());
|
FC_ASSERT(acc != idx.end());
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return offer_obj.id;
|
return offer_obj.id;
|
||||||
} FC_CAPTURE_AND_RETHROW((o)) }
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((o))
|
||||||
|
}
|
||||||
|
|
||||||
void_result bid_evaluator::do_evaluate(const bid_operation &op)
|
void_result bid_evaluator::do_evaluate(const bid_operation &op)
|
||||||
{ try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
database &d = db();
|
database &d = db();
|
||||||
offer_object offer = op.offer_id(d);
|
offer_object offer = op.offer_id(d);
|
||||||
|
|
||||||
FC_ASSERT(op.bid_price.asset_id == offer.minimum_price.asset_id);
|
FC_ASSERT(op.bid_price.asset_id == offer.minimum_price.asset_id);
|
||||||
FC_ASSERT( offer.transfer_agent_id(d).whitelisted_accounts.find(op.bidder) != offer.transfer_agent_id(d).whitelisted_accounts.end() );
|
|
||||||
FC_ASSERT(offer.minimum_price.amount == 0 || op.bid_price >= offer.minimum_price);
|
FC_ASSERT(offer.minimum_price.amount == 0 || op.bid_price >= offer.minimum_price);
|
||||||
FC_ASSERT(offer.maximum_price.amount == 0 || op.bid_price <= offer.maximum_price);
|
FC_ASSERT(offer.maximum_price.amount == 0 || op.bid_price <= offer.maximum_price);
|
||||||
if (offer.bidder) {
|
if (offer.bidder)
|
||||||
|
{
|
||||||
FC_ASSERT((offer.buying_item && op.bid_price < *offer.bid_price) || (!offer.buying_item && op.bid_price > *offer.bid_price));
|
FC_ASSERT((offer.buying_item && op.bid_price < *offer.bid_price) || (!offer.buying_item && op.bid_price > *offer.bid_price));
|
||||||
}
|
}
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
void_result bid_evaluator::do_apply(const bid_operation &op)
|
void_result bid_evaluator::do_apply(const bid_operation &op)
|
||||||
{ try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
database &d = db();
|
database &d = db();
|
||||||
|
|
||||||
offer_object offer = op.offer_id(d);
|
offer_object offer = op.offer_id(d);
|
||||||
|
|
@ -78,39 +91,41 @@ void_result bid_evaluator::do_apply( const bid_operation& op )
|
||||||
if (offer.bidder)
|
if (offer.bidder)
|
||||||
{
|
{
|
||||||
d.adjust_balance(*offer.bidder, *offer.bid_price);
|
d.adjust_balance(*offer.bidder, *offer.bid_price);
|
||||||
d.adjust_balance( offer.transfer_agent_id, -(*offer.bid_price ));
|
|
||||||
}
|
}
|
||||||
d.adjust_balance(op.bidder, -op.bid_price);
|
d.adjust_balance(op.bidder, -op.bid_price);
|
||||||
d.adjust_balance( offer.transfer_agent_id, op.bid_price );
|
|
||||||
}
|
}
|
||||||
d.modify( op.offer_id(d), [&]( offer_object& o )
|
d.modify(op.offer_id(d), [&](offer_object &o) {
|
||||||
|
if (op.bid_price == (offer.buying_item ? offer.minimum_price : offer.maximum_price))
|
||||||
{
|
{
|
||||||
if (op.bid_price == ( offer.buying_item ? offer.minimum_price : offer.maximum_price ) ) {
|
|
||||||
o.offer_expiration_date = d.head_block_time();
|
o.offer_expiration_date = d.head_block_time();
|
||||||
}
|
}
|
||||||
o.bidder = op.bidder;
|
o.bidder = op.bidder;
|
||||||
o.bid_price = op.bid_price;
|
o.bid_price = op.bid_price;
|
||||||
});
|
});
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
void_result finalize_offer_evaluator::do_evaluate(const finalize_offer_operation &op)
|
void_result finalize_offer_evaluator::do_evaluate(const finalize_offer_operation &op)
|
||||||
{ try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
database &d = db();
|
database &d = db();
|
||||||
offer_object offer = op.offer_id(d);
|
offer_object offer = op.offer_id(d);
|
||||||
|
|
||||||
// FC_ASSERT(*offer.bid_price == (offer.buying_item ? offer.minimum_price : offer.maximum_price));
|
|
||||||
|
|
||||||
if (op.result != result_type::ExpiredNoBid)
|
if (op.result != result_type::ExpiredNoBid)
|
||||||
{
|
{
|
||||||
FC_ASSERT(offer.bidder);
|
FC_ASSERT(offer.bidder);
|
||||||
FC_ASSERT((*offer.bid_price).amount >= 0);
|
FC_ASSERT((*offer.bid_price).amount >= 0);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
FC_ASSERT(!offer.bidder);
|
FC_ASSERT(!offer.bidder);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op.result) {
|
switch (op.result)
|
||||||
|
{
|
||||||
case result_type::Expired:
|
case result_type::Expired:
|
||||||
case result_type::ExpiredNoBid:
|
case result_type::ExpiredNoBid:
|
||||||
FC_ASSERT(offer.offer_expiration_date <= d.head_block_time());
|
FC_ASSERT(offer.offer_expiration_date <= d.head_block_time());
|
||||||
|
|
@ -121,9 +136,12 @@ void_result finalize_offer_evaluator::do_evaluate(const finalize_offer_operation
|
||||||
}
|
}
|
||||||
|
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
}
|
||||||
|
FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
}
|
||||||
|
|
||||||
void_result finalize_offer_evaluator::do_apply(const finalize_offer_operation& op) {
|
void_result finalize_offer_evaluator::do_apply(const finalize_offer_operation &op)
|
||||||
|
{
|
||||||
database &d = db();
|
database &d = db();
|
||||||
|
|
||||||
offer_object offer = op.offer_id(d);
|
offer_object offer = op.offer_id(d);
|
||||||
|
|
@ -133,41 +151,36 @@ void_result finalize_offer_evaluator::do_apply(const finalize_offer_operation& o
|
||||||
if (offer.buying_item)
|
if (offer.buying_item)
|
||||||
{
|
{
|
||||||
d.adjust_balance(*offer.bidder, *offer.bid_price);
|
d.adjust_balance(*offer.bidder, *offer.bid_price);
|
||||||
d.adjust_balance(offer.transfer_agent_id, -offer.maximum_price);
|
|
||||||
if (offer.bid_price < offer.maximum_price)
|
if (offer.bid_price < offer.maximum_price)
|
||||||
{
|
{
|
||||||
d.adjust_balance(offer.issuer, offer.maximum_price - *offer.bid_price);
|
d.adjust_balance(offer.issuer, offer.maximum_price - *offer.bid_price);
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
d.adjust_balance(offer.transfer_agent_id, -(*offer.bid_price));
|
|
||||||
d.adjust_balance(offer.issuer, *offer.bid_price);
|
d.adjust_balance(offer.issuer, *offer.bid_price);
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (offer.buying_item)
|
if (offer.buying_item)
|
||||||
{
|
{
|
||||||
d.adjust_balance(offer.issuer, offer.maximum_price);
|
d.adjust_balance(offer.issuer, offer.maximum_price);
|
||||||
d.adjust_balance(offer.transfer_agent_id, -offer.maximum_price);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.create<offer_history_object>([&](offer_history_object &obj) {
|
d.create<offer_history_object>([&](offer_history_object &obj) {
|
||||||
obj.issuer = offer.issuer;
|
obj.issuer = offer.issuer;
|
||||||
|
obj.item_ids = offer.item_ids;
|
||||||
obj.transfer_agent_id = offer.transfer_agent_id;
|
|
||||||
obj.item_id = offer.item_id;
|
|
||||||
obj.bidder = offer.bidder;
|
obj.bidder = offer.bidder;
|
||||||
obj.bid_price = offer.bid_price;
|
obj.bid_price = offer.bid_price;
|
||||||
obj.minimum_price = offer.minimum_price;
|
obj.minimum_price = offer.minimum_price;
|
||||||
obj.maximum_price = offer.maximum_price;
|
obj.maximum_price = offer.maximum_price;
|
||||||
|
|
||||||
obj.buying_item = offer.buying_item;
|
obj.buying_item = offer.buying_item;
|
||||||
obj.offer_expiration_date = offer.offer_expiration_date;
|
obj.offer_expiration_date = offer.offer_expiration_date;
|
||||||
std::cout << "get id" << uint64_t(obj.get_id()) << std::endl;
|
|
||||||
});
|
});
|
||||||
d.remove(op.offer_id(d));
|
d.remove(op.offer_id(d));
|
||||||
return void_result();
|
return void_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace chain
|
||||||
}
|
} // namespace graphene
|
||||||
|
|
@ -1,22 +1,25 @@
|
||||||
#include <graphene/chain/protocol/offer.hpp>
|
#include <graphene/chain/protocol/offer.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene
|
||||||
|
{
|
||||||
|
namespace chain
|
||||||
|
{
|
||||||
share_type offer_operation::calculate_fee(const fee_parameters_type &schedule) const
|
share_type offer_operation::calculate_fee(const fee_parameters_type &schedule) const
|
||||||
{
|
{
|
||||||
share_type core_fee_required = schedule.fee;
|
share_type core_fee_required = schedule.fee;
|
||||||
return core_fee_required;
|
return core_fee_required;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void offer_operation::validate() const
|
void offer_operation::validate() const
|
||||||
|
{
|
||||||
|
for (const auto &item_id : item_ids)
|
||||||
{
|
{
|
||||||
FC_ASSERT(item_id > 0);
|
FC_ASSERT(item_id > 0);
|
||||||
|
}
|
||||||
FC_ASSERT(fee.amount >= 0);
|
FC_ASSERT(fee.amount >= 0);
|
||||||
FC_ASSERT(minimum_price.asset_id == maximum_price.asset_id);
|
FC_ASSERT(minimum_price.asset_id == maximum_price.asset_id);
|
||||||
FC_ASSERT(minimum_price.amount >= 0 && maximum_price.amount > 0);
|
FC_ASSERT(minimum_price.amount >= 0 && maximum_price.amount > 0);
|
||||||
FC_ASSERT(maximum_price >= minimum_price);
|
FC_ASSERT(maximum_price >= minimum_price);
|
||||||
|
|
||||||
// FC_ASSERT( offer_expiration_date >= fc::time_point::now() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
share_type bid_operation::calculate_fee(const fee_parameters_type &schedule) const
|
share_type bid_operation::calculate_fee(const fee_parameters_type &schedule) const
|
||||||
|
|
@ -25,22 +28,22 @@ share_type bid_operation::calculate_fee( const fee_parameters_type& schedule )co
|
||||||
return core_fee_required;
|
return core_fee_required;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bid_operation::validate() const
|
void bid_operation::validate() const
|
||||||
{
|
{
|
||||||
FC_ASSERT(fee.amount.value >= 0);
|
FC_ASSERT(fee.amount.value >= 0);
|
||||||
FC_ASSERT(bid_price.amount.value >= 0);
|
FC_ASSERT(bid_price.amount.value >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void finalize_offer_operation::validate() const {
|
void finalize_offer_operation::validate() const
|
||||||
FC_ASSERT ( offer_id != offer_id_type() );
|
{
|
||||||
FC_ASSERT(fee.amount.value >= 0);
|
FC_ASSERT(fee.amount.value >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
share_type finalize_offer_operation::calculate_fee( const fee_parameters_type& k) const {
|
share_type finalize_offer_operation::calculate_fee(const fee_parameters_type &k) const
|
||||||
|
{
|
||||||
share_type core_fee_required = k.fee;
|
share_type core_fee_required = k.fee;
|
||||||
return core_fee_required;
|
return core_fee_required;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace chain
|
||||||
}
|
} // namespace graphene
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include <graphene/chain/event_group_object.hpp>
|
#include <graphene/chain/event_group_object.hpp>
|
||||||
#include <graphene/chain/event_object.hpp>
|
#include <graphene/chain/event_object.hpp>
|
||||||
#include <graphene/chain/tournament_object.hpp>
|
#include <graphene/chain/tournament_object.hpp>
|
||||||
|
#include <graphene/chain/offer_object.hpp>
|
||||||
|
|
||||||
#include <graphene/utilities/tempdir.hpp>
|
#include <graphene/utilities/tempdir.hpp>
|
||||||
|
|
||||||
|
|
@ -307,6 +308,20 @@ void database_fixture::verify_asset_supplies( const database& db )
|
||||||
total_balances[betting_market_group.asset_id] += o.fees_collected;
|
total_balances[betting_market_group.asset_id] += o.fees_collected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const offer_object &o : db.get_index_type<offer_index>().indices())
|
||||||
|
{
|
||||||
|
if (o.buying_item)
|
||||||
|
{
|
||||||
|
total_balances[o.maximum_price.asset_id] += o.maximum_price.amount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (o.bid_price)
|
||||||
|
{
|
||||||
|
total_balances[o.bid_price->asset_id] += o.bid_price->amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t sweeps_vestings = 0;
|
uint64_t sweeps_vestings = 0;
|
||||||
for( const sweeps_vesting_balance_object& svbo: db.get_index_type< sweeps_vesting_balance_index >().indices() )
|
for( const sweeps_vesting_balance_object& svbo: db.get_index_type< sweeps_vesting_balance_index >().indices() )
|
||||||
|
|
|
||||||
|
|
@ -1845,12 +1845,12 @@ BOOST_AUTO_TEST_CASE(create_offer_test)
|
||||||
std::for_each(params, params + 1, [&](bool is_buying_offer) {
|
std::for_each(params, params + 1, [&](bool is_buying_offer) {
|
||||||
offer_operation offer_op;
|
offer_operation offer_op;
|
||||||
|
|
||||||
offer_op.item_id = 13;
|
offer_op.item_ids.emplace(13);
|
||||||
|
offer_op.item_ids.emplace(14);
|
||||||
offer_op.issuer = issuer.id;
|
offer_op.issuer = issuer.id;
|
||||||
offer_op.buying_item = is_buying_offer;
|
offer_op.buying_item = is_buying_offer;
|
||||||
offer_op.maximum_price = asset(100);
|
offer_op.maximum_price = asset(100);
|
||||||
offer_op.minimum_price = asset(10);
|
offer_op.minimum_price = asset(10);
|
||||||
offer_op.transfer_agent_id = agent.id;
|
|
||||||
// +1 second
|
// +1 second
|
||||||
offer_op.offer_expiration_date = db.head_block_time() + fc::microseconds(3000000);
|
offer_op.offer_expiration_date = db.head_block_time() + fc::microseconds(3000000);
|
||||||
|
|
||||||
|
|
@ -1888,7 +1888,6 @@ BOOST_AUTO_TEST_CASE(create_offer_test)
|
||||||
BOOST_CHECK(d.issuer == issuer.id);
|
BOOST_CHECK(d.issuer == issuer.id);
|
||||||
BOOST_CHECK(d.maximum_price == asset(100));
|
BOOST_CHECK(d.maximum_price == asset(100));
|
||||||
BOOST_CHECK(d.minimum_price == asset(10));
|
BOOST_CHECK(d.minimum_price == asset(10));
|
||||||
BOOST_CHECK(d.transfer_agent_id == agent.id);
|
|
||||||
BOOST_CHECK(d.buying_item == is_buying_offer);
|
BOOST_CHECK(d.buying_item == is_buying_offer);
|
||||||
|
|
||||||
if (is_buying_offer)
|
if (is_buying_offer)
|
||||||
|
|
@ -1930,9 +1929,6 @@ BOOST_AUTO_TEST_CASE(bid_test)
|
||||||
bid_op.bidder = bidder.id;
|
bid_op.bidder = bidder.id;
|
||||||
trx.operations.push_back(bid_op);
|
trx.operations.push_back(bid_op);
|
||||||
|
|
||||||
// exception due to empty whitelist
|
|
||||||
GRAPHENE_REQUIRE_THROW(PUSH_TX(db, trx, ~0), fc::exception);
|
|
||||||
|
|
||||||
trx.operations.clear();
|
trx.operations.clear();
|
||||||
|
|
||||||
//adding whitelist
|
//adding whitelist
|
||||||
|
|
@ -1952,7 +1948,6 @@ BOOST_AUTO_TEST_CASE(bid_test)
|
||||||
asset exp_delta_agent;
|
asset exp_delta_agent;
|
||||||
asset exp_delta_bidder;
|
asset exp_delta_bidder;
|
||||||
|
|
||||||
int64_t agent_balance = get_balance(agent_id(db), asset_id_type()(db));
|
|
||||||
int64_t issuer_balance = get_balance(issuer_id(db), asset_id_type()(db));
|
int64_t issuer_balance = get_balance(issuer_id(db), asset_id_type()(db));
|
||||||
int64_t bidder_balance = get_balance(bidder_id(db), asset_id_type()(db));
|
int64_t bidder_balance = get_balance(bidder_id(db), asset_id_type()(db));
|
||||||
|
|
||||||
|
|
@ -1985,8 +1980,6 @@ BOOST_AUTO_TEST_CASE(bid_test)
|
||||||
|
|
||||||
PUSH_TX(db, trx, ~0);
|
PUSH_TX(db, trx, ~0);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(agent_id(db), asset_id_type()(db)),
|
|
||||||
(agent_balance + exp_delta_agent.amount).value);
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(bidder_id(db), asset_id_type()(db)),
|
BOOST_CHECK_EQUAL(get_balance(bidder_id(db), asset_id_type()(db)),
|
||||||
(bidder_balance + exp_delta_bidder.amount).value);
|
(bidder_balance + exp_delta_bidder.amount).value);
|
||||||
|
|
||||||
|
|
@ -1997,7 +1990,6 @@ BOOST_AUTO_TEST_CASE(bid_test)
|
||||||
// data integrity
|
// data integrity
|
||||||
BOOST_CHECK(offer_obj.bidder == bidder.id);
|
BOOST_CHECK(offer_obj.bidder == bidder.id);
|
||||||
BOOST_CHECK(offer_obj.issuer == issuer.id);
|
BOOST_CHECK(offer_obj.issuer == issuer.id);
|
||||||
BOOST_CHECK(offer_obj.transfer_agent_id == agent.id);
|
|
||||||
BOOST_CHECK(offer_obj.maximum_price == asset(100));
|
BOOST_CHECK(offer_obj.maximum_price == asset(100));
|
||||||
BOOST_CHECK(offer_obj.minimum_price == asset(10));
|
BOOST_CHECK(offer_obj.minimum_price == asset(10));
|
||||||
BOOST_CHECK(offer_obj.bid_price == bid);
|
BOOST_CHECK(offer_obj.bid_price == bid);
|
||||||
|
|
@ -2072,8 +2064,6 @@ BOOST_AUTO_TEST_CASE(second_bid_test)
|
||||||
|
|
||||||
PUSH_TX(db, trx, ~0);
|
PUSH_TX(db, trx, ~0);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(agent_id(db), asset_id_type()(db)),
|
|
||||||
(agent_balance + exp_delta_agent.amount).value);
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(bidder_id(db), asset_id_type()(db)),
|
BOOST_CHECK_EQUAL(get_balance(bidder_id(db), asset_id_type()(db)),
|
||||||
(bidder_balance + exp_delta_bidder.amount).value);
|
(bidder_balance + exp_delta_bidder.amount).value);
|
||||||
BOOST_CHECK_EQUAL(get_balance(bidder2_id(db), asset_id_type()(db)),
|
BOOST_CHECK_EQUAL(get_balance(bidder2_id(db), asset_id_type()(db)),
|
||||||
|
|
@ -2085,7 +2075,6 @@ BOOST_AUTO_TEST_CASE(second_bid_test)
|
||||||
|
|
||||||
// data integrity
|
// data integrity
|
||||||
BOOST_CHECK(offer_obj.bidder == bidder2.id);
|
BOOST_CHECK(offer_obj.bidder == bidder2.id);
|
||||||
BOOST_CHECK(offer_obj.transfer_agent_id == agent.id);
|
|
||||||
BOOST_CHECK(offer_obj.maximum_price == asset(100));
|
BOOST_CHECK(offer_obj.maximum_price == asset(100));
|
||||||
BOOST_CHECK(offer_obj.minimum_price == asset(10));
|
BOOST_CHECK(offer_obj.minimum_price == asset(10));
|
||||||
BOOST_CHECK(offer_obj.bid_price == bid);
|
BOOST_CHECK(offer_obj.bid_price == bid);
|
||||||
|
|
@ -2168,8 +2157,6 @@ BOOST_AUTO_TEST_CASE(buyout_offer_test)
|
||||||
|
|
||||||
generate_block();
|
generate_block();
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(agent_id(db), asset_id_type()(db)),
|
|
||||||
(agent_balance + exp_delta_agent.amount).value);
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(bidder_id(db), asset_id_type()(db)),
|
BOOST_CHECK_EQUAL(get_balance(bidder_id(db), asset_id_type()(db)),
|
||||||
(bidder_balance + exp_delta_bidder.amount).value);
|
(bidder_balance + exp_delta_bidder.amount).value);
|
||||||
BOOST_CHECK_EQUAL(get_balance(issuer_id(db), asset_id_type()(db)),
|
BOOST_CHECK_EQUAL(get_balance(issuer_id(db), asset_id_type()(db)),
|
||||||
|
|
@ -2189,8 +2176,7 @@ BOOST_AUTO_TEST_CASE(buyout_offer_test)
|
||||||
BOOST_CHECK(cached_offer_obj.maximum_price == history_obj.maximum_price);
|
BOOST_CHECK(cached_offer_obj.maximum_price == history_obj.maximum_price);
|
||||||
BOOST_CHECK(cached_offer_obj.minimum_price == history_obj.minimum_price);
|
BOOST_CHECK(cached_offer_obj.minimum_price == history_obj.minimum_price);
|
||||||
BOOST_CHECK(cached_offer_obj.offer_expiration_date == history_obj.offer_expiration_date);
|
BOOST_CHECK(cached_offer_obj.offer_expiration_date == history_obj.offer_expiration_date);
|
||||||
BOOST_CHECK(cached_offer_obj.transfer_agent_id == history_obj.transfer_agent_id);
|
BOOST_CHECK(cached_offer_obj.item_ids == history_obj.item_ids);
|
||||||
BOOST_CHECK(cached_offer_obj.item_id == history_obj.item_id);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (fc::exception &e)
|
catch (fc::exception &e)
|
||||||
|
|
@ -2243,8 +2229,6 @@ BOOST_AUTO_TEST_CASE(expire_with_bid_offer_test)
|
||||||
|
|
||||||
generate_blocks(5);
|
generate_blocks(5);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(agent_id(db), asset_id_type()(db)),
|
|
||||||
(agent_balance + exp_delta_agent.amount).value);
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(issuer_id(db), asset_id_type()(db)),
|
BOOST_CHECK_EQUAL(get_balance(issuer_id(db), asset_id_type()(db)),
|
||||||
(issuer_balance + exp_delta_issuer.amount).value);
|
(issuer_balance + exp_delta_issuer.amount).value);
|
||||||
BOOST_CHECK_EQUAL(get_balance(bidder_id(db), asset_id_type()(db)),
|
BOOST_CHECK_EQUAL(get_balance(bidder_id(db), asset_id_type()(db)),
|
||||||
|
|
@ -2264,8 +2248,7 @@ BOOST_AUTO_TEST_CASE(expire_with_bid_offer_test)
|
||||||
BOOST_CHECK(cached_offer_obj.maximum_price == history_obj.maximum_price);
|
BOOST_CHECK(cached_offer_obj.maximum_price == history_obj.maximum_price);
|
||||||
BOOST_CHECK(cached_offer_obj.minimum_price == history_obj.minimum_price);
|
BOOST_CHECK(cached_offer_obj.minimum_price == history_obj.minimum_price);
|
||||||
BOOST_CHECK(cached_offer_obj.offer_expiration_date == history_obj.offer_expiration_date);
|
BOOST_CHECK(cached_offer_obj.offer_expiration_date == history_obj.offer_expiration_date);
|
||||||
BOOST_CHECK(cached_offer_obj.transfer_agent_id == history_obj.transfer_agent_id);
|
BOOST_CHECK(cached_offer_obj.item_ids == history_obj.item_ids);
|
||||||
BOOST_CHECK(cached_offer_obj.item_id == history_obj.item_id);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2306,8 +2289,6 @@ BOOST_AUTO_TEST_CASE(expire_no_bid_offer_test)
|
||||||
|
|
||||||
generate_blocks(5);
|
generate_blocks(5);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(agent_id(db), asset_id_type()(db)),
|
|
||||||
(agent_balance + exp_delta_agent.amount).value);
|
|
||||||
BOOST_CHECK_EQUAL(get_balance(issuer_id(db), asset_id_type()(db)),
|
BOOST_CHECK_EQUAL(get_balance(issuer_id(db), asset_id_type()(db)),
|
||||||
(issuer_balance + exp_delta_issuer.amount).value);
|
(issuer_balance + exp_delta_issuer.amount).value);
|
||||||
|
|
||||||
|
|
@ -2325,8 +2306,7 @@ BOOST_AUTO_TEST_CASE(expire_no_bid_offer_test)
|
||||||
BOOST_CHECK(cached_offer_obj.maximum_price == history_obj.maximum_price);
|
BOOST_CHECK(cached_offer_obj.maximum_price == history_obj.maximum_price);
|
||||||
BOOST_CHECK(cached_offer_obj.minimum_price == history_obj.minimum_price);
|
BOOST_CHECK(cached_offer_obj.minimum_price == history_obj.minimum_price);
|
||||||
BOOST_CHECK(cached_offer_obj.offer_expiration_date == history_obj.offer_expiration_date);
|
BOOST_CHECK(cached_offer_obj.offer_expiration_date == history_obj.offer_expiration_date);
|
||||||
BOOST_CHECK(cached_offer_obj.transfer_agent_id == history_obj.transfer_agent_id);
|
BOOST_CHECK(cached_offer_obj.item_ids == history_obj.item_ids);
|
||||||
BOOST_CHECK(cached_offer_obj.item_id == history_obj.item_id);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// TODO: Write linear VBO tests
|
// TODO: Write linear VBO tests
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue