diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index f0186d8d34..786c7a9f31 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -302,26 +302,27 @@ namespace graphene { namespace app { const auto& db = *_app.chain_database(); FC_ASSERT( limit <= 100 ); vector result; - const auto& stats = account(db).statistics(db); - if( stats.most_recent_op == account_transaction_history_id_type() ) return result; - const account_transaction_history_object* node = &stats.most_recent_op(db); - if( start == operation_history_id_type() ) - start = node->operation_id; - - while(node && node->operation_id.instance.value > stop.instance.value && result.size() < limit) + try { + const account_transaction_history_object& node = account(db).statistics(db).most_recent_op(db); + if(start == operation_history_id_type() || start.instance.value > node.operation_id.instance.value) + start = node.operation_id; + } catch(...) { return result; } + + const auto& hist_idx = db.get_index_type(); + const auto& by_op_idx = hist_idx.indices().get(); + auto index_start = by_op_idx.begin(); + auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); + + while(itr != index_start && itr->account == account && itr->operation_id.instance.value > stop.instance.value && result.size() < limit) { - if( node->operation_id.instance.value <= start.instance.value ) - result.push_back( node->operation_id(db) ); - if( node->next == account_transaction_history_id_type() ) - node = nullptr; - else node = &node->next(db); + if(itr->operation_id.instance.value <= start.instance.value) + result.push_back(itr->operation_id(db)); + --itr; } - if( stop.instance.value == 0 && result.size() < limit ) - { - node = db.find(account_transaction_history_id_type()); - if( node && node->account == account) - result.push_back( node->operation_id(db) ); + if(stop.instance.value == 0 && result.size() < limit && itr->account == account) { + result.push_back(itr->operation_id(db)); } + return result; } diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index d7b79fe19f..edab85706e 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -93,7 +93,23 @@ database_fixture::database_fixture() genesis_state.initial_parameters.current_fees->zero_all_fees(); open_database(); - // app.initialize(); + // add account tracking for ahplugin for special test case with track-account enabled + if( !options.count("track-account") && boost::unit_test::framework::current_test_case().p_name.value == "track_account") { + std::vector track_account; + std::string track = "\"1.2.17\""; + track_account.push_back(track); + options.insert(std::make_pair("track-account", boost::program_options::variable_value(track_account, false))); + } + // account tracking 2 accounts + if( !options.count("track-account") && boost::unit_test::framework::current_test_case().p_name.value == "track_account2") { + std::vector track_account; + std::string track = "\"1.2.0\""; + track_account.push_back(track); + track = "\"1.2.16\""; + track_account.push_back(track); + options.insert(std::make_pair("track-account", boost::program_options::variable_value(track_account, false))); + } + ahplugin->plugin_set_app(&app); ahplugin->plugin_initialize(options); diff --git a/tests/tests/history_api_tests.cpp b/tests/tests/history_api_tests.cpp index 5ef1067b70..53b3ce799b 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -25,14 +25,6 @@ #include #include -#include -#include - -#include -#include -#include -#include -#include #include @@ -62,6 +54,7 @@ BOOST_AUTO_TEST_CASE(get_account_history) { //account_id_type() did 3 ops and includes id0 vector histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 100, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 3); BOOST_CHECK_EQUAL(histories[2].id.instance(), 0); BOOST_CHECK_EQUAL(histories[2].op.which(), asset_create_op_id); @@ -72,6 +65,7 @@ BOOST_AUTO_TEST_CASE(get_account_history) { BOOST_CHECK(histories[0].id.instance() != 0); BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + // Limit 2 returns 2 result histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 2, operation_history_id_type()); BOOST_CHECK_EQUAL(histories.size(), 2); @@ -82,6 +76,438 @@ BOOST_AUTO_TEST_CASE(get_account_history) { BOOST_CHECK_EQUAL(histories.size(), 1); BOOST_CHECK_EQUAL(histories[0].op.which(), account_create_op_id); + + } catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE(get_account_history_additional) { + try { + graphene::app::history_api hist_api(app); + + // A = account_id_type() with records { 5, 3, 1, 0 }, and + // B = dan with records { 6, 4, 2, 1 } + // account_id_type() and dan share operation id 1(account create) - share can be also in id 0 + + // no history at all in the chain + vector histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(0), 4, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + create_bitasset("USD", account_id_type()); // create op 0 + generate_block(); + // what if the account only has one history entry and it is 0? + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 0); + + + const account_object& dan = create_account("dan"); // create op 1 + auto dan_id = dan.id; + + create_bitasset("CNY", dan.id); // create op 2 + create_bitasset("BTC", account_id_type()); // create op 3 + create_bitasset("XMR", dan.id); // create op 4 + create_bitasset("EUR", account_id_type()); // create op 5 + create_bitasset("OIL", dan.id); // create op 6 + + generate_block(); + + // f(A, 0, 4, 9) = { 5, 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type(9)); + BOOST_CHECK_EQUAL(histories.size(), 4); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 0); + + // f(A, 0, 4, 6) = { 5, 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type(6)); + BOOST_CHECK_EQUAL(histories.size(), 4); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 0); + + // f(A, 0, 4, 5) = { 5, 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type(5)); + BOOST_CHECK_EQUAL(histories.size(), 4); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 0); + + // f(A, 0, 4, 4) = { 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type(4)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 0); + + // f(A, 0, 4, 3) = { 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type(3)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 0); + + // f(A, 0, 4, 2) = { 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type(2)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 0); + + // f(A, 0, 4, 1) = { 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type(1)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 0); + + // f(A, 0, 4, 0) = { 5, 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 4); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 0); + + // f(A, 1, 5, 9) = { 5, 3 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 5, operation_history_id_type(9)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + + // f(A, 1, 5, 6) = { 5, 3 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 5, operation_history_id_type(6)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + + // f(A, 1, 5, 5) = { 5, 3 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 5, operation_history_id_type(5)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + + // f(A, 1, 5, 4) = { 3 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 5, operation_history_id_type(4)); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 3); + + // f(A, 1, 5, 3) = { 3 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 5, operation_history_id_type(3)); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 3); + + // f(A, 1, 5, 2) = { } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 5, operation_history_id_type(2)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // f(A, 1, 5, 1) = { } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 5, operation_history_id_type(1)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // f(A, 1, 5, 0) = { 5, 3 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 5, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + + // f(A, 0, 3, 9) = { 5, 3, 1 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 3, operation_history_id_type(9)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + + // f(A, 0, 3, 6) = { 5, 3, 1 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 3, operation_history_id_type(6)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + + // f(A, 0, 3, 5) = { 5, 3, 1 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 3, operation_history_id_type(5)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + + // f(A, 0, 3, 4) = { 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 3, operation_history_id_type(4)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 0); + + // f(A, 0, 3, 3) = { 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 3, operation_history_id_type(3)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 0); + + // f(A, 0, 3, 2) = { 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 3, operation_history_id_type(2)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 0); + + // f(A, 0, 3, 1) = { 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 3, operation_history_id_type(1)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 0); + + // f(A, 0, 3, 0) = { 5, 3, 1 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 3, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + + // f(B, 0, 4, 9) = { 6, 4, 2, 1 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(), 4, operation_history_id_type(9)); + BOOST_CHECK_EQUAL(histories.size(), 4); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 6); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 4); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 2); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 1); + + // f(B, 0, 4, 6) = { 6, 4, 2, 1 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(), 4, operation_history_id_type(6)); + BOOST_CHECK_EQUAL(histories.size(), 4); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 6); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 4); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 2); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 1); + + // f(B, 0, 4, 5) = { 4, 2, 1 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(), 4, operation_history_id_type(5)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 4); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 2); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + + // f(B, 0, 4, 4) = { 4, 2, 1 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(), 4, operation_history_id_type(4)); + BOOST_CHECK_EQUAL(histories.size(), 3); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 4); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 2); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + + // f(B, 0, 4, 3) = { 2, 1 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(), 4, operation_history_id_type(3)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 2); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 1); + + // f(B, 0, 4, 2) = { 2, 1 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(), 4, operation_history_id_type(2)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 2); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 1); + + // f(B, 0, 4, 1) = { 1 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(), 4, operation_history_id_type(1)); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 1); + + // f(B, 0, 4, 0) = { 6, 4, 2, 1 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(), 4, operation_history_id_type()); + BOOST_CHECK_EQUAL(histories.size(), 4); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 6); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 4); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 2); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 1); + + // f(B, 2, 4, 9) = { 6, 4 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(2), 4, operation_history_id_type(9)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 6); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 4); + + // f(B, 2, 4, 6) = { 6, 4 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(2), 4, operation_history_id_type(6)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 6); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 4); + + // f(B, 2, 4, 5) = { 4 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(2), 4, operation_history_id_type(5)); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 4); + + // f(B, 2, 4, 4) = { 4 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(2), 4, operation_history_id_type(4)); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 4); + + // f(B, 2, 4, 3) = { } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(2), 4, operation_history_id_type(3)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // f(B, 2, 4, 2) = { } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(2), 4, operation_history_id_type(2)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // f(B, 2, 4, 1) = { } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(2), 4, operation_history_id_type(1)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // f(B, 2, 4, 0) = { 6, 4 } + histories = hist_api.get_account_history(dan_id, operation_history_id_type(2), 4, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 6); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 4); + + // 0 limits + histories = hist_api.get_account_history(dan_id, operation_history_id_type(0), 0, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(3), 0, operation_history_id_type(9)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // non existent account + histories = hist_api.get_account_history(account_id_type(18), operation_history_id_type(0), 4, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // create a new account C = alice { 7 } + const account_object& alice = create_account("alice"); + auto alice_id = alice.id; + + generate_block(); + + // f(C, 0, 4, 10) = { 7 } + histories = hist_api.get_account_history(alice_id, operation_history_id_type(0), 4, operation_history_id_type(10)); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 7); + + // f(C, 8, 4, 10) = { } + histories = hist_api.get_account_history(alice_id, operation_history_id_type(8), 4, operation_history_id_type(10)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // f(A, 0, 10, 0) = { 7, 5, 3, 1, 0 } + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(0), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 5); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 7); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 5); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[4].id.instance(), 0); + + } + catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} + +BOOST_AUTO_TEST_CASE(track_account) { + try { + graphene::app::history_api hist_api(app); + + // account_id_type() is not tracked + + // account_id_type() creates alice(not tracked account) + const account_object& alice = create_account("alice"); + auto alice_id = alice.id; + + //account_id_type() creates some ops + create_bitasset("CNY", account_id_type()); + create_bitasset("USD", account_id_type()); + + // account_id_type() creates dan(account tracked) + const account_object& dan = create_account("dan"); + auto dan_id = dan.id; + + // dan makes 1 op + create_bitasset("EUR", dan_id); + + generate_block(); + + // anything against account_id_type() should be {} + vector histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(0), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(1), 1, operation_history_id_type(2)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // anything against alice should be {} + histories = hist_api.get_account_history(alice_id, operation_history_id_type(0), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + histories = hist_api.get_account_history(alice_id, operation_history_id_type(1), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + histories = hist_api.get_account_history(alice_id, operation_history_id_type(1), 1, operation_history_id_type(2)); + BOOST_CHECK_EQUAL(histories.size(), 0); + + // dan should have history + histories = hist_api.get_account_history(dan_id, operation_history_id_type(0), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 4); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 3); + + } catch (fc::exception &e) { + edump((e.to_detail_string())); + throw; + } +} +BOOST_AUTO_TEST_CASE(track_account2) { + try { + graphene::app::history_api hist_api(app); + + // account_id_type() is tracked + + // account_id_type() creates alice(tracked account) + const account_object& alice = create_account("alice"); + auto alice_id = alice.id; + + //account_id_type() creates some ops + create_bitasset("CNY", account_id_type()); + create_bitasset("USD", account_id_type()); + + // alice makes 1 op + create_bitasset("EUR", alice_id); + + // account_id_type() creates dan(account not tracked) + const account_object& dan = create_account("dan"); + auto dan_id = dan.id; + + generate_block(); + + // all account_id_type() should have 4 ops {4,2,1,0} + vector histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(0), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 4); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 4); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 2); + BOOST_CHECK_EQUAL(histories[2].id.instance(), 1); + BOOST_CHECK_EQUAL(histories[3].id.instance(), 0); + + // all alice account should have 2 ops {3, 0} + histories = hist_api.get_account_history(alice_id, operation_history_id_type(0), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 2); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 3); + BOOST_CHECK_EQUAL(histories[1].id.instance(), 0); + + // alice first op should be {0} + histories = hist_api.get_account_history(alice_id, operation_history_id_type(0), 1, operation_history_id_type(1)); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 0); + + // alice second op should be {3} + histories = hist_api.get_account_history(alice_id, operation_history_id_type(1), 1, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 1); + BOOST_CHECK_EQUAL(histories[0].id.instance(), 3); + + // anything against dan should be {} + histories = hist_api.get_account_history(dan_id, operation_history_id_type(0), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + histories = hist_api.get_account_history(dan_id, operation_history_id_type(1), 10, operation_history_id_type(0)); + BOOST_CHECK_EQUAL(histories.size(), 0); + histories = hist_api.get_account_history(dan_id, operation_history_id_type(1), 1, operation_history_id_type(2)); + BOOST_CHECK_EQUAL(histories.size(), 0); + } catch (fc::exception &e) { edump((e.to_detail_string())); throw;