Skip to content

Commit

Permalink
implement storage_map and account_list
Browse files Browse the repository at this point in the history
  • Loading branch information
oxarbitrage committed Aug 23, 2019
1 parent f1518aa commit 7e59910
Show file tree
Hide file tree
Showing 11 changed files with 630 additions and 21 deletions.
10 changes: 10 additions & 0 deletions libraries/app/api.cpp
Expand Up @@ -738,4 +738,14 @@ namespace graphene { namespace app {
return optional<htlc_order_object>();
}

optional<account_storage_object> custom_operations_api::get_storage_info(std::string account_id_or_name)const
{
const auto account_id = database_api.get_account_id_from_string(account_id_or_name);
auto &index = _app.chain_database()->get_index_type<account_storage_index>().indices().get<by_custom_account>();
auto itr = index.find(account_id);
if(itr != index.end())
return *itr;
return optional<account_storage_object>();
}

} } // graphene::app
9 changes: 9 additions & 0 deletions libraries/app/include/graphene/app/api.hpp
Expand Up @@ -571,6 +571,15 @@ namespace graphene { namespace app {
*/
optional<htlc_order_object> get_htlc_offer(htlc_order_id_type id)const;

/**
* @breif Get storage information of an account
*
* @param account Account name to get info from
*
* @return The storage information of the account or empty
*/
optional<account_storage_object> get_storage_info(std::string account)const;

private:
application& _app;
graphene::app::database_api database_api;
Expand Down
97 changes: 83 additions & 14 deletions libraries/plugins/custom_operations/custom_evaluators.cpp
Expand Up @@ -35,6 +35,17 @@ custom_generic_evaluator::custom_generic_evaluator(database& db, const account_i
_account = account;
}

void fill_contact_object(account_contact_object& aco, account_id_type account, const account_contact_operation& op)
{
aco.account = account;
if(op.extensions.value.name.valid()) aco.name = *op.extensions.value.name;
if(op.extensions.value.email.valid()) aco.email = *op.extensions.value.email;
if(op.extensions.value.phone.valid()) aco.phone = *op.extensions.value.phone;
if(op.extensions.value.address.valid()) aco.address = *op.extensions.value.address;
if(op.extensions.value.company.valid()) aco.company = *op.extensions.value.company;
if(op.extensions.value.url.valid()) aco.url = *op.extensions.value.url;
}

object_id_type custom_generic_evaluator::do_apply(const account_contact_operation& op)
{
auto &index = _db->get_index_type<account_contact_index>().indices().get<by_custom_account>();
Expand All @@ -43,26 +54,14 @@ object_id_type custom_generic_evaluator::do_apply(const account_contact_operatio
if( itr != index.end() )
{
_db->modify( *itr, [&op, this]( account_contact_object& aco ){
aco.account = _account;
if(op.extensions.value.name.valid()) aco.name = *op.extensions.value.name;
if(op.extensions.value.email.valid()) aco.email = *op.extensions.value.email;
if(op.extensions.value.phone.valid()) aco.phone = *op.extensions.value.phone;
if(op.extensions.value.address.valid()) aco.address = *op.extensions.value.address;
if(op.extensions.value.company.valid()) aco.company = *op.extensions.value.company;
if(op.extensions.value.url.valid()) aco.url = *op.extensions.value.url;
fill_contact_object(aco, _account, op);
});
return itr->id;
}
else
{
auto created = _db->create<account_contact_object>( [&op, this]( account_contact_object& aco ) {
aco.account = _account;
if(op.extensions.value.name.valid()) aco.name = *op.extensions.value.name;
if(op.extensions.value.email.valid()) aco.email = *op.extensions.value.email;
if(op.extensions.value.phone.valid()) aco.phone = *op.extensions.value.phone;
if(op.extensions.value.address.valid()) aco.address = *op.extensions.value.address;
if(op.extensions.value.company.valid()) aco.company = *op.extensions.value.company;
if(op.extensions.value.url.valid()) aco.url = *op.extensions.value.url;
fill_contact_object(aco, _account, op);
});
return created.id;
}
Expand Down Expand Up @@ -114,4 +113,74 @@ object_id_type custom_generic_evaluator::do_apply(const take_htlc_order_operatio
return htlc_order_id;
}

void fill_storage_map(account_storage_object& aso, account_id_type account, const account_store_data& op)
{
aso.account = account;
if(op.extensions.value.pairs.valid())
{
for(auto const& row: *op.extensions.value.pairs) {
if (op.extensions.value.remove.valid() && *op.extensions.value.remove)
aso.storage_map.erase(row.first);
else
aso.storage_map[row.first] = row.second;
}
}
}

object_id_type custom_generic_evaluator::do_apply(const account_store_data& op)
{
auto &index = _db->get_index_type<account_storage_index>().indices().get<by_custom_account>();

auto itr = index.find(_account);
if( itr != index.end() )
{
_db->modify( *itr, [&op, this]( account_storage_object& aso ) {
fill_storage_map(aso, _account, op);
});
return itr->id;
}
else
{
auto created = _db->create<account_storage_object>( [&op, this]( account_storage_object& aso ) {
fill_storage_map(aso, _account, op);
});
return created.id;
}
}

void fill_account_list(account_storage_object& aso, account_id_type account, const account_list_data& op)
{
aso.account = account;
if(op.extensions.value.accounts.valid())
{
for(auto const& account: *op.extensions.value.accounts) {
if (op.extensions.value.remove.valid() && *op.extensions.value.remove)
aso.account_list.erase(account);
else
aso.account_list.insert(account);
}
}
}

object_id_type custom_generic_evaluator::do_apply(const account_list_data& op)
{
auto &index = _db->get_index_type<account_storage_index>().indices().get<by_custom_account>();

auto itr = index.find(_account);
if( itr != index.end() )
{
_db->modify( *itr, [&op, this]( account_storage_object& aso ) {
fill_account_list(aso, _account, op);
});
return itr->id;
}
else
{
auto created = _db->create<account_storage_object>( [&op, this]( account_storage_object& aso ) {
fill_account_list(aso, _account, op);
});
return created.id;
}
}

} }
13 changes: 13 additions & 0 deletions libraries/plugins/custom_operations/custom_operations.cpp
Expand Up @@ -46,8 +46,21 @@ void take_htlc_order_operation::validate()const
FC_ASSERT(extensions.value.htlc_order_id.valid());
}

void account_store_data::validate()const
{
FC_ASSERT(extensions.value.pairs.valid());
FC_ASSERT(extensions.value.pairs->size() <= 10);
}
void account_list_data::validate()const
{
FC_ASSERT(extensions.value.accounts.valid());
FC_ASSERT(extensions.value.accounts->size() <= 10);
}

} } //graphene::custom_operations

GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_contact_operation )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::custom_operations::create_htlc_order_operation )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::custom_operations::take_htlc_order_operation )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_store_data )
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_list_data )
Expand Up @@ -115,6 +115,7 @@ void custom_operations_plugin::plugin_initialize(const boost::program_options::v
{
database().add_index< primary_index< account_contact_index > >();
database().add_index< primary_index< htlc_orderbook_index > >();
database().add_index< primary_index< account_storage_index > >();

database().applied_block.connect( [this]( const signed_block& b) {
my->onBlock(b);
Expand Down
Expand Up @@ -37,6 +37,8 @@ class custom_generic_evaluator
object_id_type do_apply(const account_contact_operation& o);
object_id_type do_apply(const create_htlc_order_operation& o);
object_id_type do_apply(const take_htlc_order_operation& o);
object_id_type do_apply(const account_store_data& o);
object_id_type do_apply(const account_list_data& o);
};

} }
Expand Down
Expand Up @@ -37,7 +37,9 @@ using namespace chain;
enum types {
account_contact = 0,
create_htlc = 1,
take_htlc = 2
take_htlc = 2,
account_store = 3,
account_list = 4
};
enum blockchains {
eos = 0,
Expand Down Expand Up @@ -83,6 +85,16 @@ struct htlc_order_object : public abstract_object<htlc_order_object>
optional<fc::time_point_sec> close_time;
};

struct account_storage_object : public abstract_object<account_storage_object>
{
static const uint8_t space_id = CUSTOM_OPERATIONS_SPACE_ID;
static const uint8_t type_id = account_store;

account_id_type account;
flat_map<string, string> storage_map;
flat_set<account_id_type> account_list;
};

struct by_custom_id;
struct by_custom_account;
typedef multi_index_container<
Expand Down Expand Up @@ -120,18 +132,32 @@ typedef multi_index_container<

typedef generic_index<htlc_order_object, htlc_orderbook_multi_index_type> htlc_orderbook_index;

typedef multi_index_container<
account_storage_object,
indexed_by<
ordered_non_unique< tag<by_custom_id>, member< object, object_id_type, &object::id > >,
ordered_unique< tag<by_custom_account>,
member< account_storage_object, account_id_type, &account_storage_object::account > >
>
> account_storage_multi_index_type;

typedef generic_index<account_storage_object, account_storage_multi_index_type> account_storage_index;

using account_contact_id_type = object_id<CUSTOM_OPERATIONS_SPACE_ID, account_contact>;
using htlc_order_id_type = object_id<CUSTOM_OPERATIONS_SPACE_ID, create_htlc>;
using account_storage_id_type = object_id<CUSTOM_OPERATIONS_SPACE_ID, account_store>;

} } //graphene::custom_operations


