diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 2210b008..5ea05e45 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -553,4 +553,24 @@ namespace graphene { namespace app { } FC_CAPTURE_AND_RETHROW( (id) ) } + vector database_api::get_balance_objects( const vector
& addrs )const + { try { + const auto& bal_idx = _db.get_index_type(); + const auto& by_owner_idx = bal_idx.indices().get(); + + vector result; + + for( const auto& owner : addrs ) + { + auto itr = by_owner_idx.lower_bound( boost::make_tuple( owner, asset_id_type(0) ) ); + while( itr != by_owner_idx.end() && itr->owner == owner ) + { + result.push_back( *itr ); + ++itr; + } + } + return result; + } FC_CAPTURE_AND_RETHROW( (addrs) ) } + + } } // graphene::app diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index be3b1d5f..bc68aeef 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -252,6 +253,9 @@ namespace graphene { namespace app { */ vector get_margin_positions( const account_id_type& id )const; + /** @return all unclaimed balance objects for a set of addresses */ + vector get_balance_objects( const vector
& addrs )const; + private: /** called every time a block is applied to report the objects that were changed */ void on_objects_changed(const vector& ids); @@ -395,6 +399,7 @@ FC_API(graphene::app::database_api, (get_account_references) (get_keys_for_address) (get_margin_positions) + (get_balance_objects) ) FC_API(graphene::app::history_api, (get_account_history)(get_market_history)(get_market_history_buckets)) FC_API(graphene::app::network_api, (broadcast_transaction)(add_node)(get_connected_peers)) diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index fda048c7..c17fe0cb 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include #include #include +#include #include @@ -94,6 +96,7 @@ void database::initialize_evaluators() register_evaluator(); register_evaluator(); register_evaluator(); + register_evaluator(); } void database::initialize_indexes() @@ -123,6 +126,7 @@ void database::initialize_indexes() add_index< primary_index >(); add_index< primary_index > >(); add_index< primary_index >(); + add_index< primary_index >(); //Implementation object indexes add_index< primary_index >(); diff --git a/libraries/chain/include/graphene/chain/operations.hpp b/libraries/chain/include/graphene/chain/operations.hpp index 7c556422..232e7318 100644 --- a/libraries/chain/include/graphene/chain/operations.hpp +++ b/libraries/chain/include/graphene/chain/operations.hpp @@ -129,6 +129,25 @@ namespace graphene { namespace chain { void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), -fee); } }; + /** + * This operation will claim all initial balance objects owned by any of the addresses and + * deposit them into the deposit_to_account. + */ + struct balance_claim_operation + { + asset fee; + account_id_type deposit_to_account; + flat_set
owners; + asset total_claimed; + + account_id_type fee_payer()const { return deposit_to_account; } + void get_required_auth(flat_set& active_auth_set, flat_set&)const; + share_type calculate_fee(const fee_schedule_type& k)const { return 0; } + void validate()const; + + void get_balance_delta(balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust(fee_payer(), total_claimed-fee); } + }; + /** * @brief reserves a new ID to refer to a particular key or address. * @ingroup operations @@ -1391,7 +1410,8 @@ namespace graphene { namespace chain { vesting_balance_withdraw_operation, worker_create_operation, custom_operation, - assert_operation + assert_operation, + balance_claim_operation > operation; /// @} // operations group @@ -1623,6 +1643,7 @@ FC_REFLECT( graphene::chain::custom_operation, (fee)(payer)(required_auths)(id)( FC_REFLECT( graphene::chain::assert_operation, (fee)(fee_paying_account)(predicates)(required_auths) ) FC_REFLECT( graphene::chain::void_result, ) +FC_REFLECT( graphene::chain::balance_claim_operation, (fee)(deposit_to_account)(owners)(total_claimed) ) FC_REFLECT_TYPENAME( graphene::chain::operation ) FC_REFLECT_TYPENAME( graphene::chain::operation_result ) diff --git a/libraries/chain/include/graphene/chain/types.hpp b/libraries/chain/include/graphene/chain/types.hpp index ab99b20b..b893a0e4 100644 --- a/libraries/chain/include/graphene/chain/types.hpp +++ b/libraries/chain/include/graphene/chain/types.hpp @@ -116,6 +116,7 @@ namespace graphene { namespace chain { withdraw_permission_object_type, vesting_balance_object_type, worker_object_type, + balance_object_type, OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types }; @@ -160,6 +161,7 @@ namespace graphene { namespace chain { class vesting_balance_object; class witness_schedule_object; class worker_object; + class balance_object; typedef object_id< protocol_ids, key_object_type, key_object> key_id_type; typedef object_id< protocol_ids, account_object_type, account_object> account_id_type; @@ -175,6 +177,7 @@ namespace graphene { namespace chain { typedef object_id< protocol_ids, withdraw_permission_object_type,withdraw_permission_object> withdraw_permission_id_type; 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< relative_protocol_ids, key_object_type, key_object> relative_key_id_type; typedef object_id< relative_protocol_ids, account_object_type, account_object> relative_account_id_type; @@ -521,6 +524,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type, (withdraw_permission_object_type) (vesting_balance_object_type) (worker_object_type) + (balance_object_type) (OBJECT_TYPE_COUNT) ) FC_REFLECT_ENUM( graphene::chain::impl_object_type, diff --git a/libraries/chain/operations.cpp b/libraries/chain/operations.cpp index 65edbad3..65c84c59 100644 --- a/libraries/chain/operations.cpp +++ b/libraries/chain/operations.cpp @@ -898,4 +898,17 @@ share_type assert_operation::calculate_fee(const fee_schedule_type& k)const return std::max(size_t(1), fc::raw::pack_size(*this) / 1024) * k.assert_op_fee; } +void balance_claim_operation::get_required_auth(flat_set& active_auth_set, flat_set&)const +{ + active_auth_set.insert( fee_payer() ); +} + +void balance_claim_operation::validate()const +{ + FC_ASSERT( owners.size() > 0 ); + FC_ASSERT( total_claimed.amount > 0 ); + FC_ASSERT( fee == asset() ); +} + + } } // namespace graphene::chain diff --git a/libraries/plugins/account_history/account_history_plugin.cpp b/libraries/plugins/account_history/account_history_plugin.cpp index 4f5e763b..9928dcb3 100644 --- a/libraries/plugins/account_history/account_history_plugin.cpp +++ b/libraries/plugins/account_history/account_history_plugin.cpp @@ -184,11 +184,9 @@ struct operation_get_impacted_accounts _impacted.insert( o.owner ); } - void operator()( const worker_create_operation& )const - {} - - void operator()( const assert_operation& )const - {} + void operator()( const worker_create_operation& )const {} + void operator()( const assert_operation& )const {} + void operator()( const balance_claim_operation& )const {} };