From 126016946ab6a22a5780677cde2d67df3ea8620e Mon Sep 17 00:00:00 2001 From: Alfredo Date: Sat, 24 Aug 2019 10:55:09 -0300 Subject: [PATCH] change underlying storage object and operations --- libraries/app/api.cpp | 16 +- libraries/app/include/graphene/app/api.hpp | 7 +- .../custom_operations/custom_evaluators.cpp | 102 +++---- .../custom_operations/custom_operations.cpp | 18 +- .../custom_operations/custom_evaluators.hpp | 4 +- .../custom_operations/custom_objects.hpp | 44 ++- .../custom_operations/custom_operations.hpp | 27 +- .../custom_operations_plugin.hpp | 4 +- tests/custom_operations/main.cpp | 267 +++++++++--------- 9 files changed, 261 insertions(+), 228 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 83edac5c6f..483179710c 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -738,14 +738,18 @@ namespace graphene { namespace app { return optional(); } - optional custom_operations_api::get_storage_info(std::string account_id_or_name)const + vector custom_operations_api::get_storage_info(std::string account_id_or_name, + std::string catalog)const { const auto account_id = database_api.get_account_id_from_string(account_id_or_name); - auto &index = _app.chain_database()->get_index_type().indices().get(); - auto itr = index.find(account_id); - if(itr != index.end()) - return *itr; - return optional(); + vector results; + auto &index = _app.chain_database()->get_index_type().indices().get(); + auto itr = index.lower_bound(make_tuple(account_id, catalog)); + while(itr != index.end() && itr->account == account_id && itr->catalog == catalog) { + results.push_back(*itr); + ++itr; + } + return results; } } } // graphene::app diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index 4650773d8d..7f39b8bfca 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -572,13 +572,14 @@ namespace graphene { namespace app { optional get_htlc_offer(htlc_order_id_type id)const; /** - * @breif Get storage information of an account + * @breif Get all stored objects of an account * * @param account Account name to get info from + * @param catalog Category classification * - * @return The storage information of the account or empty + * @return The vector of objects of the account or empty */ - optional get_storage_info(std::string account)const; + vector get_storage_info(std::string account, std::string catalog)const; private: application& _app; diff --git a/libraries/plugins/custom_operations/custom_evaluators.cpp b/libraries/plugins/custom_operations/custom_evaluators.cpp index e409aa2369..875e9019c7 100644 --- a/libraries/plugins/custom_operations/custom_evaluators.cpp +++ b/libraries/plugins/custom_operations/custom_evaluators.cpp @@ -113,73 +113,65 @@ 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) +object_id_type custom_generic_evaluator::do_apply(const account_storage_map& 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; - } - } -} + auto &index = _db->get_index_type().indices().get(); -object_id_type custom_generic_evaluator::do_apply(const account_store_data& op) -{ - auto &index = _db->get_index_type().indices().get(); - - auto itr = index.find(_account); - if( itr != index.end() ) + if (op.extensions.value.remove.valid() && *op.extensions.value.remove) { - _db->modify( *itr, [&op, this]( account_storage_object& aso ) { - fill_storage_map(aso, _account, op); - }); - return itr->id; - } - else - { - auto created = _db->create( [&op, this]( account_storage_object& aso ) { - fill_storage_map(aso, _account, op); - }); - return created.id; + for(auto const& row: *op.extensions.value.key_values) { + auto itr = index.find(make_tuple(_account, *op.extensions.value.catalog, row.first)); + if(itr != index.end()) + _db->remove(*itr); + } } -} - -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 { + for(auto const& row: *op.extensions.value.key_values) { + auto itr = index.find(make_tuple(_account, *op.extensions.value.catalog, row.first)); + if(itr == index.end()) + { + auto created = _db->create( [&op, this, &row]( account_storage_object& aso ) { + aso.catalog = *op.extensions.value.catalog; + aso.account = _account; + aso.key = row.first; + aso.value = row.second; + }); + } else - aso.account_list.insert(account); + { + _db->modify(*itr, [&op, this, &row](account_storage_object &aso) { + aso.value = row.second; + }); + } } } } - -object_id_type custom_generic_evaluator::do_apply(const account_list_data& op) +object_id_type custom_generic_evaluator::do_apply(const account_storage_list& op) { - auto &index = _db->get_index_type().indices().get(); + auto &index = _db->get_index_type().indices().get(); - auto itr = index.find(_account); - if( itr != index.end() ) + if (op.extensions.value.remove.valid() && *op.extensions.value.remove) { - _db->modify( *itr, [&op, this]( account_storage_object& aso ) { - fill_account_list(aso, _account, op); - }); - return itr->id; + for(auto const& list_value: *op.extensions.value.values) { + + auto itr = index.find(make_tuple(_account, *op.extensions.value.catalog, list_value)); + if(itr != index.end()) + _db->remove(*itr); + } } - else - { - auto created = _db->create( [&op, this]( account_storage_object& aso ) { - fill_account_list(aso, _account, op); - }); - return created.id; + else { + + for(auto const& list_value: *op.extensions.value.values) { + auto itr = index.find(make_tuple(_account, *op.extensions.value.catalog, list_value)); + if(itr == index.end()) + { + auto created = _db->create( [&op, this, &list_value]( account_storage_object& aso ) { + aso.catalog = *op.extensions.value.catalog; + aso.account = _account; + aso.value = list_value; + }); + } + } } } diff --git a/libraries/plugins/custom_operations/custom_operations.cpp b/libraries/plugins/custom_operations/custom_operations.cpp index 54176a295d..80ab429dab 100644 --- a/libraries/plugins/custom_operations/custom_operations.cpp +++ b/libraries/plugins/custom_operations/custom_operations.cpp @@ -46,15 +46,17 @@ void take_htlc_order_operation::validate()const FC_ASSERT(extensions.value.htlc_order_id.valid()); } -void account_store_data::validate()const +void account_storage_map::validate()const { - FC_ASSERT(extensions.value.pairs.valid()); - FC_ASSERT(extensions.value.pairs->size() <= 10); + FC_ASSERT(extensions.value.catalog.valid()); + FC_ASSERT(extensions.value.key_values.valid()); + FC_ASSERT(extensions.value.key_values->size() <= 10); } -void account_list_data::validate()const +void account_storage_list::validate()const { - FC_ASSERT(extensions.value.accounts.valid()); - FC_ASSERT(extensions.value.accounts->size() <= 10); + FC_ASSERT(extensions.value.catalog.valid()); + FC_ASSERT(extensions.value.values.valid()); + FC_ASSERT(extensions.value.values->size() <= 10); } } } //graphene::custom_operations @@ -62,5 +64,5 @@ void account_list_data::validate()const 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 ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_storage_map ) +GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_storage_list ) diff --git a/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_evaluators.hpp b/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_evaluators.hpp index 7f11a967c2..32a36fdae0 100644 --- a/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_evaluators.hpp +++ b/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_evaluators.hpp @@ -37,8 +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); + object_id_type do_apply(const account_storage_map& o); + object_id_type do_apply(const account_storage_list& o); }; } } diff --git a/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_objects.hpp b/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_objects.hpp index c92cda33d9..a4ac2b5093 100644 --- a/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_objects.hpp +++ b/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_objects.hpp @@ -91,8 +91,9 @@ struct account_storage_object : public abstract_object static const uint8_t type_id = account_store; account_id_type account; - flat_map storage_map; - flat_set account_list; + string catalog; + optional key; + string value; }; struct by_custom_id; @@ -132,12 +133,45 @@ typedef multi_index_container< typedef generic_index htlc_orderbook_index; +struct by_account_catalog; +struct by_account_catalog_key; +struct by_account_catalog_value; +struct by_account_catalog_key_value; + typedef multi_index_container< account_storage_object, indexed_by< ordered_non_unique< tag, member< object, object_id_type, &object::id > >, - ordered_unique< tag, - member< account_storage_object, account_id_type, &account_storage_object::account > > + ordered_non_unique< tag, + member< account_storage_object, account_id_type, &account_storage_object::account > >, + ordered_non_unique< tag, + composite_key< account_storage_object, + member< account_storage_object, account_id_type, &account_storage_object::account >, + member< account_storage_object, string, &account_storage_object::catalog > + > + >, + ordered_non_unique< tag, + composite_key< account_storage_object, + member< account_storage_object, account_id_type, &account_storage_object::account >, + member< account_storage_object, string, &account_storage_object::catalog >, + member< account_storage_object, optional, &account_storage_object::key > + > + >, + ordered_unique< tag, + composite_key< account_storage_object, + member< account_storage_object, account_id_type, &account_storage_object::account >, + member< account_storage_object, string, &account_storage_object::catalog >, + member< account_storage_object, string, &account_storage_object::value > + > + >, + ordered_unique< tag, + composite_key< account_storage_object, + member< account_storage_object, account_id_type, &account_storage_object::account >, + member< account_storage_object, string, &account_storage_object::catalog >, + member< account_storage_object, optional, &account_storage_object::key >, + member< account_storage_object, string, &account_storage_object::value > + > + > > > account_storage_multi_index_type; @@ -157,7 +191,7 @@ FC_REFLECT_DERIVED( graphene::custom_operations::htlc_order_object, (graphene::d (blockchain_asset_precision)(token_contract)(tag)(taker_bitshares_account) (taker_blockchain_account)(close_time)) FC_REFLECT_DERIVED( graphene::custom_operations::account_storage_object, (graphene::db::object), - (account)(storage_map)(account_list)) + (account)(catalog)(key)(value)) 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) ) diff --git a/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_operations.hpp b/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_operations.hpp index 1a9155ff7e..976302ce63 100644 --- a/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_operations.hpp +++ b/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_operations.hpp @@ -82,12 +82,13 @@ struct take_htlc_order_operation : chain::base_operation void validate()const; }; -struct account_store_data : chain::base_operation +struct account_storage_map : chain::base_operation { struct ext { optional remove; - optional> pairs; + optional catalog; + optional> key_values; }; graphene::protocol::extension extensions; @@ -95,12 +96,13 @@ struct account_store_data : chain::base_operation void validate()const; }; -struct account_list_data : chain::base_operation +struct account_storage_list : chain::base_operation { struct ext { optional remove; - optional> accounts; + optional catalog; + optional> values; }; graphene::protocol::extension extensions; @@ -125,17 +127,16 @@ FC_REFLECT( graphene::custom_operations::take_htlc_order_operation::ext, (htlc_o FC_REFLECT_TYPENAME( graphene::protocol::extension ) 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 ) -FC_REFLECT( graphene::custom_operations::account_store_data, (extensions) ) +FC_REFLECT( graphene::custom_operations::account_storage_map::ext, (remove)(catalog)(key_values) ) +FC_REFLECT_TYPENAME( graphene::protocol::extension ) +FC_REFLECT( graphene::custom_operations::account_storage_map, (extensions) ) -FC_REFLECT( graphene::custom_operations::account_list_data::ext, (accounts)(remove) ) -FC_REFLECT_TYPENAME( graphene::protocol::extension ) -FC_REFLECT( graphene::custom_operations::account_list_data, (extensions) ) +FC_REFLECT( graphene::custom_operations::account_storage_list::ext, (catalog)(values)(remove) ) +FC_REFLECT_TYPENAME( graphene::protocol::extension ) +FC_REFLECT( graphene::custom_operations::account_storage_list, (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 ) - +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_storage_map ) +GRAPHENE_DECLARE_EXTERNAL_SERIALIZATION( graphene::custom_operations::account_storage_list ) diff --git a/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_operations_plugin.hpp b/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_operations_plugin.hpp index b8612215b2..d9ee4cdf61 100644 --- a/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_operations_plugin.hpp +++ b/libraries/plugins/custom_operations/include/graphene/custom_operations/custom_operations_plugin.hpp @@ -60,8 +60,8 @@ typedef fc::static_variant< account_contact_operation, create_htlc_order_operation, take_htlc_order_operation, - account_store_data, - account_list_data + account_storage_map, + account_storage_list > custom_plugin_operation; struct custom_operation_wrapper { diff --git a/tests/custom_operations/main.cpp b/tests/custom_operations/main.cpp index e2b5606d8a..3916b3af57 100644 --- a/tests/custom_operations/main.cpp +++ b/tests/custom_operations/main.cpp @@ -485,17 +485,18 @@ try { transfer(committee_account, nathan_id, asset(init_balance)); transfer(committee_account, alice_id, asset(init_balance)); - // nathan adds arbitrary account data via custom operation, simulating some dapp settings in this case + // nathan adds key-value data via custom operation to a settings catalog { custom_operation op; - account_store_data store; - account_store_data::ext data; + account_storage_map store; + account_storage_map::ext data; flat_map pairs; pairs["language"] = "en"; pairs["image_url"] = "http://some.image.url/img.jpg"; - store.extensions.value.pairs = pairs; + store.extensions.value.key_values = pairs; + store.extensions.value.catalog = "settings"; auto packed = fc::raw::pack(store); packed.insert(packed.begin(), types::account_store); @@ -514,28 +515,27 @@ try { fc::usleep(fc::milliseconds(200)); // check nathan stored data with the api - account_storage_object storage_results_nathan = *custom_operations_api.get_storage_info("nathan"); - - BOOST_CHECK_EQUAL(storage_results_nathan.account.instance.value, 16 ); - auto row1 = storage_results_nathan.storage_map.find("language"); - auto row2 = storage_results_nathan.storage_map.find("image_url"); - - BOOST_CHECK_EQUAL(row1->first, "language"); - BOOST_CHECK_EQUAL(row1->second, "en"); - BOOST_CHECK_EQUAL(row2->first, "image_url"); - BOOST_CHECK_EQUAL(row2->second, "http://some.image.url/img.jpg"); - - // add accounts to account list storage + vector storage_results_nathan = custom_operations_api.get_storage_info("nathan", "settings"); + BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(*storage_results_nathan[0].key, "image_url"); + BOOST_CHECK_EQUAL(storage_results_nathan[0].value, "http://some.image.url/img.jpg"); + BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(*storage_results_nathan[1].key, "language"); + BOOST_CHECK_EQUAL(storage_results_nathan[1].value, "en"); + + // nathan add a list of accounts to storage { custom_operation op; - account_list_data list; - account_list_data::ext data; + account_storage_list list; + account_storage_list::ext data; - flat_set accounts; - accounts.insert(alice_id); - accounts.insert(robert_id); + flat_set accounts; + accounts.insert(alice.name); + accounts.insert(robert.name); - list.extensions.value.accounts = accounts; + list.extensions.value.values = accounts; + list.extensions.value.catalog = "contact_list"; auto packed = fc::raw::pack(list); packed.insert(packed.begin(), types::account_list); @@ -554,25 +554,24 @@ try { fc::usleep(fc::milliseconds(200)); // get the account list for nathan, check alice and robert are there - auto account_list_nathan = *custom_operations_api.get_storage_info("nathan"); - - BOOST_CHECK_EQUAL(account_list_nathan.account.instance.value, 16 ); - BOOST_CHECK_EQUAL(account_list_nathan.account_list.size(), 2 ); - auto itr = account_list_nathan.account_list.begin(); - BOOST_CHECK_EQUAL(itr->instance.value, alice_id.instance.value); - ++itr; - BOOST_CHECK_EQUAL(itr->instance.value, robert_id.instance.value); + storage_results_nathan = custom_operations_api.get_storage_info("nathan", "contact_list"); + BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].value, alice.name); + BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(storage_results_nathan[1].value, robert.name); // add a value into account list already there { custom_operation op; - account_list_data list; - account_list_data::ext data; + account_storage_list list; + account_storage_list::ext data; - flat_set accounts; - accounts.insert(alice_id); + flat_set accounts; + accounts.insert(alice.name); - list.extensions.value.accounts = accounts; + list.extensions.value.values = accounts; + list.extensions.value.catalog = "contact_list"; auto packed = fc::raw::pack(list); packed.insert(packed.begin(), types::account_list); @@ -591,25 +590,25 @@ try { fc::usleep(fc::milliseconds(200)); // nothing changes - account_list_nathan = *custom_operations_api.get_storage_info("nathan"); - BOOST_CHECK_EQUAL(account_list_nathan.account.instance.value, 16 ); - BOOST_CHECK_EQUAL(account_list_nathan.account_list.size(), 2 ); - itr = account_list_nathan.account_list.begin(); - BOOST_CHECK_EQUAL(itr->instance.value, alice_id.instance.value); - ++itr; - BOOST_CHECK_EQUAL(itr->instance.value, robert_id.instance.value); + storage_results_nathan = custom_operations_api.get_storage_info("nathan", "contact_list"); + BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].value, alice.name); + BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(storage_results_nathan[1].value, robert.name); // delete alice from the list { custom_operation op; - account_list_data list; - account_list_data::ext data; + account_storage_list list; + account_storage_list::ext data; - flat_set accounts; - accounts.insert(alice_id); + flat_set accounts; + accounts.insert(alice.name); - list.extensions.value.accounts = accounts; + list.extensions.value.values = accounts; list.extensions.value.remove = true; + list.extensions.value.catalog = "contact_list"; auto packed = fc::raw::pack(list); packed.insert(packed.begin(), types::account_list); @@ -628,23 +627,23 @@ try { fc::usleep(fc::milliseconds(200)); // alice gone - account_list_nathan = *custom_operations_api.get_storage_info("nathan"); - BOOST_CHECK_EQUAL(account_list_nathan.account.instance.value, 16 ); - BOOST_CHECK_EQUAL(account_list_nathan.account_list.size(), 1 ); - itr = account_list_nathan.account_list.begin(); - BOOST_CHECK_EQUAL(itr->instance.value, robert_id.instance.value); + storage_results_nathan = custom_operations_api.get_storage_info("nathan", "contact_list"); + BOOST_CHECK_EQUAL(storage_results_nathan.size(), 1 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].value, robert.name); // add and edit more stuff to the storage { custom_operation op; - account_store_data store; - account_store_data::ext data; + account_storage_map store; + account_storage_map::ext data; flat_map pairs; pairs["image_url"] = "http://new.image.url/newimg.jpg"; pairs["theme"] = "dark"; - store.extensions.value.pairs = pairs; + store.extensions.value.key_values = pairs; + store.extensions.value.catalog = "settings"; auto packed = fc::raw::pack(store); packed.insert(packed.begin(), types::account_store); @@ -662,31 +661,30 @@ try { generate_block(); fc::usleep(fc::milliseconds(200)); - // all good, image_url updated and theme added - storage_results_nathan = *custom_operations_api.get_storage_info("nathan"); - BOOST_CHECK_EQUAL(storage_results_nathan.account.instance.value, 16 ); - row1 = storage_results_nathan.storage_map.find("language"); - row2 = storage_results_nathan.storage_map.find("image_url"); - auto row3 = storage_results_nathan.storage_map.find("theme"); - - BOOST_CHECK_EQUAL(row1->first, "language"); - BOOST_CHECK_EQUAL(row1->second, "en"); - BOOST_CHECK_EQUAL(row2->first, "image_url"); - BOOST_CHECK_EQUAL(row2->second, "http://new.image.url/newimg.jpg"); - BOOST_CHECK_EQUAL(row3->first, "theme"); - BOOST_CHECK_EQUAL(row3->second, "dark"); + // check old and new stuff + storage_results_nathan = custom_operations_api.get_storage_info("nathan", "settings"); + BOOST_CHECK_EQUAL(storage_results_nathan.size(), 3 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(*storage_results_nathan[0].key, "image_url"); + BOOST_CHECK_EQUAL(storage_results_nathan[0].value, "http://new.image.url/newimg.jpg"); + BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(*storage_results_nathan[1].key, "language"); + BOOST_CHECK_EQUAL(storage_results_nathan[1].value, "en"); + BOOST_CHECK_EQUAL(*storage_results_nathan[2].key, "theme"); + BOOST_CHECK_EQUAL(storage_results_nathan[2].value, "dark"); // delete stuff from the storage { custom_operation op; - account_store_data store; - account_store_data::ext data; + account_storage_map store; + account_storage_map::ext data; flat_map pairs; pairs["theme"] = "dark"; - store.extensions.value.pairs = pairs; + store.extensions.value.key_values = pairs; store.extensions.value.remove = true; + store.extensions.value.catalog = "settings"; auto packed = fc::raw::pack(store); packed.insert(packed.begin(), types::account_store); @@ -705,27 +703,27 @@ try { fc::usleep(fc::milliseconds(200)); // theme is removed from the storage - storage_results_nathan = *custom_operations_api.get_storage_info("nathan"); - BOOST_CHECK_EQUAL(storage_results_nathan.account.instance.value, 16 ); - row1 = storage_results_nathan.storage_map.find("language"); - row2 = storage_results_nathan.storage_map.find("image_url"); - - BOOST_CHECK_EQUAL(row1->first, "language"); - BOOST_CHECK_EQUAL(row1->second, "en"); - BOOST_CHECK_EQUAL(row2->first, "image_url"); - BOOST_CHECK_EQUAL(row2->second, "http://new.image.url/newimg.jpg"); - - // delete stuff from that it is not there + storage_results_nathan = custom_operations_api.get_storage_info("nathan", "settings"); + BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(*storage_results_nathan[0].key, "image_url"); + BOOST_CHECK_EQUAL(storage_results_nathan[0].value, "http://new.image.url/newimg.jpg"); + BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(*storage_results_nathan[1].key, "language"); + BOOST_CHECK_EQUAL(storage_results_nathan[1].value, "en"); + + // delete stuff that it is not there { custom_operation op; - account_store_data store; - account_store_data::ext data; + account_storage_map store; + account_storage_map::ext data; flat_map pairs; pairs["nothere"] = "nothere"; - store.extensions.value.pairs = pairs; + store.extensions.value.key_values = pairs; store.extensions.value.remove = true; + store.extensions.value.catalog = "settings"; auto packed = fc::raw::pack(store); packed.insert(packed.begin(), types::account_store); @@ -744,21 +742,20 @@ try { fc::usleep(fc::milliseconds(200)); // nothing changes - storage_results_nathan = *custom_operations_api.get_storage_info("nathan"); - BOOST_CHECK_EQUAL(storage_results_nathan.account.instance.value, 16 ); - row1 = storage_results_nathan.storage_map.find("language"); - row2 = storage_results_nathan.storage_map.find("image_url"); - - BOOST_CHECK_EQUAL(row1->first, "language"); - BOOST_CHECK_EQUAL(row1->second, "en"); - BOOST_CHECK_EQUAL(row2->first, "image_url"); - BOOST_CHECK_EQUAL(row2->second, "http://new.image.url/newimg.jpg"); + storage_results_nathan = custom_operations_api.get_storage_info("nathan", "settings"); + BOOST_CHECK_EQUAL(storage_results_nathan.size(), 2 ); + BOOST_CHECK_EQUAL(storage_results_nathan[0].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(*storage_results_nathan[0].key, "image_url"); + BOOST_CHECK_EQUAL(storage_results_nathan[0].value, "http://new.image.url/newimg.jpg"); + BOOST_CHECK_EQUAL(storage_results_nathan[1].account.instance.value, 16 ); + BOOST_CHECK_EQUAL(*storage_results_nathan[1].key, "language"); + BOOST_CHECK_EQUAL(storage_results_nathan[1].value, "en"); // add more than 10 storage items in 1 operation is not allowed { custom_operation op; - account_store_data store; - account_store_data::ext data; + account_storage_map store; + account_storage_map::ext data; flat_map pairs; pairs["key1"] = "value1"; @@ -773,7 +770,8 @@ try { pairs["key10"] = "value10"; pairs["key11"] = "value11"; - store.extensions.value.pairs = pairs; + store.extensions.value.key_values = pairs; + store.extensions.value.catalog = "settings"; auto packed = fc::raw::pack(store); packed.insert(packed.begin(), types::account_store); @@ -794,23 +792,24 @@ try { // add more than 10 accounts to the list in 1 operation is not allowed { custom_operation op; - account_list_data list; - account_list_data::ext data; - - flat_set accounts; - accounts.insert(account_id_type(0)); - accounts.insert(account_id_type(1)); - accounts.insert(account_id_type(2)); - accounts.insert(account_id_type(3)); - accounts.insert(account_id_type(4)); - accounts.insert(account_id_type(5)); - accounts.insert(account_id_type(6)); - accounts.insert(account_id_type(7)); - accounts.insert(account_id_type(8)); - accounts.insert(account_id_type(9)); - accounts.insert(account_id_type(10)); - - list.extensions.value.accounts = accounts; + account_storage_list list; + account_storage_list::ext data; + + flat_set accounts; + accounts.insert("init0"); + accounts.insert("init1"); + accounts.insert("init2"); + accounts.insert("init3"); + accounts.insert("init4"); + accounts.insert("init5"); + accounts.insert("init6"); + accounts.insert("init7"); + accounts.insert("init8"); + accounts.insert("init9"); + accounts.insert("init10"); + + list.extensions.value.values = accounts; + list.extensions.value.catalog = "contact_list"; list.extensions.value.remove = true; auto packed = fc::raw::pack(list); @@ -832,14 +831,15 @@ try { // alice, duplicated keys in storage, only second value will be added { custom_operation op; - account_store_data store; - account_store_data::ext data; + account_storage_map store; + account_storage_map::ext data; flat_map pairs; pairs["key1"] = "value1"; pairs["key1"] = "value2"; - store.extensions.value.pairs = pairs; + store.extensions.value.key_values = pairs; + store.extensions.value.catalog = "random"; auto packed = fc::raw::pack(store); packed.insert(packed.begin(), types::account_store); @@ -857,24 +857,24 @@ try { generate_block(); fc::usleep(fc::milliseconds(200)); - auto storage_results_alice = *custom_operations_api.get_storage_info("alice"); - BOOST_CHECK_EQUAL(storage_results_alice.account.instance.value, 17 ); - row1 = storage_results_alice.storage_map.find("key1"); - - BOOST_CHECK_EQUAL(row1->first, "key1"); - BOOST_CHECK_EQUAL(row1->second, "value2"); + vector storage_results_alice = custom_operations_api.get_storage_info("alice", "random"); + BOOST_CHECK_EQUAL(storage_results_alice.size(), 1 ); + BOOST_CHECK_EQUAL(storage_results_alice[0].account.instance.value, 17 ); + BOOST_CHECK_EQUAL(*storage_results_alice[0].key, "key1"); + BOOST_CHECK_EQUAL(storage_results_alice[0].value, "value2"); // duplicated accounts in the list, only 1 will be inserted { custom_operation op; - account_list_data list; - account_list_data::ext data; + account_storage_list list; + account_storage_list::ext data; - flat_set accounts; - accounts.insert(robert_id); - accounts.insert(robert_id); + flat_set accounts; + accounts.insert(robert.name); + accounts.insert(robert.name); - list.extensions.value.accounts = accounts; + list.extensions.value.values = accounts; + list.extensions.value.catalog = "contact_list"; auto packed = fc::raw::pack(list); packed.insert(packed.begin(), types::account_list); @@ -892,11 +892,10 @@ try { generate_block(); fc::usleep(fc::milliseconds(200)); - auto account_list_alice = *custom_operations_api.get_storage_info("alice"); - BOOST_CHECK_EQUAL(account_list_alice.account.instance.value, 17 ); - BOOST_CHECK_EQUAL(account_list_alice.account_list.size(), 1 ); - itr = account_list_nathan.account_list.begin(); - BOOST_CHECK_EQUAL(itr->instance.value, robert_id.instance.value); + storage_results_alice = custom_operations_api.get_storage_info("alice", "contact_list"); + BOOST_CHECK_EQUAL(storage_results_alice.size(), 1 ); + BOOST_CHECK_EQUAL(storage_results_alice[0].account.instance.value, 17 ); + BOOST_CHECK_EQUAL(storage_results_alice[0].value, robert.name); } catch (fc::exception &e) {