FC_REFLECT_DERIVED( graphene::custom_operations::account_contact_object, (graphene::db::object),
(account)(name)(email)(phone)(address)(company)(url))
FC_REFLECT_DERIVED( graphene::custom_operations::htlc_order_object, (graphene::db::object),
(bitshares_account)(bitshares_amount)(blockchain)(blockchain_account)(blockchain_asset)
(blockchain_amount)(expiration)(order_time)(active)
(blockchain_asset_precision)(token_contract)(tag)(taker_bitshares_account)
(taker_blockchain_account)(close_time))
FC_REFLECT_ENUM( graphene::custom_operations::types, (account_contact)(create_htlc)(take_htlc) )
FC_REFLECT_DERIVED( graphene::custom_operations::account_storage_object, (graphene::db::object),
(account)(storage_map)(account_list))
FC_REFLECT_ENUM( graphene::custom_operations::types, (account_contact)(create_htlc)(take_htlc)(account_store)
(account_list))
FC_REFLECT_ENUM( graphene::custom_operations::blockchains, (eos)(bitcoin)(ripple)(ethereum) )
Expand Up @@ -82,6 +82,33 @@ struct take_htlc_order_operation : chain::base_operation
void validate()const;
};

struct account_store_data : chain::base_operation
{
struct ext
{
optional<bool> remove;
optional<flat_map<string, string>> pairs;
};

graphene::protocol::extension<ext> extensions;

void validate()const;
};

struct account_list_data : chain::base_operation
{
struct ext
{
optional<bool> remove;
optional<flat_set<account_id_type>> accounts;
};

graphene::protocol::extension<ext> extensions;

void validate()const;
};


} } //graphene::custom_operations

FC_REFLECT( graphene::custom_operations::account_contact_operation::ext, (name)(email)(phone)(address)(company)(url) )
Expand All @@ -98,6 +125,17 @@ FC_REFLECT( graphene::custom_operations::take_htlc_order_operation::ext, (htlc_o
FC_REFLECT_TYPENAME( graphene::protocol::extension<graphene::custom_operations::take_htlc_order_operation::ext> )
FC_REFLECT( graphene::custom_operations::take_htlc_order_operation, (extensions) )

FC_REFLECT( graphene::custom_operations::account_store_data::ext, (pairs)(remove) )
FC_REFLECT_TYPENAME( graphene::protocol::extension<graphene::custom_operations::account_store_data::ext> )
FC_REFLECT( graphene::custom_operations::account_store_data, (extensions) )

FC_REFLECT( graphene::custom_operations::account_list_data::ext, (accounts)(remove) )
FC_REFLECT_TYPENAME( graphene::protocol::extension<graphene::custom_operations::account_list_data::ext> )
FC_REFLECT( graphene::custom_operations::account_list_data, (extensions) )

GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_contact_operation )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::custom_operations::create_htlc_order_operation )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::custom_operations::take_htlc_order_operation )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_store_data )
GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_list_data )

Expand Up @@ -56,11 +56,12 @@ class custom_operations_plugin : public graphene::app::plugin
std::unique_ptr<detail::custom_operations_plugin_impl> my;
};


typedef fc::static_variant<
account_contact_operation,
create_htlc_order_operation,
take_htlc_order_operation
take_htlc_order_operation,
account_store_data,
account_list_data
> custom_plugin_operation;

struct custom_operation_wrapper {
Expand All @@ -84,7 +85,6 @@ struct custom_op_visitor
}
};


} } //graphene::custom_operations

FC_REFLECT_TYPENAME( graphene::custom_operations::custom_plugin_operation )
Expand Down
4 changes: 3 additions & 1 deletion tests/common/database_fixture.cpp
Expand Up @@ -286,7 +286,9 @@ database_fixture::database_fixture(const fc::time_point_sec &initial_timestamp)
ahiplugin->plugin_startup();
}

if(current_test_name == "custom_operations_account_contact_test" || current_test_name == "custom_operations_htlc_bitshares_eos_test") {
if(current_test_name == "custom_operations_account_contact_test" ||
current_test_name == "custom_operations_htlc_bitshares_eos_test" ||
current_test_name == "custom_operations_account_storage_test") {
auto custom_operations_plugin = app.register_plugin<graphene::custom_operations::custom_operations_plugin>();
custom_operations_plugin->plugin_set_app(&app);
custom_operations_plugin->plugin_initialize(options);
Expand Down

0 comments on commit 7e59910

Please sign in to comment.