diff --git a/libraries/chain/db_update.cpp b/libraries/chain/db_update.cpp index a08c33fd..df37c741 100644 --- a/libraries/chain/db_update.cpp +++ b/libraries/chain/db_update.cpp @@ -720,7 +720,7 @@ void database::finalize_expired_offers(){ ++itr; finalize_offer_operation finalize; - finalize.fee_paying_account = offer.transfer_agent_id; + finalize.fee_paying_account = offer.issuer; finalize.offer_id = offer.id; finalize.fee = current_fee_schedule().calculate_fee( finalize ); finalize.result = offer.bidder ? result_type::Expired : result_type::ExpiredNoBid; diff --git a/libraries/chain/include/graphene/chain/offer_evaluator.hpp b/libraries/chain/include/graphene/chain/offer_evaluator.hpp index 141b8bfa..d566410d 100644 --- a/libraries/chain/include/graphene/chain/offer_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/offer_evaluator.hpp @@ -2,33 +2,37 @@ #include #include -namespace graphene { namespace chain { +namespace graphene +{ +namespace chain +{ - class offer_evaluator : public evaluator - { - public: - typedef offer_operation operation_type; +class offer_evaluator : public evaluator +{ +public: + typedef offer_operation operation_type; - void_result do_evaluate( const offer_operation& o ); - object_id_type do_apply( const offer_operation& o ); - }; - - class bid_evaluator : public evaluator - { - public: - typedef bid_operation operation_type; + void_result do_evaluate(const offer_operation &o); + object_id_type do_apply(const offer_operation &o); +}; - void_result do_evaluate( const bid_operation& o ); - void_result do_apply( const bid_operation& o ); - }; +class bid_evaluator : public evaluator +{ +public: + typedef bid_operation operation_type; - class finalize_offer_evaluator : public evaluator - { - public: - typedef finalize_offer_operation operation_type; + void_result do_evaluate(const bid_operation &o); + void_result do_apply(const bid_operation &o); +}; - void_result do_evaluate( const finalize_offer_operation& op ); - void_result do_apply( const finalize_offer_operation& op ); - }; +class finalize_offer_evaluator : public evaluator +{ +public: + typedef finalize_offer_operation operation_type; -}} + void_result do_evaluate(const finalize_offer_operation &op); + void_result do_apply(const finalize_offer_operation &op); +}; + +} // namespace chain +} // namespace graphene diff --git a/libraries/chain/include/graphene/chain/offer_object.hpp b/libraries/chain/include/graphene/chain/offer_object.hpp index 1c3ee7ba..9fe29a46 100644 --- a/libraries/chain/include/graphene/chain/offer_object.hpp +++ b/libraries/chain/include/graphene/chain/offer_object.hpp @@ -2,116 +2,106 @@ #include #include -namespace graphene { namespace chain { - class database; +namespace graphene +{ +namespace chain +{ +class database; - /** +/** * @brief This class represents an offer on the object graph * @ingroup object * @ingroup protocol * */ - struct by_expiration_date{}; - class offer_object : public graphene::db::abstract_object +struct by_expiration_date +{ +}; +class offer_object : public graphene::db::abstract_object +{ +public: + static const uint8_t space_id = protocol_ids; + static const uint8_t type_id = offer_object_type; + + account_id_type issuer; + + set item_ids; + optional bidder; + optional bid_price; + asset minimum_price; + asset maximum_price; + + bool buying_item; + fc::time_point_sec offer_expiration_date; + + offer_id_type get_id() const { return id; } +}; + +class offer_history_object : public graphene::db::abstract_object +{ +public: + static const uint8_t space_id = implementation_ids; + static const uint8_t type_id = impl_offer_history_object_type; + + account_id_type issuer; + + set item_ids; + optional bidder; + optional bid_price; + asset minimum_price; + asset maximum_price; + + bool buying_item; + fc::time_point_sec offer_expiration_date; + + offer_history_id_type get_id() const { return id; } +}; + +struct compare_by_expiration_date +{ + bool operator()(const fc::time_point_sec &o1, const fc::time_point_sec &o2) const { - public: - static const uint8_t space_id = protocol_ids; - static const uint8_t type_id = offer_object_type; + return o1 > o2; + } +}; - account_id_type issuer; - - account_id_type transfer_agent_id; - uint32_t item_id; - optional bidder; - optional bid_price; - asset minimum_price; - asset maximum_price; - - bool buying_item; - fc::time_point_sec offer_expiration_date; - - offer_id_type get_id()const { return id; } - }; - - class offer_history_object : public graphene::db::abstract_object - { - public: - static const uint8_t space_id = implementation_ids; - static const uint8_t type_id = impl_offer_history_object_type; - - account_id_type issuer; - - account_id_type transfer_agent_id; - uint32_t item_id; - optional bidder; - optional bid_price; - asset minimum_price; - asset maximum_price; - - bool buying_item; - fc::time_point_sec offer_expiration_date; - - offer_history_id_type get_id()const { return id; } - }; - - struct compare_by_expiration_date { - bool operator()( const fc::time_point_sec& o1, const fc::time_point_sec& o2 ) const { - return o1 > o2; - } - }; - - /** +/** * @ingroup object_index */ - typedef multi_index_container< - offer_object, - indexed_by< - ordered_unique< tag, member< object, object_id_type, &object::id > >, - ordered_non_unique< - tag, - member< offer_object, fc::time_point_sec, &offer_object::offer_expiration_date >, - compare_by_expiration_date - > - > - > offer_multi_index_type; +typedef multi_index_container< + offer_object, + indexed_by< + ordered_unique, member>, + ordered_non_unique< + tag, + member, + compare_by_expiration_date>>> + offer_multi_index_type; - typedef multi_index_container< - offer_history_object, - indexed_by< - ordered_unique< tag, member< object, object_id_type, &object::id > >, - ordered_non_unique< - tag, - member< offer_history_object, fc::time_point_sec, &offer_history_object::offer_expiration_date >, - compare_by_expiration_date - > - > - > offer_history_multi_index_type; +typedef multi_index_container< + offer_history_object, + indexed_by< + ordered_unique, member>, + ordered_non_unique< + tag, + member, + compare_by_expiration_date>>> + offer_history_multi_index_type; - /** +/** * @ingroup object_index */ - typedef generic_index offer_index; +typedef generic_index offer_index; - typedef generic_index offer_history_index; +typedef generic_index offer_history_index; -}} +} // namespace chain +} // namespace graphene -FC_REFLECT_DERIVED( graphene::chain::offer_object, - (graphene::db::object), - (issuer) - (transfer_agent_id)(item_id) - (bidder)(bid_price) - (minimum_price)(maximum_price) - (buying_item) - (offer_expiration_date) - ) +FC_REFLECT_DERIVED(graphene::chain::offer_object, + (graphene::db::object), + (issuer)(item_ids)(bidder)(bid_price)(minimum_price)(maximum_price)(buying_item)(offer_expiration_date)) -FC_REFLECT_DERIVED( graphene::chain::offer_history_object, - (graphene::db::object), - (issuer) - (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, + (graphene::db::object), + (issuer)(item_ids)(bidder)(bid_price)(minimum_price)(maximum_price)(buying_item)(offer_expiration_date)) diff --git a/libraries/chain/include/graphene/chain/protocol/offer.hpp b/libraries/chain/include/graphene/chain/protocol/offer.hpp index 5d982318..627766be 100644 --- a/libraries/chain/include/graphene/chain/protocol/offer.hpp +++ b/libraries/chain/include/graphene/chain/protocol/offer.hpp @@ -2,105 +2,115 @@ #include #include -namespace graphene { namespace chain { +namespace graphene +{ +namespace chain +{ - /* +/* * @class offer_operation * @brief To place an offer to buy or sell an item, a user broadcasts a proposed transaction * @ingroup operations * @pre amount.asset_id->issuer == issuer * @pre issuer != from because this is pointless, use a normal transfer operation */ - 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; - uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos. - }; - - account_id_type transfer_agent_id; - uint32_t item_id; - - // /** - // * minimum_price.asset_id == maximum_price.asset_id. - // * to set fixed price without auction minimum_price == maximum_price - // * If buying_item is true, and minimum_price != maximum_price, the user is proposing a “reverse auction” - // * where bidders can offer to sell the item for progressively lower prices. - // * In this case, minimum_price functions as the sell-it-now price for the reverse auction - // */ - - asset fee; - account_id_type issuer; - - /// minimum_price is minimum bid price. 0 if no minimum_price required - asset minimum_price; - /// buy_it_now price. 0 if no maximum price - asset maximum_price; - /// true means user wants to buy item, false mean user is selling item - bool buying_item; - /// not transaction expiration date - fc::time_point_sec offer_expiration_date; - - /// User provided data encrypted to the memo key of the "to" account - optional memo; - extensions_type extensions; - - account_id_type fee_payer()const { return transfer_agent_id; } - void validate()const; - share_type calculate_fee(const fee_parameters_type& k)const; + uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION; + uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos. }; - struct bid_operation : public base_operation + set item_ids; + + // /** + // * minimum_price.asset_id == maximum_price.asset_id. + // * to set fixed price without auction minimum_price == maximum_price + // * If buying_item is true, and minimum_price != maximum_price, the user is proposing a “reverse auction” + // * where bidders can offer to sell the item for progressively lower prices. + // * In this case, minimum_price functions as the sell-it-now price for the reverse auction + // */ + + asset fee; + account_id_type issuer; + + /// minimum_price is minimum bid price. 0 if no minimum_price required + asset minimum_price; + /// buy_it_now price. 0 if no maximum price + asset maximum_price; + /// true means user wants to buy item, false mean user is selling item + bool buying_item; + /// not transaction expiration date + fc::time_point_sec offer_expiration_date; + + /// User provided data encrypted to the memo key of the "to" account + optional memo; + extensions_type extensions; + + account_id_type fee_payer() const { return issuer; } + void validate() const; + share_type calculate_fee(const fee_parameters_type &k) const; +}; + +struct bid_operation : public base_operation +{ + struct fee_parameters_type { - struct fee_parameters_type { - uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION; - uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos. - }; - - asset fee; - account_id_type bidder; - - asset bid_price; - offer_id_type offer_id; - - extensions_type extensions; - - account_id_type fee_payer()const { return bidder; } - void validate()const; - share_type calculate_fee(const fee_parameters_type& k)const; + uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION; + uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos. }; - enum class result_type {Expired = 0, ExpiredNoBid = 1}; + asset fee; + account_id_type bidder; - struct finalize_offer_operation : public base_operation + asset bid_price; + offer_id_type offer_id; + + extensions_type extensions; + + account_id_type fee_payer() const { return bidder; } + void validate() const; + share_type calculate_fee(const fee_parameters_type &k) const; +}; + +enum class result_type +{ + Expired = 0, + ExpiredNoBid = 1 +}; + +struct finalize_offer_operation : public base_operation +{ + struct fee_parameters_type { - struct fee_parameters_type { - uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION; - uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos. - }; - - asset fee; - account_id_type fee_paying_account; - - offer_id_type offer_id; - - fc::enum_type result; - - extensions_type extensions; - - account_id_type fee_payer()const { return fee_paying_account; } - void validate()const; - share_type calculate_fee(const fee_parameters_type& k)const; + uint64_t fee = 20 * GRAPHENE_BLOCKCHAIN_PRECISION; + uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos. }; -}} // graphene::chain + asset fee; + account_id_type fee_paying_account; -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) ); + offer_id_type offer_id; -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::enum_type result; -FC_REFLECT_ENUM( graphene::chain::result_type, (Expired)(ExpiredNoBid) ); -FC_REFLECT( graphene::chain::finalize_offer_operation::fee_parameters_type, (fee)(price_per_kbyte) ); -FC_REFLECT( graphene::chain::finalize_offer_operation, (fee)(fee_paying_account)(offer_id)(result)(extensions) ); + extensions_type extensions; + + account_id_type fee_payer() const { return fee_paying_account; } + void validate() const; + share_type calculate_fee(const fee_parameters_type &k) const; +}; + +} // namespace chain +} // namespace graphene + +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)(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)(bidder)(bid_price)(offer_id)(extensions)); + +FC_REFLECT_ENUM(graphene::chain::result_type, (Expired)(ExpiredNoBid)); +FC_REFLECT(graphene::chain::finalize_offer_operation::fee_parameters_type, (fee)(price_per_kbyte)); +FC_REFLECT(graphene::chain::finalize_offer_operation, (fee)(fee_paying_account)(offer_id)(result)(extensions)); diff --git a/libraries/chain/offer_evaluator.cpp b/libraries/chain/offer_evaluator.cpp index 192c60e7..d75b6408 100644 --- a/libraries/chain/offer_evaluator.cpp +++ b/libraries/chain/offer_evaluator.cpp @@ -6,125 +6,143 @@ #include #include -namespace graphene { namespace chain { +namespace graphene +{ +namespace chain +{ -void_result offer_evaluator::do_evaluate( const offer_operation& op ) -{ try { - database& d = db(); - - 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.minimum_price.amount >= 0 && op.maximum_price.amount > 0); - FC_ASSERT( op.minimum_price.asset_id == op.maximum_price.asset_id ); - FC_ASSERT( op.maximum_price >= op.minimum_price ); - - return void_result(); -} FC_CAPTURE_AND_RETHROW( (op) ) } - -object_id_type offer_evaluator::do_apply( const offer_operation& o ) -{ try { - database& d = db(); - - if (o.buying_item) - { - 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& obj ){ - obj.issuer = o.issuer; - - obj.transfer_agent_id = o.transfer_agent_id; - obj.item_id = o.item_id; - - obj.minimum_price = o.minimum_price; - obj.maximum_price = o.maximum_price; - - obj.buying_item = o.buying_item; - obj.offer_expiration_date = o.offer_expiration_date; - auto& idx = d.get_index_type().indices().get(); - auto acc = idx.find(o.issuer); - FC_ASSERT(acc != idx.end()); - - }); - - return offer_obj.id; -} FC_CAPTURE_AND_RETHROW((o)) } - -void_result bid_evaluator::do_evaluate( const bid_operation& op ) -{ try { - database& d = db(); - offer_object offer = op.offer_id(d); - - 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.maximum_price.amount == 0 || op.bid_price <= offer.maximum_price); - if (offer.bidder) { - FC_ASSERT((offer.buying_item && op.bid_price < *offer.bid_price) || (!offer.buying_item && op.bid_price > *offer.bid_price)); - } - return void_result(); -} FC_CAPTURE_AND_RETHROW( (op) ) } - -void_result bid_evaluator::do_apply( const bid_operation& op ) -{ try { - database& d = db(); - - offer_object offer = op.offer_id(d); - - if (!offer.buying_item) - { - if(offer.bidder) - { - 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( offer.transfer_agent_id, op.bid_price ); - } - d.modify( op.offer_id(d), [&]( offer_object& o ) - { - if (op.bid_price == ( offer.buying_item ? offer.minimum_price : offer.maximum_price ) ) { - o.offer_expiration_date = d.head_block_time(); - } - o.bidder = op.bidder; - o.bid_price = op.bid_price; - }); - return void_result(); -} FC_CAPTURE_AND_RETHROW( (op) ) } - -void_result finalize_offer_evaluator::do_evaluate(const finalize_offer_operation& op) -{ try { - database& d = db(); - 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) +void_result offer_evaluator::do_evaluate(const offer_operation &op) +{ + try { - FC_ASSERT(offer.bidder); - FC_ASSERT((*offer.bid_price).amount >= 0); - } else - { - FC_ASSERT(!offer.bidder); + database &d = db(); + + FC_ASSERT(op.offer_expiration_date > d.head_block_time()); + FC_ASSERT(op.fee.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.maximum_price >= op.minimum_price); + + return void_result(); } + FC_CAPTURE_AND_RETHROW((op)) +} - switch (op.result) { +object_id_type offer_evaluator::do_apply(const offer_operation &o) +{ + try + { + database &d = db(); + + if (o.buying_item) + { + d.adjust_balance(o.issuer, -o.maximum_price); + } + + const auto &offer_obj = db().create([&](offer_object &obj) { + obj.issuer = o.issuer; + + obj.item_ids = o.item_ids; + + obj.minimum_price = o.minimum_price; + obj.maximum_price = o.maximum_price; + + obj.buying_item = o.buying_item; + obj.offer_expiration_date = o.offer_expiration_date; + auto &idx = d.get_index_type().indices().get(); + auto acc = idx.find(o.issuer); + FC_ASSERT(acc != idx.end()); + }); + + return offer_obj.id; + } + FC_CAPTURE_AND_RETHROW((o)) +} + +void_result bid_evaluator::do_evaluate(const bid_operation &op) +{ + try + { + database &d = db(); + offer_object offer = op.offer_id(d); + + FC_ASSERT(op.bid_price.asset_id == offer.minimum_price.asset_id); + 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); + if (offer.bidder) + { + FC_ASSERT((offer.buying_item && op.bid_price < *offer.bid_price) || (!offer.buying_item && op.bid_price > *offer.bid_price)); + } + return void_result(); + } + FC_CAPTURE_AND_RETHROW((op)) +} + +void_result bid_evaluator::do_apply(const bid_operation &op) +{ + try + { + database &d = db(); + + offer_object offer = op.offer_id(d); + + if (!offer.buying_item) + { + if (offer.bidder) + { + d.adjust_balance(*offer.bidder, *offer.bid_price); + } + d.adjust_balance(op.bidder, -op.bid_price); + } + d.modify(op.offer_id(d), [&](offer_object &o) { + if (op.bid_price == (offer.buying_item ? offer.minimum_price : offer.maximum_price)) + { + o.offer_expiration_date = d.head_block_time(); + } + o.bidder = op.bidder; + o.bid_price = op.bid_price; + }); + return void_result(); + } + FC_CAPTURE_AND_RETHROW((op)) +} + +void_result finalize_offer_evaluator::do_evaluate(const finalize_offer_operation &op) +{ + try + { + database &d = db(); + offer_object offer = op.offer_id(d); + + if (op.result != result_type::ExpiredNoBid) + { + FC_ASSERT(offer.bidder); + FC_ASSERT((*offer.bid_price).amount >= 0); + } + else + { + FC_ASSERT(!offer.bidder); + } + + switch (op.result) + { case result_type::Expired: case result_type::ExpiredNoBid: FC_ASSERT(offer.offer_expiration_date <= d.head_block_time()); break; default: - FC_THROW_EXCEPTION( fc::assert_exception, "finalize_offer_operation: unknown result type." ); + FC_THROW_EXCEPTION(fc::assert_exception, "finalize_offer_operation: unknown result type."); break; + } + + return void_result(); } + FC_CAPTURE_AND_RETHROW((op)) +} - return void_result(); -} FC_CAPTURE_AND_RETHROW( (op) ) } - -void_result finalize_offer_evaluator::do_apply(const finalize_offer_operation& op) { - database& d = db(); +void_result finalize_offer_evaluator::do_apply(const finalize_offer_operation &op) +{ + database &d = db(); 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) { 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) { 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); } - } else + } + else { if (offer.buying_item) { d.adjust_balance(offer.issuer, offer.maximum_price); - d.adjust_balance(offer.transfer_agent_id, -offer.maximum_price); } } - d.create( [&]( offer_history_object& obj ) { - obj.issuer = offer.issuer; - - obj.transfer_agent_id = offer.transfer_agent_id; - obj.item_id = offer.item_id; - obj.bidder = offer.bidder; - obj.bid_price = offer.bid_price; - obj.minimum_price = offer.minimum_price; - obj.maximum_price = offer.maximum_price; - - obj.buying_item = offer.buying_item; - obj.offer_expiration_date = offer.offer_expiration_date; - std::cout << "get id" << uint64_t(obj.get_id()) << std::endl; + d.create([&](offer_history_object &obj) { + obj.issuer = offer.issuer; + obj.item_ids = offer.item_ids; + obj.bidder = offer.bidder; + obj.bid_price = offer.bid_price; + obj.minimum_price = offer.minimum_price; + obj.maximum_price = offer.maximum_price; + obj.buying_item = offer.buying_item; + obj.offer_expiration_date = offer.offer_expiration_date; }); d.remove(op.offer_id(d)); return void_result(); } -} -} \ No newline at end of file +} // namespace chain +} // namespace graphene \ No newline at end of file diff --git a/libraries/chain/protocol/offer.cpp b/libraries/chain/protocol/offer.cpp index 0f8afa18..3909e5cd 100644 --- a/libraries/chain/protocol/offer.cpp +++ b/libraries/chain/protocol/offer.cpp @@ -1,46 +1,49 @@ #include -namespace graphene { namespace chain { -share_type offer_operation::calculate_fee( const fee_parameters_type& schedule )const +namespace graphene { - share_type core_fee_required = schedule.fee; - return core_fee_required; -} - - -void offer_operation::validate()const +namespace chain { - FC_ASSERT( item_id > 0 ); - FC_ASSERT( fee.amount >= 0 ); - FC_ASSERT( minimum_price.asset_id == maximum_price.asset_id ); - FC_ASSERT( minimum_price.amount >= 0 && maximum_price.amount > 0); - 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 offer_operation::calculate_fee(const fee_parameters_type &schedule) const { - share_type core_fee_required = schedule.fee; - return core_fee_required; + share_type core_fee_required = schedule.fee; + return core_fee_required; } - -void bid_operation::validate()const +void offer_operation::validate() const { - FC_ASSERT( fee.amount.value >= 0 ); - FC_ASSERT( bid_price.amount.value >= 0 ); + for (const auto &item_id : item_ids) + { + FC_ASSERT(item_id > 0); + } + FC_ASSERT(fee.amount >= 0); + FC_ASSERT(minimum_price.asset_id == maximum_price.asset_id); + FC_ASSERT(minimum_price.amount >= 0 && maximum_price.amount > 0); + FC_ASSERT(maximum_price >= minimum_price); } -void finalize_offer_operation::validate() const { - FC_ASSERT ( offer_id != offer_id_type() ); - FC_ASSERT( fee.amount.value >= 0 ); +share_type bid_operation::calculate_fee(const fee_parameters_type &schedule) const +{ + share_type core_fee_required = schedule.fee; + return core_fee_required; } -share_type finalize_offer_operation::calculate_fee( const fee_parameters_type& k) const { - share_type core_fee_required = k.fee; - return core_fee_required; +void bid_operation::validate() const +{ + FC_ASSERT(fee.amount.value >= 0); + FC_ASSERT(bid_price.amount.value >= 0); } +void finalize_offer_operation::validate() const +{ + FC_ASSERT(fee.amount.value >= 0); } -} \ No newline at end of file + +share_type finalize_offer_operation::calculate_fee(const fee_parameters_type &k) const +{ + share_type core_fee_required = k.fee; + return core_fee_required; +} + +} // namespace chain +} // namespace graphene \ No newline at end of file diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index edddfb42..3a381585 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include @@ -307,7 +308,21 @@ void database_fixture::verify_asset_supplies( const database& db ) total_balances[betting_market_group.asset_id] += o.fees_collected; } - + for (const offer_object &o : db.get_index_type().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; for( const sweeps_vesting_balance_object& svbo: db.get_index_type< sweeps_vesting_balance_index >().indices() ) sweeps_vestings += svbo.balance; diff --git a/tests/tests/operation_tests.cpp b/tests/tests/operation_tests.cpp index ed656a8b..0f5dbf8d 100644 --- a/tests/tests/operation_tests.cpp +++ b/tests/tests/operation_tests.cpp @@ -1845,12 +1845,12 @@ BOOST_AUTO_TEST_CASE(create_offer_test) std::for_each(params, params + 1, [&](bool is_buying_offer) { 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.buying_item = is_buying_offer; offer_op.maximum_price = asset(100); offer_op.minimum_price = asset(10); - offer_op.transfer_agent_id = agent.id; // +1 second 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.maximum_price == asset(100)); BOOST_CHECK(d.minimum_price == asset(10)); - BOOST_CHECK(d.transfer_agent_id == agent.id); BOOST_CHECK(d.buying_item == is_buying_offer); if (is_buying_offer) @@ -1930,9 +1929,6 @@ BOOST_AUTO_TEST_CASE(bid_test) bid_op.bidder = bidder.id; trx.operations.push_back(bid_op); - // exception due to empty whitelist - GRAPHENE_REQUIRE_THROW(PUSH_TX(db, trx, ~0), fc::exception); - trx.operations.clear(); //adding whitelist @@ -1952,7 +1948,6 @@ BOOST_AUTO_TEST_CASE(bid_test) asset exp_delta_agent; 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 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); - 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)), (bidder_balance + exp_delta_bidder.amount).value); @@ -1997,7 +1990,6 @@ BOOST_AUTO_TEST_CASE(bid_test) // data integrity BOOST_CHECK(offer_obj.bidder == bidder.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.minimum_price == asset(10)); BOOST_CHECK(offer_obj.bid_price == bid); @@ -2072,8 +2064,6 @@ BOOST_AUTO_TEST_CASE(second_bid_test) 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)), (bidder_balance + exp_delta_bidder.amount).value); 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 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.minimum_price == asset(10)); BOOST_CHECK(offer_obj.bid_price == bid); @@ -2168,8 +2157,6 @@ BOOST_AUTO_TEST_CASE(buyout_offer_test) 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)), (bidder_balance + exp_delta_bidder.amount).value); 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.minimum_price == history_obj.minimum_price); 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_id == history_obj.item_id); + BOOST_CHECK(cached_offer_obj.item_ids == history_obj.item_ids); }); } catch (fc::exception &e) @@ -2243,8 +2229,6 @@ BOOST_AUTO_TEST_CASE(expire_with_bid_offer_test) 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)), (issuer_balance + exp_delta_issuer.amount).value); 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.minimum_price == history_obj.minimum_price); 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_id == history_obj.item_id); + BOOST_CHECK(cached_offer_obj.item_ids == history_obj.item_ids); }); } @@ -2306,8 +2289,6 @@ BOOST_AUTO_TEST_CASE(expire_no_bid_offer_test) 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)), (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.minimum_price == history_obj.minimum_price); 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_id == history_obj.item_id); + BOOST_CHECK(cached_offer_obj.item_ids == history_obj.item_ids); }); } // TODO: Write linear VBO tests