From 1c5bcc10213009e7e60c9f9b68d387028c0fa9b7 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 4 Jun 2018 13:40:18 -0500 Subject: [PATCH 1/8] Adding index on short_backing_asset --- .../include/graphene/chain/asset_object.hpp | 14 +- tests/common/database_fixture.hpp | 7 +- tests/tests/bitasset_tests2.cpp | 135 ++++++++++++++++++ 3 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 tests/tests/bitasset_tests2.cpp diff --git a/libraries/chain/include/graphene/chain/asset_object.hpp b/libraries/chain/include/graphene/chain/asset_object.hpp index b37f5a5b0f..99344afa92 100644 --- a/libraries/chain/include/graphene/chain/asset_object.hpp +++ b/libraries/chain/include/graphene/chain/asset_object.hpp @@ -224,10 +224,22 @@ namespace graphene { namespace chain { void update_median_feeds(time_point_sec current_time); }; + // key extractor for short backing asset + struct bitasset_short_backing_asset_extractor + { + typedef asset_id_type result_type; + result_type operator() (const asset_bitasset_data_object& obj) const + { + return obj.options.short_backing_asset; + } + }; + + struct by_short_backing_asset; typedef multi_index_container< asset_bitasset_data_object, indexed_by< - ordered_unique< tag, member< object, object_id_type, &object::id > > + ordered_unique< tag, member< object, object_id_type, &object::id > >, + ordered_non_unique< tag, bitasset_short_backing_asset_extractor > > > asset_bitasset_data_object_multi_index_type; typedef generic_index asset_bitasset_data_index; diff --git a/tests/common/database_fixture.hpp b/tests/common/database_fixture.hpp index cf60b08872..c81d170848 100644 --- a/tests/common/database_fixture.hpp +++ b/tests/common/database_fixture.hpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -127,17 +128,17 @@ extern uint32_t GRAPHENE_TESTING_GENESIS_TIMESTAMP; #define PREP_ACTOR(name) \ fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); \ - public_key_type name ## _public_key = name ## _private_key.get_public_key(); + graphene::chain::public_key_type name ## _public_key = name ## _private_key.get_public_key(); #define ACTOR(name) \ PREP_ACTOR(name) \ const auto& name = create_account(BOOST_PP_STRINGIZE(name), name ## _public_key); \ - account_id_type name ## _id = name.id; (void)name ## _id; + graphene::chain::account_id_type name ## _id = name.id; (void)name ## _id; #define GET_ACTOR(name) \ fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); \ const account_object& name = get_account(BOOST_PP_STRINGIZE(name)); \ - account_id_type name ## _id = name.id; \ + graphene::chain::account_id_type name ## _id = name.id; \ (void)name ##_id #define ACTORS_IMPL(r, data, elem) ACTOR(elem) diff --git a/tests/tests/bitasset_tests2.cpp b/tests/tests/bitasset_tests2.cpp new file mode 100644 index 0000000000..96e5207aaa --- /dev/null +++ b/tests/tests/bitasset_tests2.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2018 Bitshares Foundation, and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include + +#include + +#include + +#include "../common/database_fixture.hpp" +#include + +BOOST_FIXTURE_TEST_SUITE( bitasset_tests, graphene::chain::database_fixture ) + +void change_backing_asset(graphene::chain::database_fixture& fixture, const fc::ecc::private_key& signing_key, + const graphene::chain::asset_object& asset_to_update, graphene::chain::asset_id_type new_backing_asset_id) +{ + graphene::chain::asset_update_bitasset_operation ba_op; + ba_op.asset_to_update = asset_to_update.get_id(); + ba_op.issuer = asset_to_update.issuer; + ba_op.new_options.short_backing_asset = new_backing_asset_id; + fixture.trx.operations.push_back(ba_op); + fixture.sign(fixture.trx, signing_key); + PUSH_TX(fixture.db, fixture.trx, ~0); + fixture.generate_block(); + fixture.trx.clear(); +} + +const graphene::chain::asset_object& create_bitasset_backed(graphene::chain::database_fixture& fixture, + int index, graphene::chain::asset_id_type backing, const fc::ecc::private_key& signing_key) +{ + // create the coin + std::string name = "COIN" + std::to_string(index + 1) + "TEST"; + const graphene::chain::asset_object& obj = fixture.create_bitasset(name); + // adjust the backing asset + change_backing_asset(fixture, signing_key, obj, backing); + fixture.trx.set_expiration(fixture.db.get_dynamic_global_properties().next_maintenance_time); + return obj; +} + +BOOST_AUTO_TEST_CASE( bitasset_secondary_index ) +{ + ACTORS( (nathan) ); + + graphene::chain::asset_id_type core_id; + BOOST_TEST_MESSAGE("Create coins"); + try + { + // make 5 coins (backed by core) + for(int i = 0; i < 5; i++) + { + create_bitasset_backed(*this, i, core_id, nathan_private_key); + } + // make the next 5 (10-14) be backed by COIN1 + graphene::chain::asset_id_type coin1_id = get_asset("COIN1TEST").get_id(); + for(int i = 5; i < 10; i++) + { + create_bitasset_backed(*this, i, coin1_id, nathan_private_key); + } + // make the next 5 (15-19) be backed by COIN2 + graphene::chain::asset_id_type coin2_id = get_asset("COIN2TEST").get_id(); + for(int i = 10; i < 15; i++) + { + create_bitasset_backed(*this, i, coin2_id, nathan_private_key); + } + // make the last 5 be backed by core + for(int i = 15; i < 20; i++) + { + create_bitasset_backed(*this, i, core_id, nathan_private_key); + } + + BOOST_TEST_MESSAGE("Searching for all coins backed by CORE"); + const auto& idx = db.get_index_type().indices().get(); + auto core_itr = idx.find( core_id ); + auto core_end = idx.upper_bound(core_id); + BOOST_TEST_MESSAGE("Searching for all coins backed by COIN1"); + auto coin1_itr = idx.find( coin1_id ); + auto coin1_end = idx.upper_bound( coin1_id ); + BOOST_TEST_MESSAGE("Searching for all coins backed by COIN2"); + auto coin2_itr = idx.find( coin2_id ); + + int core_count = 0, coin1_count = 0, coin2_count = 0; + + BOOST_TEST_MESSAGE("Counting coins in each category"); + + for( ; core_itr != core_end; ++core_itr) + { + BOOST_CHECK(core_itr->options.short_backing_asset == core_id); + core_count++; + } + for( ; coin1_itr != coin1_end; ++coin1_itr ) + { + BOOST_CHECK(coin1_itr->options.short_backing_asset == coin1_id); + coin1_count++; + } + for( ; coin2_itr != idx.end(); ++coin2_itr ) + { + BOOST_CHECK(coin2_itr->options.short_backing_asset == coin2_id); + coin2_count++; + } + + BOOST_CHECK_EQUAL(core_count, 10); + BOOST_CHECK_EQUAL(coin1_count, 5); + BOOST_CHECK_EQUAL(coin2_count, 5); + } + catch (fc::exception& ex) + { + BOOST_FAIL(ex.to_string(fc::log_level(fc::log_level::all))); + } +} + +BOOST_AUTO_TEST_SUITE_END() From 25b3548e15df85ed227febb3c4ea47dbaecc447b Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 15 Jun 2018 14:36:09 -0500 Subject: [PATCH 2/8] Use new index to iterate through assets backed by a certain asset. --- libraries/chain/asset_evaluator.cpp | 11 ++- tests/tests/bitasset_tests.cpp | 94 ++++++++++++++++++- tests/tests/bitasset_tests2.cpp | 135 ---------------------------- 3 files changed, 100 insertions(+), 140 deletions(-) delete mode 100644 tests/tests/bitasset_tests2.cpp diff --git a/libraries/chain/asset_evaluator.cpp b/libraries/chain/asset_evaluator.cpp index 2a8b5019f9..cf7dd6da6a 100644 --- a/libraries/chain/asset_evaluator.cpp +++ b/libraries/chain/asset_evaluator.cpp @@ -378,12 +378,15 @@ void check_children_of_bitasset(database& d, const asset_update_bitasset_operati return; // loop through all assets that have this asset as a backing asset - const auto& idx = d.get_index_type().indices().get(); + const auto& idx = d.get_index_type().indices().get(); + auto backed_by_itr = idx.find( new_backing_asset.get_id() ); + auto backed_end = idx.upper_bound( new_backing_asset.get_id() ); - for( auto itr = idx.lower_bound(true); itr != idx.end(); ++itr ) + for( ; backed_by_itr != backed_end; ++backed_by_itr ) { - const auto& child = *itr; - if ( child.bitasset_data(d).options.short_backing_asset == op.asset_to_update ) + const auto& bitasset_data = *backed_by_itr; + const auto& child = bitasset_data.asset_id(d); + if ( bitasset_data.options.short_backing_asset == op.asset_to_update ) { if ( after_hf_922_931 ) { diff --git a/tests/tests/bitasset_tests.cpp b/tests/tests/bitasset_tests.cpp index bcb4366e70..b7df6f0920 100644 --- a/tests/tests/bitasset_tests.cpp +++ b/tests/tests/bitasset_tests.cpp @@ -80,7 +80,7 @@ void change_backing_asset(database_fixture& fixture, const fc::ecc::private_key& } /****** - * @ brief helper method to turn witness_fed_asset on and off + * @brief helper method to turn witness_fed_asset on and off * @param fixture the database_fixture * @param new_issuer optionally change the issuer * @param signing_key signer @@ -115,6 +115,26 @@ void change_asset_options(database_fixture& fixture, const optional().indices().get(); + auto core_itr = idx.find( core_id ); + auto core_end = idx.upper_bound(core_id); + BOOST_TEST_MESSAGE("Searching for all coins backed by COIN1"); + auto coin1_itr = idx.find( coin1_id ); + auto coin1_end = idx.upper_bound( coin1_id ); + BOOST_TEST_MESSAGE("Searching for all coins backed by COIN2"); + auto coin2_itr = idx.find( coin2_id ); + + int core_count = 0, coin1_count = 0, coin2_count = 0; + + BOOST_TEST_MESSAGE("Counting coins in each category"); + + for( ; core_itr != core_end; ++core_itr) + { + BOOST_CHECK(core_itr->options.short_backing_asset == core_id); + core_count++; + } + for( ; coin1_itr != coin1_end; ++coin1_itr ) + { + BOOST_CHECK(coin1_itr->options.short_backing_asset == coin1_id); + coin1_count++; + } + for( ; coin2_itr != idx.end(); ++coin2_itr ) + { + BOOST_CHECK(coin2_itr->options.short_backing_asset == coin2_id); + coin2_count++; + } + + BOOST_CHECK_EQUAL(core_count, 10); + BOOST_CHECK_EQUAL(coin1_count, 5); + BOOST_CHECK_EQUAL(coin2_count, 5); + } + catch (fc::exception& ex) + { + BOOST_FAIL(ex.to_string(fc::log_level(fc::log_level::all))); + } +} + + /***** * @brief make sure feeds work correctly after changing from non-witness-fed to witness-fed before the 868 fork * NOTE: This test case is a different issue than what is currently being worked on, and fails. Hopefully it diff --git a/tests/tests/bitasset_tests2.cpp b/tests/tests/bitasset_tests2.cpp deleted file mode 100644 index 96e5207aaa..0000000000 --- a/tests/tests/bitasset_tests2.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2018 Bitshares Foundation, and contributors. - * - * The MIT License - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include - -#include - -#include - -#include "../common/database_fixture.hpp" -#include - -BOOST_FIXTURE_TEST_SUITE( bitasset_tests, graphene::chain::database_fixture ) - -void change_backing_asset(graphene::chain::database_fixture& fixture, const fc::ecc::private_key& signing_key, - const graphene::chain::asset_object& asset_to_update, graphene::chain::asset_id_type new_backing_asset_id) -{ - graphene::chain::asset_update_bitasset_operation ba_op; - ba_op.asset_to_update = asset_to_update.get_id(); - ba_op.issuer = asset_to_update.issuer; - ba_op.new_options.short_backing_asset = new_backing_asset_id; - fixture.trx.operations.push_back(ba_op); - fixture.sign(fixture.trx, signing_key); - PUSH_TX(fixture.db, fixture.trx, ~0); - fixture.generate_block(); - fixture.trx.clear(); -} - -const graphene::chain::asset_object& create_bitasset_backed(graphene::chain::database_fixture& fixture, - int index, graphene::chain::asset_id_type backing, const fc::ecc::private_key& signing_key) -{ - // create the coin - std::string name = "COIN" + std::to_string(index + 1) + "TEST"; - const graphene::chain::asset_object& obj = fixture.create_bitasset(name); - // adjust the backing asset - change_backing_asset(fixture, signing_key, obj, backing); - fixture.trx.set_expiration(fixture.db.get_dynamic_global_properties().next_maintenance_time); - return obj; -} - -BOOST_AUTO_TEST_CASE( bitasset_secondary_index ) -{ - ACTORS( (nathan) ); - - graphene::chain::asset_id_type core_id; - BOOST_TEST_MESSAGE("Create coins"); - try - { - // make 5 coins (backed by core) - for(int i = 0; i < 5; i++) - { - create_bitasset_backed(*this, i, core_id, nathan_private_key); - } - // make the next 5 (10-14) be backed by COIN1 - graphene::chain::asset_id_type coin1_id = get_asset("COIN1TEST").get_id(); - for(int i = 5; i < 10; i++) - { - create_bitasset_backed(*this, i, coin1_id, nathan_private_key); - } - // make the next 5 (15-19) be backed by COIN2 - graphene::chain::asset_id_type coin2_id = get_asset("COIN2TEST").get_id(); - for(int i = 10; i < 15; i++) - { - create_bitasset_backed(*this, i, coin2_id, nathan_private_key); - } - // make the last 5 be backed by core - for(int i = 15; i < 20; i++) - { - create_bitasset_backed(*this, i, core_id, nathan_private_key); - } - - BOOST_TEST_MESSAGE("Searching for all coins backed by CORE"); - const auto& idx = db.get_index_type().indices().get(); - auto core_itr = idx.find( core_id ); - auto core_end = idx.upper_bound(core_id); - BOOST_TEST_MESSAGE("Searching for all coins backed by COIN1"); - auto coin1_itr = idx.find( coin1_id ); - auto coin1_end = idx.upper_bound( coin1_id ); - BOOST_TEST_MESSAGE("Searching for all coins backed by COIN2"); - auto coin2_itr = idx.find( coin2_id ); - - int core_count = 0, coin1_count = 0, coin2_count = 0; - - BOOST_TEST_MESSAGE("Counting coins in each category"); - - for( ; core_itr != core_end; ++core_itr) - { - BOOST_CHECK(core_itr->options.short_backing_asset == core_id); - core_count++; - } - for( ; coin1_itr != coin1_end; ++coin1_itr ) - { - BOOST_CHECK(coin1_itr->options.short_backing_asset == coin1_id); - coin1_count++; - } - for( ; coin2_itr != idx.end(); ++coin2_itr ) - { - BOOST_CHECK(coin2_itr->options.short_backing_asset == coin2_id); - coin2_count++; - } - - BOOST_CHECK_EQUAL(core_count, 10); - BOOST_CHECK_EQUAL(coin1_count, 5); - BOOST_CHECK_EQUAL(coin2_count, 5); - } - catch (fc::exception& ex) - { - BOOST_FAIL(ex.to_string(fc::log_level(fc::log_level::all))); - } -} - -BOOST_AUTO_TEST_SUITE_END() From 6a7b9b06a490669c0db06fae5febaf3ae9011b1a Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 15 Jun 2018 20:36:10 -0500 Subject: [PATCH 3/8] Use the new index to find assets that are backed by this asset. --- libraries/chain/asset_evaluator.cpp | 81 +++++++------- tests/tests/bitasset_tests.cpp | 157 +++++++++++++++------------- 2 files changed, 124 insertions(+), 114 deletions(-) diff --git a/libraries/chain/asset_evaluator.cpp b/libraries/chain/asset_evaluator.cpp index cf7dd6da6a..8c177970d5 100644 --- a/libraries/chain/asset_evaluator.cpp +++ b/libraries/chain/asset_evaluator.cpp @@ -379,56 +379,59 @@ void check_children_of_bitasset(database& d, const asset_update_bitasset_operati // loop through all assets that have this asset as a backing asset const auto& idx = d.get_index_type().indices().get(); - auto backed_by_itr = idx.find( new_backing_asset.get_id() ); - auto backed_end = idx.upper_bound( new_backing_asset.get_id() ); - - for( ; backed_by_itr != backed_end; ++backed_by_itr ) + auto backed_by_itr = idx.find( op.asset_to_update ); + if ( backed_by_itr != idx.end() ) // if we found at least 1 { - const auto& bitasset_data = *backed_by_itr; - const auto& child = bitasset_data.asset_id(d); - if ( bitasset_data.options.short_backing_asset == op.asset_to_update ) + auto backed_end = idx.upper_bound( new_backing_asset.get_id() ); + + for( ; backed_by_itr != backed_end; ++backed_by_itr ) { - if ( after_hf_922_931 ) + const auto& bitasset_data = *backed_by_itr; + const auto& child = bitasset_data.asset_id(d); + if ( bitasset_data.options.short_backing_asset == op.asset_to_update ) { - FC_ASSERT( child.get_id() != op.new_options.short_backing_asset, - "A BitAsset would be invalidated by changing this backing asset ('A' backed by 'B' backed by 'A')." ); + if ( after_hf_922_931 ) + { + FC_ASSERT( child.get_id() != op.new_options.short_backing_asset, + "A BitAsset would be invalidated by changing this backing asset ('A' backed by 'B' backed by 'A')." ); - FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT, - "A blockchain-controlled market asset would be invalidated by changing this backing asset." ); + FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT, + "A blockchain-controlled market asset would be invalidated by changing this backing asset." ); - FC_ASSERT( !new_backing_asset.is_market_issued(), - "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset."); + FC_ASSERT( !new_backing_asset.is_market_issued(), + "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset."); - } - else - { - if( child.get_id() == op.new_options.short_backing_asset ) - { - wlog( "Before hf-922-931, modified an asset to be backed by another, but would cause a continuous " - "loop. A cannot be backed by B which is backed by A." ); - return; - } - - if( child.issuer == GRAPHENE_COMMITTEE_ACCOUNT ) - { - wlog( "before hf-922-931, modified an asset to be backed by a non-CORE, but this asset " - "is a backing asset for a committee-issued asset. This occurred at block ${b}", - ("b", d.head_block_num())); - return; } else { - if ( new_backing_asset.is_market_issued() ) { // a.k.a. !UIA - wlog( "before hf-922-931, modified an asset to be backed by an MPA, but this asset " - "is a backing asset for another MPA, which would cause MPA backed by MPA backed by MPA. " - "This occurred at block ${b}", - ("b", d.head_block_num())); + if( child.get_id() == op.new_options.short_backing_asset ) + { + wlog( "Before hf-922-931, modified an asset to be backed by another, but would cause a continuous " + "loop. A cannot be backed by B which is backed by A." ); + return; + } + + if( child.issuer == GRAPHENE_COMMITTEE_ACCOUNT ) + { + wlog( "before hf-922-931, modified an asset to be backed by a non-CORE, but this asset " + "is a backing asset for a committee-issued asset. This occurred at block ${b}", + ("b", d.head_block_num())); return; } - } // if child.issuer - } // if hf 922/931 - } // if this child is backed by the asset being adjusted - } // for each asset + else + { + if ( new_backing_asset.is_market_issued() ) { // a.k.a. !UIA + wlog( "before hf-922-931, modified an asset to be backed by an MPA, but this asset " + "is a backing asset for another MPA, which would cause MPA backed by MPA backed by MPA. " + "This occurred at block ${b}", + ("b", d.head_block_num())); + return; + } + } // if child.issuer + } // if hf 922/931 + } // if this child is backed by the asset being adjusted + } // for each asset + } // if this asset is backing another asset } // check_children_of_bitasset void_result asset_update_bitasset_evaluator::do_evaluate(const asset_update_bitasset_operation& op) diff --git a/tests/tests/bitasset_tests.cpp b/tests/tests/bitasset_tests.cpp index b7df6f0920..9711faed6b 100644 --- a/tests/tests/bitasset_tests.cpp +++ b/tests/tests/bitasset_tests.cpp @@ -128,8 +128,9 @@ const graphene::chain::asset_object& create_bitasset_backed(graphene::chain::dat // create the coin std::string name = "COIN" + std::to_string(index + 1) + "TEST"; const graphene::chain::asset_object& obj = fixture.create_bitasset(name); + asset_id_type asset_id = obj.get_id(); // adjust the backing asset - change_backing_asset(fixture, signing_key, obj.get_id(), backing); + change_backing_asset(fixture, signing_key, asset_id, backing); fixture.trx.set_expiration(fixture.db.get_dynamic_global_properties().next_maintenance_time); return obj; } @@ -573,48 +574,48 @@ class bitasset_evaluator_wrapper : public asset_update_bitasset_evaluator struct assets_922_931 { - const asset_object* bit_usd; - const asset_object* bit_usdbacked; - const asset_object* bit_usdbacked2; - const asset_object* bit_child_bitasset; - const asset_object* bit_parent; - const asset_object* user_issued; - const asset_object* six_precision; - const asset_object* prediction; + asset_id_type bit_usd; + asset_id_type bit_usdbacked; + asset_id_type bit_usdbacked2; + asset_id_type bit_child_bitasset; + asset_id_type bit_parent; + asset_id_type user_issued; + asset_id_type six_precision; + asset_id_type prediction; }; assets_922_931 create_assets_922_931(database_fixture* fixture) { assets_922_931 asset_objs; BOOST_TEST_MESSAGE( "Create USDBIT" ); - asset_objs.bit_usd = &fixture->create_bitasset( "USDBIT", GRAPHENE_COMMITTEE_ACCOUNT ); + asset_objs.bit_usd = fixture->create_bitasset( "USDBIT", GRAPHENE_COMMITTEE_ACCOUNT ).get_id(); BOOST_TEST_MESSAGE( "Create USDBACKED" ); - asset_objs.bit_usdbacked = &fixture->create_bitasset( "USDBACKED", GRAPHENE_COMMITTEE_ACCOUNT, - 100, charge_market_fee, 2, asset_objs.bit_usd->get_id() ); + asset_objs.bit_usdbacked = fixture->create_bitasset( "USDBACKED", GRAPHENE_COMMITTEE_ACCOUNT, + 100, charge_market_fee, 2, asset_objs.bit_usd ).get_id(); BOOST_TEST_MESSAGE( "Create USDBACKEDII" ); - asset_objs.bit_usdbacked2 = &fixture->create_bitasset( "USDBACKEDII", GRAPHENE_WITNESS_ACCOUNT, - 100, charge_market_fee, 2, asset_objs.bit_usd->get_id() ); + asset_objs.bit_usdbacked2 = fixture->create_bitasset( "USDBACKEDII", GRAPHENE_WITNESS_ACCOUNT, + 100, charge_market_fee, 2, asset_objs.bit_usd ).get_id(); BOOST_TEST_MESSAGE( "Create PARENT" ); - asset_objs.bit_parent = &fixture->create_bitasset( "PARENT", GRAPHENE_WITNESS_ACCOUNT); + asset_objs.bit_parent = fixture->create_bitasset( "PARENT", GRAPHENE_WITNESS_ACCOUNT).get_id(); BOOST_TEST_MESSAGE( "Create CHILDUSER" ); - asset_objs.bit_child_bitasset = &fixture->create_bitasset( "CHILDUSER", GRAPHENE_WITNESS_ACCOUNT, - 100, charge_market_fee, 2, asset_objs.bit_parent->get_id() ); + asset_objs.bit_child_bitasset = fixture->create_bitasset( "CHILDUSER", GRAPHENE_WITNESS_ACCOUNT, + 100, charge_market_fee, 2, asset_objs.bit_parent ).get_id(); BOOST_TEST_MESSAGE( "Create user issued USERISSUED" ); - asset_objs.user_issued = &fixture->create_user_issued_asset( "USERISSUED", - GRAPHENE_WITNESS_ACCOUNT(fixture->db), charge_market_fee ); + asset_objs.user_issued = fixture->create_user_issued_asset( "USERISSUED", + GRAPHENE_WITNESS_ACCOUNT(fixture->db), charge_market_fee ).get_id(); BOOST_TEST_MESSAGE( "Create a user-issued asset with a precision of 6" ); - asset_objs.six_precision = &fixture->create_user_issued_asset( "SIXPRECISION", GRAPHENE_WITNESS_ACCOUNT(fixture->db), - charge_market_fee, price(asset(1, asset_id_type(1)), asset(1)), 6 ); + asset_objs.six_precision = fixture->create_user_issued_asset( "SIXPRECISION", GRAPHENE_WITNESS_ACCOUNT(fixture->db), + charge_market_fee, price(asset(1, asset_id_type(1)), asset(1)), 6 ).get_id(); BOOST_TEST_MESSAGE( "Create Prediction market with precision of 6, backed by SIXPRECISION" ); - asset_objs.prediction = &fixture->create_prediction_market( "PREDICTION", GRAPHENE_WITNESS_ACCOUNT, - 100, charge_market_fee, 6, asset_objs.six_precision->get_id() ); + asset_objs.prediction = fixture->create_prediction_market( "PREDICTION", GRAPHENE_WITNESS_ACCOUNT, + 100, charge_market_fee, 6, asset_objs.six_precision ).get_id(); return asset_objs; } @@ -631,15 +632,15 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_before_922_931 ) ACTORS( (nathan) (john) ); assets_922_931 asset_objs = create_assets_922_931( this ); - const asset_id_type bit_usd_id = asset_objs.bit_usd->get_id(); + const asset_id_type bit_usd_id = asset_objs.bit_usd; // make a generic operation bitasset_evaluator_wrapper evaluator; evaluator.set_db(db); asset_update_bitasset_operation op; op.asset_to_update = bit_usd_id; - op.issuer = asset_objs.bit_usd->issuer; - op.new_options = asset_objs.bit_usd->bitasset_data(db).options; + op.issuer = asset_objs.bit_usd(db).issuer; + op.new_options = asset_objs.bit_usd(db).bitasset_data(db).options; // this should pass BOOST_TEST_MESSAGE( "Evaluating a good operation" ); @@ -647,7 +648,7 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_before_922_931 ) // test with a market issued asset BOOST_TEST_MESSAGE( "Sending a non-bitasset." ); - op.asset_to_update = asset_objs.user_issued->get_id(); + op.asset_to_update = asset_objs.user_issued; REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "on a non-BitAsset." ); op.asset_to_update = bit_usd_id; @@ -677,19 +678,19 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_before_922_931 ) // prediction market with different precision BOOST_TEST_MESSAGE( "Message should contain: for a PM, asset_obj.precision != new_backing_asset.precision" ); - op.asset_to_update = asset_objs.prediction->get_id(); - op.issuer = asset_objs.prediction->issuer; + op.asset_to_update = asset_objs.prediction; + op.issuer = asset_objs.prediction(db).issuer; BOOST_CHECK( evaluator.evaluate(op) == void_result() ); op.asset_to_update = bit_usd_id; - op.issuer = asset_objs.bit_usd->issuer; + op.issuer = asset_objs.bit_usd(db).issuer; // checking old backing asset instead of new backing asset BOOST_TEST_MESSAGE( "Message should contain: to be backed by an asset which is not market issued asset nor CORE" ); - op.new_options.short_backing_asset = asset_objs.six_precision->get_id(); + op.new_options.short_backing_asset = asset_objs.six_precision; BOOST_CHECK( evaluator.evaluate(op) == void_result() ); BOOST_TEST_MESSAGE( "Message should contain: modified a blockchain-controlled market asset to be backed by an asset " "which is not backed by CORE" ); - op.new_options.short_backing_asset = asset_objs.prediction->get_id(); + op.new_options.short_backing_asset = asset_objs.prediction; BOOST_CHECK( evaluator.evaluate(op) == void_result() ); op.new_options.short_backing_asset = correct_asset_id; @@ -698,30 +699,30 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_before_922_931 ) // because that will make CHILD be backed by an asset that is not itself backed by CORE or a UIA. BOOST_TEST_MESSAGE( "Message should contain: but this asset is a backing asset for another MPA, which would cause MPA " "backed by MPA backed by MPA." ); - op.asset_to_update = asset_objs.bit_parent->get_id(); - op.issuer = asset_objs.bit_parent->issuer; - op.new_options.short_backing_asset = asset_objs.bit_usdbacked->get_id(); + op.asset_to_update = asset_objs.bit_parent; + op.issuer = asset_objs.bit_parent(db).issuer; + op.new_options.short_backing_asset = asset_objs.bit_usdbacked; // this should generate a warning in the log, but not fail. BOOST_CHECK( evaluator.evaluate(op) == void_result() ); // changing the backing asset to a UIA should work BOOST_TEST_MESSAGE( "Switching to a backing asset that is a UIA should work. No warning should be produced." ); - op.new_options.short_backing_asset = asset_objs.user_issued->get_id(); + op.new_options.short_backing_asset = asset_objs.user_issued; BOOST_CHECK( evaluator.evaluate(op) == void_result() ); // A -> B -> C, change B to be backed by A (circular backing) BOOST_TEST_MESSAGE( "Message should contain: A cannot be backed by B which is backed by A." ); - op.new_options.short_backing_asset = asset_objs.bit_child_bitasset->get_id(); + op.new_options.short_backing_asset = asset_objs.bit_child_bitasset; BOOST_CHECK( evaluator.evaluate(op) == void_result() ); - op.new_options.short_backing_asset = asset_objs.user_issued->get_id(); + op.new_options.short_backing_asset = asset_objs.user_issued; BOOST_TEST_MESSAGE( "Message should contain: but this asset is a backing asset for a committee-issued asset." ); // CHILDCOMMITTEE is a committee asset backed by PARENT which is backed by CORE // Cannot change PARENT's backing asset from CORE to something else because that will make CHILD be backed by // an asset that is not itself backed by CORE create_bitasset( "CHILDCOMMITTEE", GRAPHENE_COMMITTEE_ACCOUNT, 100, charge_market_fee, 2, - asset_objs.bit_parent->get_id() ); + asset_objs.bit_parent ); // it should again work, generating 2 warnings in the log. 1 for the above, and 1 new one. BOOST_CHECK( evaluator.evaluate(op) == void_result() ); - op.asset_to_update = asset_objs.bit_usd->get_id(); - op.issuer = asset_objs.bit_usd->issuer; + op.asset_to_update = asset_objs.bit_usd; + op.issuer = asset_objs.bit_usd(db).issuer; op.new_options.short_backing_asset = correct_asset_id; // USDBACKED is backed by USDBIT (which is backed by CORE) @@ -730,13 +731,13 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_before_922_931 ) // because that would be a MPA backed by MPA backed by MPA. BOOST_TEST_MESSAGE( "Message should contain: a BitAsset cannot be backed by a BitAsset that " "itself is backed by a BitAsset." ); - op.asset_to_update = asset_objs.bit_usdbacked2->get_id(); - op.issuer = asset_objs.bit_usdbacked2->issuer; - op.new_options.short_backing_asset = asset_objs.bit_usdbacked->get_id(); + op.asset_to_update = asset_objs.bit_usdbacked2; + op.issuer = asset_objs.bit_usdbacked2(db).issuer; + op.new_options.short_backing_asset = asset_objs.bit_usdbacked; BOOST_CHECK( evaluator.evaluate(op) == void_result() ); // set everything to a more normal state - op.asset_to_update = asset_objs.bit_usdbacked->get_id(); - op.issuer = asset_objs.bit_usd->issuer; + op.asset_to_update = asset_objs.bit_usdbacked; + op.issuer = asset_objs.bit_usd(db).issuer; op.new_options.short_backing_asset = asset_id_type(); // Feed lifetime must exceed block interval @@ -777,15 +778,15 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_after_922_931 ) ACTORS( (nathan) (john) ); assets_922_931 asset_objs = create_assets_922_931( this ); - const asset_id_type& bit_usd_id = asset_objs.bit_usd->get_id(); + const asset_id_type& bit_usd_id = asset_objs.bit_usd; // make a generic operation bitasset_evaluator_wrapper evaluator; evaluator.set_db( db ); asset_update_bitasset_operation op; op.asset_to_update = bit_usd_id; - op.issuer = asset_objs.bit_usd->issuer; - op.new_options = asset_objs.bit_usd->bitasset_data(db).options; + op.issuer = asset_objs.bit_usd(db).issuer; + op.new_options = asset_objs.bit_usd(db).bitasset_data(db).options; // this should pass BOOST_TEST_MESSAGE( "Evaluating a good operation" ); @@ -793,7 +794,7 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_after_922_931 ) // test with a market issued asset BOOST_TEST_MESSAGE( "Sending a non-bitasset." ); - op.asset_to_update = asset_objs.user_issued->get_id(); + op.asset_to_update = asset_objs.user_issued; REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "Cannot update BitAsset-specific settings on a non-BitAsset" ); op.asset_to_update = bit_usd_id; @@ -823,17 +824,17 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_after_922_931 ) // prediction market with different precision BOOST_TEST_MESSAGE( "Prediction market with different precision" ); - op.asset_to_update = asset_objs.prediction->get_id(); - op.issuer = asset_objs.prediction->issuer; + op.asset_to_update = asset_objs.prediction; + op.issuer = asset_objs.prediction(db).issuer; REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "The precision of the asset and backing asset must" ); op.asset_to_update = bit_usd_id; - op.issuer = asset_objs.bit_usd->issuer; + op.issuer = asset_objs.bit_usd(db).issuer; // checking old backing asset instead of new backing asset BOOST_TEST_MESSAGE( "Correctly checking new backing asset rather than old backing asset" ); - op.new_options.short_backing_asset = asset_objs.six_precision->get_id(); + op.new_options.short_backing_asset = asset_objs.six_precision; REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "which is not market issued asset nor CORE." ); - op.new_options.short_backing_asset = asset_objs.prediction->get_id(); + op.new_options.short_backing_asset = asset_objs.prediction; REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "which is not backed by CORE" ); op.new_options.short_backing_asset = correct_asset_id; @@ -841,29 +842,30 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_after_922_931 ) // Cannot change PARENT's backing asset from CORE to something that is not [CORE | UIA] // because that will make CHILD be backed by an asset that is not itself backed by CORE or a UIA. BOOST_TEST_MESSAGE( "Attempting to change PARENT to be backed by a non-core and non-user-issued asset" ); - op.asset_to_update = asset_objs.bit_parent->get_id(); - op.issuer = asset_objs.bit_parent->issuer; - op.new_options.short_backing_asset = asset_objs.bit_usdbacked->get_id(); - REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "A non-blockchain controlled BitAsset would be invalidated" ); + op.asset_to_update = asset_objs.bit_parent; + op.issuer = asset_objs.bit_parent(db).issuer; + op.new_options.short_backing_asset = asset_objs.bit_usdbacked; + REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "cannot be backed by a BitAsset that itself is backed by a BitAsset." ); // changing the backing asset to a UIA should work BOOST_TEST_MESSAGE( "Switching to a backing asset that is a UIA should work." ); - op.new_options.short_backing_asset = asset_objs.user_issued->get_id(); + op.new_options.short_backing_asset = asset_objs.user_issued; BOOST_CHECK( evaluator.evaluate(op) == void_result() ); // A -> B -> C, change B to be backed by A (circular backing) BOOST_TEST_MESSAGE( "Check for circular backing. This should generate an exception" ); - op.new_options.short_backing_asset = asset_objs.bit_child_bitasset->get_id(); + op.new_options.short_backing_asset = asset_objs.bit_child_bitasset; REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "'A' backed by 'B' backed by 'A'" ); - op.new_options.short_backing_asset = asset_objs.user_issued->get_id(); + op.new_options.short_backing_asset = asset_objs.user_issued; + BOOST_CHECK( evaluator.evaluate(op) == void_result() ); BOOST_TEST_MESSAGE( "Creating CHILDCOMMITTEE" ); // CHILDCOMMITTEE is a committee asset backed by PARENT which is backed by CORE - // Cannot change PARENT's backing asset from CORE to something else because that will make CHILD be backed by - // an asset that is not itself backed by CORE + // Cannot change PARENT's backing asset from CORE to something else because that will make CHILDCOMMITTEE + // be backed by an asset that is not itself backed by CORE create_bitasset( "CHILDCOMMITTEE", GRAPHENE_COMMITTEE_ACCOUNT, 100, charge_market_fee, 2, - asset_objs.bit_parent->get_id() ); + asset_objs.bit_parent ); // it should again not work REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "A blockchain-controlled market asset would be invalidated" ); - op.asset_to_update = asset_objs.bit_usd->get_id(); - op.issuer = asset_objs.bit_usd->issuer; + op.asset_to_update = asset_objs.bit_usd; + op.issuer = asset_objs.bit_usd(db).issuer; op.new_options.short_backing_asset = correct_asset_id; // USDBACKED is backed by USDBIT (which is backed by CORE) @@ -871,14 +873,14 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_after_922_931 ) // We should not be able to make USDBACKEDII be backed by USDBACKED // because that would be a MPA backed by MPA backed by MPA. BOOST_TEST_MESSAGE( "MPA -> MPA -> MPA not allowed" ); - op.asset_to_update = asset_objs.bit_usdbacked2->get_id(); - op.issuer = asset_objs.bit_usdbacked2->issuer; - op.new_options.short_backing_asset = asset_objs.bit_usdbacked->get_id(); + op.asset_to_update = asset_objs.bit_usdbacked2; + op.issuer = asset_objs.bit_usdbacked2(db).issuer; + op.new_options.short_backing_asset = asset_objs.bit_usdbacked; REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "A BitAsset cannot be backed by a BitAsset that itself is backed by a BitAsset" ); // set everything to a more normal state - op.asset_to_update = asset_objs.bit_usdbacked->get_id(); - op.issuer = asset_objs.bit_usd->issuer; + op.asset_to_update = asset_objs.bit_usdbacked; + op.issuer = asset_objs.bit_usd(db).issuer; op.new_options.short_backing_asset = asset_id_type(); // Feed lifetime must exceed block interval @@ -1134,6 +1136,8 @@ BOOST_AUTO_TEST_CASE( bitasset_secondary_index ) ACTORS( (nathan) ); graphene::chain::asset_id_type core_id; + BOOST_TEST_MESSAGE( "Running test bitasset_secondary_index" ); + BOOST_TEST_MESSAGE( "Core asset id: " + fc::json::to_pretty_string( core_id ) ); BOOST_TEST_MESSAGE("Create coins"); try { @@ -1177,22 +1181,25 @@ BOOST_AUTO_TEST_CASE( bitasset_secondary_index ) for( ; core_itr != core_end; ++core_itr) { BOOST_CHECK(core_itr->options.short_backing_asset == core_id); + BOOST_TEST_MESSAGE( fc::json::to_pretty_string(core_itr->asset_id) + " is backed by CORE" ); core_count++; } for( ; coin1_itr != coin1_end; ++coin1_itr ) { BOOST_CHECK(coin1_itr->options.short_backing_asset == coin1_id); + BOOST_TEST_MESSAGE( fc::json::to_pretty_string( coin1_itr->asset_id) + " is backed by COIN1TEST" ); coin1_count++; } for( ; coin2_itr != idx.end(); ++coin2_itr ) { BOOST_CHECK(coin2_itr->options.short_backing_asset == coin2_id); + BOOST_TEST_MESSAGE( fc::json::to_pretty_string( coin2_itr->asset_id) + " is backed by COIN2TEST" ); coin2_count++; } - BOOST_CHECK_EQUAL(core_count, 10); - BOOST_CHECK_EQUAL(coin1_count, 5); - BOOST_CHECK_EQUAL(coin2_count, 5); + BOOST_CHECK( core_count >= 10 ); + BOOST_CHECK_EQUAL( coin1_count, 5 ); + BOOST_CHECK_EQUAL( coin2_count, 5 ); } catch (fc::exception& ex) { From e921b54ceb8a2823b731c041bbeab5761c8b431d Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 18 Jun 2018 07:35:38 -0500 Subject: [PATCH 4/8] fix logic errors using new index --- libraries/chain/asset_evaluator.cpp | 65 ++++++++++++++--------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/libraries/chain/asset_evaluator.cpp b/libraries/chain/asset_evaluator.cpp index 8c177970d5..4c61e8bdfd 100644 --- a/libraries/chain/asset_evaluator.cpp +++ b/libraries/chain/asset_evaluator.cpp @@ -382,54 +382,51 @@ void check_children_of_bitasset(database& d, const asset_update_bitasset_operati auto backed_by_itr = idx.find( op.asset_to_update ); if ( backed_by_itr != idx.end() ) // if we found at least 1 { - auto backed_end = idx.upper_bound( new_backing_asset.get_id() ); + auto backed_end = idx.upper_bound( op.asset_to_update ); for( ; backed_by_itr != backed_end; ++backed_by_itr ) { const auto& bitasset_data = *backed_by_itr; const auto& child = bitasset_data.asset_id(d); - if ( bitasset_data.options.short_backing_asset == op.asset_to_update ) + if ( after_hf_922_931 ) { - if ( after_hf_922_931 ) - { - FC_ASSERT( child.get_id() != op.new_options.short_backing_asset, - "A BitAsset would be invalidated by changing this backing asset ('A' backed by 'B' backed by 'A')." ); + FC_ASSERT( child.get_id() != op.new_options.short_backing_asset, + "A BitAsset would be invalidated by changing this backing asset ('A' backed by 'B' backed by 'A')." ); - FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT, - "A blockchain-controlled market asset would be invalidated by changing this backing asset." ); + FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT, + "A blockchain-controlled market asset would be invalidated by changing this backing asset." ); - FC_ASSERT( !new_backing_asset.is_market_issued(), - "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset."); + FC_ASSERT( !new_backing_asset.is_market_issued(), + "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset."); + } + else + { + if( child.get_id() == op.new_options.short_backing_asset ) + { + wlog( "Before hf-922-931, modified an asset to be backed by another, but would cause a continuous " + "loop. A cannot be backed by B which is backed by A." ); + return; + } + + if( child.issuer == GRAPHENE_COMMITTEE_ACCOUNT ) + { + wlog( "before hf-922-931, modified an asset to be backed by a non-CORE, but this asset " + "is a backing asset for a committee-issued asset. This occurred at block ${b}", + ("b", d.head_block_num())); + return; } else { - if( child.get_id() == op.new_options.short_backing_asset ) - { - wlog( "Before hf-922-931, modified an asset to be backed by another, but would cause a continuous " - "loop. A cannot be backed by B which is backed by A." ); - return; - } - - if( child.issuer == GRAPHENE_COMMITTEE_ACCOUNT ) - { - wlog( "before hf-922-931, modified an asset to be backed by a non-CORE, but this asset " - "is a backing asset for a committee-issued asset. This occurred at block ${b}", - ("b", d.head_block_num())); + if ( new_backing_asset.is_market_issued() ) { // a.k.a. !UIA + wlog( "before hf-922-931, modified an asset to be backed by an MPA, but this asset " + "is a backing asset for another MPA, which would cause MPA backed by MPA backed by MPA. " + "This occurred at block ${b}", + ("b", d.head_block_num())); return; } - else - { - if ( new_backing_asset.is_market_issued() ) { // a.k.a. !UIA - wlog( "before hf-922-931, modified an asset to be backed by an MPA, but this asset " - "is a backing asset for another MPA, which would cause MPA backed by MPA backed by MPA. " - "This occurred at block ${b}", - ("b", d.head_block_num())); - return; - } - } // if child.issuer - } // if hf 922/931 - } // if this child is backed by the asset being adjusted + } // if child.issuer + } // if hf 922/931 } // for each asset } // if this asset is backing another asset } // check_children_of_bitasset From 79b0337c4846bcde8c751ba6742ec960753e3c15 Mon Sep 17 00:00:00 2001 From: John Jones Date: Mon, 18 Jun 2018 08:33:18 -0500 Subject: [PATCH 5/8] fix bitasset hardfork test --- tests/tests/bitasset_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests/bitasset_tests.cpp b/tests/tests/bitasset_tests.cpp index 9711faed6b..1585e9fdd7 100644 --- a/tests/tests/bitasset_tests.cpp +++ b/tests/tests/bitasset_tests.cpp @@ -845,7 +845,7 @@ BOOST_AUTO_TEST_CASE( bitasset_evaluator_test_after_922_931 ) op.asset_to_update = asset_objs.bit_parent; op.issuer = asset_objs.bit_parent(db).issuer; op.new_options.short_backing_asset = asset_objs.bit_usdbacked; - REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "cannot be backed by a BitAsset that itself is backed by a BitAsset." ); + REQUIRE_EXCEPTION_WITH_TEXT( evaluator.evaluate(op), "A non-blockchain controlled BitAsset would be invalidated" ); // changing the backing asset to a UIA should work BOOST_TEST_MESSAGE( "Switching to a backing asset that is a UIA should work." ); op.new_options.short_backing_asset = asset_objs.user_issued; From 32800c2af54a0ccfbbb7c5c612f4e3fcfbc0a578 Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 21 Jun 2018 21:49:40 -0500 Subject: [PATCH 6/8] Clarified comment --- libraries/chain/asset_evaluator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/chain/asset_evaluator.cpp b/libraries/chain/asset_evaluator.cpp index 4c61e8bdfd..758788339b 100644 --- a/libraries/chain/asset_evaluator.cpp +++ b/libraries/chain/asset_evaluator.cpp @@ -380,6 +380,7 @@ void check_children_of_bitasset(database& d, const asset_update_bitasset_operati // loop through all assets that have this asset as a backing asset const auto& idx = d.get_index_type().indices().get(); auto backed_by_itr = idx.find( op.asset_to_update ); + if ( backed_by_itr != idx.end() ) // if we found at least 1 { auto backed_end = idx.upper_bound( op.asset_to_update ); @@ -427,7 +428,7 @@ void check_children_of_bitasset(database& d, const asset_update_bitasset_operati } } // if child.issuer } // if hf 922/931 - } // for each asset + } // for each asset backed by asset_to_update } // if this asset is backing another asset } // check_children_of_bitasset From cba93b8ab6fd4950f6fff3a17265eb266f6f81a3 Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 22 Jun 2018 17:16:33 -0500 Subject: [PATCH 7/8] Switched to using boost multiindex range --- libraries/chain/asset_evaluator.cpp | 86 +++++++++++++++-------------- tests/tests/bitasset_tests.cpp | 30 +++++----- 2 files changed, 60 insertions(+), 56 deletions(-) diff --git a/libraries/chain/asset_evaluator.cpp b/libraries/chain/asset_evaluator.cpp index 758788339b..de576320ea 100644 --- a/libraries/chain/asset_evaluator.cpp +++ b/libraries/chain/asset_evaluator.cpp @@ -33,6 +33,8 @@ #include #include +#include // to fix the lack of an include before 1.62 +#include namespace graphene { namespace chain { @@ -378,58 +380,58 @@ void check_children_of_bitasset(database& d, const asset_update_bitasset_operati return; // loop through all assets that have this asset as a backing asset - const auto& idx = d.get_index_type().indices().get(); - auto backed_by_itr = idx.find( op.asset_to_update ); - - if ( backed_by_itr != idx.end() ) // if we found at least 1 + const auto& idx = d.get_index_type() + .indices() + .get(); + //std::pair backed_range + // = idx.range(op.asset_to_update, op.asset_to_update); + auto backed_range = idx.range(op.asset_to_update == boost::lambda::_1, boost::lambda::_1 == op.asset_to_update); + + for( auto backed_itr = backed_range.first; backed_itr != backed_range.second; ++backed_itr ) { - auto backed_end = idx.upper_bound( op.asset_to_update ); - - for( ; backed_by_itr != backed_end; ++backed_by_itr ) + const auto& bitasset_data = *backed_itr; + const auto& child = bitasset_data.asset_id(d); + if ( after_hf_922_931 ) { - const auto& bitasset_data = *backed_by_itr; - const auto& child = bitasset_data.asset_id(d); - if ( after_hf_922_931 ) - { - FC_ASSERT( child.get_id() != op.new_options.short_backing_asset, - "A BitAsset would be invalidated by changing this backing asset ('A' backed by 'B' backed by 'A')." ); + FC_ASSERT( child.get_id() != op.new_options.short_backing_asset, + "A BitAsset would be invalidated by changing this backing asset ('A' backed by 'B' backed by 'A')." ); - FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT, - "A blockchain-controlled market asset would be invalidated by changing this backing asset." ); + FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT, + "A blockchain-controlled market asset would be invalidated by changing this backing asset." ); - FC_ASSERT( !new_backing_asset.is_market_issued(), - "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset."); + FC_ASSERT( !new_backing_asset.is_market_issued(), + "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset."); + } + else + { + if( child.get_id() == op.new_options.short_backing_asset ) + { + wlog( "Before hf-922-931, modified an asset to be backed by another, but would cause a continuous " + "loop. A cannot be backed by B which is backed by A." ); + return; + } + + if( child.issuer == GRAPHENE_COMMITTEE_ACCOUNT ) + { + wlog( "before hf-922-931, modified an asset to be backed by a non-CORE, but this asset " + "is a backing asset for a committee-issued asset. This occurred at block ${b}", + ("b", d.head_block_num())); + return; } else { - if( child.get_id() == op.new_options.short_backing_asset ) - { - wlog( "Before hf-922-931, modified an asset to be backed by another, but would cause a continuous " - "loop. A cannot be backed by B which is backed by A." ); - return; - } - - if( child.issuer == GRAPHENE_COMMITTEE_ACCOUNT ) - { - wlog( "before hf-922-931, modified an asset to be backed by a non-CORE, but this asset " - "is a backing asset for a committee-issued asset. This occurred at block ${b}", - ("b", d.head_block_num())); + if ( new_backing_asset.is_market_issued() ) { // a.k.a. !UIA + wlog( "before hf-922-931, modified an asset to be backed by an MPA, but this asset " + "is a backing asset for another MPA, which would cause MPA backed by MPA backed by MPA. " + "This occurred at block ${b}", + ("b", d.head_block_num())); return; } - else - { - if ( new_backing_asset.is_market_issued() ) { // a.k.a. !UIA - wlog( "before hf-922-931, modified an asset to be backed by an MPA, but this asset " - "is a backing asset for another MPA, which would cause MPA backed by MPA backed by MPA. " - "This occurred at block ${b}", - ("b", d.head_block_num())); - return; - } - } // if child.issuer - } // if hf 922/931 - } // for each asset backed by asset_to_update - } // if this asset is backing another asset + } // if child.issuer + } // if hf 922/931 + } // for each asset backed by asset_to_update } // check_children_of_bitasset void_result asset_update_bitasset_evaluator::do_evaluate(const asset_update_bitasset_operation& op) diff --git a/tests/tests/bitasset_tests.cpp b/tests/tests/bitasset_tests.cpp index 1585e9fdd7..023aad9452 100644 --- a/tests/tests/bitasset_tests.cpp +++ b/tests/tests/bitasset_tests.cpp @@ -25,6 +25,7 @@ #include #include + #include #include @@ -44,6 +45,9 @@ #include "../common/database_fixture.hpp" +#include // to fix the lack of an include before 1.62 +#include + using namespace graphene::chain; using namespace graphene::chain::test; @@ -1166,34 +1170,32 @@ BOOST_AUTO_TEST_CASE( bitasset_secondary_index ) BOOST_TEST_MESSAGE("Searching for all coins backed by CORE"); const auto& idx = db.get_index_type().indices().get(); - auto core_itr = idx.find( core_id ); - auto core_end = idx.upper_bound(core_id); + auto core_itr = idx.range( core_id == boost::lambda::_1, core_id == boost::lambda::_1); BOOST_TEST_MESSAGE("Searching for all coins backed by COIN1"); - auto coin1_itr = idx.find( coin1_id ); - auto coin1_end = idx.upper_bound( coin1_id ); + auto coin1_itr = idx.range( coin1_id == boost::lambda::_1, coin1_id == boost::lambda::_1); BOOST_TEST_MESSAGE("Searching for all coins backed by COIN2"); - auto coin2_itr = idx.find( coin2_id ); + auto coin2_itr = idx.range( coin2_id == boost::lambda::_1, coin2_id == boost::lambda::_1); int core_count = 0, coin1_count = 0, coin2_count = 0; BOOST_TEST_MESSAGE("Counting coins in each category"); - for( ; core_itr != core_end; ++core_itr) + for( auto itr = core_itr.first ; itr != core_itr.second; ++itr) { - BOOST_CHECK(core_itr->options.short_backing_asset == core_id); - BOOST_TEST_MESSAGE( fc::json::to_pretty_string(core_itr->asset_id) + " is backed by CORE" ); + BOOST_CHECK(itr->options.short_backing_asset == core_id); + BOOST_TEST_MESSAGE( fc::json::to_pretty_string(itr->asset_id) + " is backed by CORE" ); core_count++; } - for( ; coin1_itr != coin1_end; ++coin1_itr ) + for( auto itr = coin1_itr.first ; itr != coin1_itr.second; ++itr ) { - BOOST_CHECK(coin1_itr->options.short_backing_asset == coin1_id); - BOOST_TEST_MESSAGE( fc::json::to_pretty_string( coin1_itr->asset_id) + " is backed by COIN1TEST" ); + BOOST_CHECK(itr->options.short_backing_asset == coin1_id); + BOOST_TEST_MESSAGE( fc::json::to_pretty_string( itr->asset_id) + " is backed by COIN1TEST" ); coin1_count++; } - for( ; coin2_itr != idx.end(); ++coin2_itr ) + for( auto itr = coin2_itr.first; itr != coin2_itr.second; ++itr ) { - BOOST_CHECK(coin2_itr->options.short_backing_asset == coin2_id); - BOOST_TEST_MESSAGE( fc::json::to_pretty_string( coin2_itr->asset_id) + " is backed by COIN2TEST" ); + BOOST_CHECK(itr->options.short_backing_asset == coin2_id); + BOOST_TEST_MESSAGE( fc::json::to_pretty_string( itr->asset_id) + " is backed by COIN2TEST" ); coin2_count++; } From ccd8ff2e48ea4a2314db3129b75513c146b808d5 Mon Sep 17 00:00:00 2001 From: John Jones Date: Fri, 22 Jun 2018 21:50:50 -0500 Subject: [PATCH 8/8] Implemented idx.equal_range to avoid ugly lambda --- libraries/chain/asset_evaluator.cpp | 89 ++++++++++++++--------------- tests/tests/bitasset_tests.cpp | 9 +-- 2 files changed, 45 insertions(+), 53 deletions(-) diff --git a/libraries/chain/asset_evaluator.cpp b/libraries/chain/asset_evaluator.cpp index de576320ea..e2d0ca5eb2 100644 --- a/libraries/chain/asset_evaluator.cpp +++ b/libraries/chain/asset_evaluator.cpp @@ -33,8 +33,6 @@ #include #include -#include // to fix the lack of an include before 1.62 -#include namespace graphene { namespace chain { @@ -383,55 +381,52 @@ void check_children_of_bitasset(database& d, const asset_update_bitasset_operati const auto& idx = d.get_index_type() .indices() .get(); - //std::pair backed_range - // = idx.range(op.asset_to_update, op.asset_to_update); - auto backed_range = idx.range(op.asset_to_update == boost::lambda::_1, boost::lambda::_1 == op.asset_to_update); - - for( auto backed_itr = backed_range.first; backed_itr != backed_range.second; ++backed_itr ) - { - const auto& bitasset_data = *backed_itr; - const auto& child = bitasset_data.asset_id(d); - if ( after_hf_922_931 ) - { - FC_ASSERT( child.get_id() != op.new_options.short_backing_asset, - "A BitAsset would be invalidated by changing this backing asset ('A' backed by 'B' backed by 'A')." ); + auto backed_range = idx.equal_range(op.asset_to_update); + std::for_each( backed_range.first, backed_range.second, + [after_hf_922_931, &new_backing_asset, &d, &op](const asset_bitasset_data_object& bitasset_data) + { + const auto& child = bitasset_data.asset_id(d); + if ( after_hf_922_931 ) + { + FC_ASSERT( child.get_id() != op.new_options.short_backing_asset, + "A BitAsset would be invalidated by changing this backing asset ('A' backed by 'B' backed by 'A')." ); - FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT, - "A blockchain-controlled market asset would be invalidated by changing this backing asset." ); + FC_ASSERT( child.issuer != GRAPHENE_COMMITTEE_ACCOUNT, + "A blockchain-controlled market asset would be invalidated by changing this backing asset." ); - FC_ASSERT( !new_backing_asset.is_market_issued(), - "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset."); + FC_ASSERT( !new_backing_asset.is_market_issued(), + "A non-blockchain controlled BitAsset would be invalidated by changing this backing asset."); - } - else - { - if( child.get_id() == op.new_options.short_backing_asset ) - { - wlog( "Before hf-922-931, modified an asset to be backed by another, but would cause a continuous " - "loop. A cannot be backed by B which is backed by A." ); - return; - } - - if( child.issuer == GRAPHENE_COMMITTEE_ACCOUNT ) - { - wlog( "before hf-922-931, modified an asset to be backed by a non-CORE, but this asset " - "is a backing asset for a committee-issued asset. This occurred at block ${b}", - ("b", d.head_block_num())); - return; - } - else - { - if ( new_backing_asset.is_market_issued() ) { // a.k.a. !UIA - wlog( "before hf-922-931, modified an asset to be backed by an MPA, but this asset " - "is a backing asset for another MPA, which would cause MPA backed by MPA backed by MPA. " - "This occurred at block ${b}", - ("b", d.head_block_num())); - return; } - } // if child.issuer - } // if hf 922/931 - } // for each asset backed by asset_to_update + else + { + if( child.get_id() == op.new_options.short_backing_asset ) + { + wlog( "Before hf-922-931, modified an asset to be backed by another, but would cause a continuous " + "loop. A cannot be backed by B which is backed by A." ); + return; + } + + if( child.issuer == GRAPHENE_COMMITTEE_ACCOUNT ) + { + wlog( "before hf-922-931, modified an asset to be backed by a non-CORE, but this asset " + "is a backing asset for a committee-issued asset. This occurred at block ${b}", + ("b", d.head_block_num())); + return; + } + else + { + if ( new_backing_asset.is_market_issued() ) // a.k.a. !UIA + { + wlog( "before hf-922-931, modified an asset to be backed by an MPA, but this asset " + "is a backing asset for another MPA, which would cause MPA backed by MPA backed by MPA. " + "This occurred at block ${b}", + ("b", d.head_block_num())); + return; + } + } // if child.issuer + } // if hf 922/931 + } ); // end of lambda and std::for_each() } // check_children_of_bitasset void_result asset_update_bitasset_evaluator::do_evaluate(const asset_update_bitasset_operation& op) diff --git a/tests/tests/bitasset_tests.cpp b/tests/tests/bitasset_tests.cpp index 023aad9452..9e9a2814ed 100644 --- a/tests/tests/bitasset_tests.cpp +++ b/tests/tests/bitasset_tests.cpp @@ -45,9 +45,6 @@ #include "../common/database_fixture.hpp" -#include // to fix the lack of an include before 1.62 -#include - using namespace graphene::chain; using namespace graphene::chain::test; @@ -1170,11 +1167,11 @@ BOOST_AUTO_TEST_CASE( bitasset_secondary_index ) BOOST_TEST_MESSAGE("Searching for all coins backed by CORE"); const auto& idx = db.get_index_type().indices().get(); - auto core_itr = idx.range( core_id == boost::lambda::_1, core_id == boost::lambda::_1); + auto core_itr = idx.equal_range( core_id ); BOOST_TEST_MESSAGE("Searching for all coins backed by COIN1"); - auto coin1_itr = idx.range( coin1_id == boost::lambda::_1, coin1_id == boost::lambda::_1); + auto coin1_itr = idx.equal_range( coin1_id ); BOOST_TEST_MESSAGE("Searching for all coins backed by COIN2"); - auto coin2_itr = idx.range( coin2_id == boost::lambda::_1, coin2_id == boost::lambda::_1); + auto coin2_itr = idx.equal_range( coin2_id ); int core_count = 0, coin1_count = 0, coin2_count = 0;