From a536f5bce48d44466d226bb3699a9b5eed0f1826 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Fri, 2 Feb 2018 19:01:04 -0300 Subject: [PATCH 01/16] change get_account_history api call --- libraries/app/api.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index f0186d8d34..e20ff174ba 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -308,19 +308,17 @@ namespace graphene { namespace app { if( start == operation_history_id_type() ) start = node->operation_id; - while(node && node->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( 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) ); + const auto& hist_idx = db.get_index_type(); + const auto& by_op_idx = hist_idx.indices().get(); + + if( start.instance.value >= stop.instance.value && start.instance.value > stats.removed_ops) { + auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); + auto itr_stop = by_op_idx.upper_bound(boost::make_tuple(account, stop)); + + do { + result.push_back(itr->operation_id(db)); + --itr; + } while (itr != itr_stop && itr->operation_id.instance.value > stop.instance.value && result.size() < limit); } return result; } From d7dd01dd3c6359612e4e4431e73feea7ac058542 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Sat, 3 Feb 2018 10:42:46 -0300 Subject: [PATCH 02/16] fix wrong if --- libraries/app/api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index e20ff174ba..8c828411a3 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -311,7 +311,7 @@ namespace graphene { namespace app { const auto& hist_idx = db.get_index_type(); const auto& by_op_idx = hist_idx.indices().get(); - if( start.instance.value >= stop.instance.value && start.instance.value > stats.removed_ops) { + if( start.instance.value >= stop.instance.value) { auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); auto itr_stop = by_op_idx.upper_bound(boost::make_tuple(account, stop)); From ca85f2d7008a13c115e882118e2692a57b5eaade Mon Sep 17 00:00:00 2001 From: Alfredo Date: Mon, 5 Feb 2018 12:33:41 -0300 Subject: [PATCH 03/16] Add checks --- libraries/app/api.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 8c828411a3..2f8bcc6891 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -316,9 +316,11 @@ namespace graphene { namespace app { auto itr_stop = by_op_idx.upper_bound(boost::make_tuple(account, stop)); do { - result.push_back(itr->operation_id(db)); --itr; - } while (itr != itr_stop && itr->operation_id.instance.value > stop.instance.value && result.size() < limit); + if(itr->account == account) + result.push_back(itr->operation_id(db)); + + } while (itr != itr_stop && itr->operation_id.instance.value > stop.instance.value && itr->operation_id.instance.value <= start.instance.value && result.size() < limit); } return result; } From 902791c944a7df2e008f0c2799d84104cdf2cccb Mon Sep 17 00:00:00 2001 From: Alfredo Date: Tue, 13 Feb 2018 12:43:08 -0300 Subject: [PATCH 04/16] refactor get_account_history --- libraries/app/api.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 2f8bcc6891..afd69a9f44 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -304,6 +304,7 @@ namespace graphene { namespace app { vector result; const auto& stats = account(db).statistics(db); if( stats.most_recent_op == account_transaction_history_id_type() ) return result; + if( start.instance.value < stop.instance.value) return result; const account_transaction_history_object* node = &stats.most_recent_op(db); if( start == operation_history_id_type() ) start = node->operation_id; @@ -311,16 +312,17 @@ namespace graphene { namespace app { const auto& hist_idx = db.get_index_type(); const auto& by_op_idx = hist_idx.indices().get(); - if( start.instance.value >= stop.instance.value) { - auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); - auto itr_stop = by_op_idx.upper_bound(boost::make_tuple(account, stop)); + auto index_end = by_op_idx.end(); + auto index_start = by_op_idx.begin(); - do { - --itr; - if(itr->account == account) - result.push_back(itr->operation_id(db)); + auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); + auto itr_end = by_op_idx.upper_bound(boost::make_tuple(account, stop)); - } while (itr != itr_stop && itr->operation_id.instance.value > stop.instance.value && itr->operation_id.instance.value <= start.instance.value && result.size() < limit); + while(itr != index_end && itr != itr_end && itr != index_start && result.size() < limit) + { + if(itr->account == account) + result.push_back(itr->operation_id(db)); + --itr; } return result; } From bc1422e5bc383c02b52e8bab5e1e4c4d54011767 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Tue, 13 Feb 2018 23:08:29 -0300 Subject: [PATCH 05/16] make output compatible with original call --- libraries/app/api.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index afd69a9f44..a7d1e1e71b 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -305,6 +305,7 @@ namespace graphene { namespace app { const auto& stats = account(db).statistics(db); if( stats.most_recent_op == account_transaction_history_id_type() ) return result; if( start.instance.value < stop.instance.value) return result; + if( start.instance.value == stop.instance.value && start != operation_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; @@ -313,14 +314,14 @@ namespace graphene { namespace app { const auto& by_op_idx = hist_idx.indices().get(); auto index_end = by_op_idx.end(); - auto index_start = by_op_idx.begin(); - auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); - auto itr_end = by_op_idx.upper_bound(boost::make_tuple(account, stop)); + auto itr = by_op_idx.upper_bound(boost::make_tuple(account, start)); + auto itr_end = by_op_idx.lower_bound(boost::make_tuple(account, stop)); + itr_end--; - while(itr != index_end && itr != itr_end && itr != index_start && result.size() < limit) + while(itr != index_end && itr != itr_end && result.size() < limit) { - if(itr->account == account) + if(itr->account == account && itr->operation_id.instance.value <= start.instance.value) result.push_back(itr->operation_id(db)); --itr; } From 2bd1706972c7407e02a549624e2efc01d7514818 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Wed, 14 Feb 2018 12:50:04 -0300 Subject: [PATCH 06/16] change loop and checks --- libraries/app/api.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index a7d1e1e71b..0489e464ba 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -309,21 +309,20 @@ namespace graphene { namespace app { const account_transaction_history_object* node = &stats.most_recent_op(db); if( start == operation_history_id_type() ) start = node->operation_id; + if( start > node->operation_id ) + start = node->operation_id; const auto& hist_idx = db.get_index_type(); const auto& by_op_idx = hist_idx.indices().get(); - auto index_end = by_op_idx.end(); + auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); - auto itr = by_op_idx.upper_bound(boost::make_tuple(account, start)); - auto itr_end = by_op_idx.lower_bound(boost::make_tuple(account, stop)); - itr_end--; - - while(itr != index_end && itr != itr_end && result.size() < limit) + while(itr != index_end && result.size() < limit) { - if(itr->account == account && itr->operation_id.instance.value <= start.instance.value) - result.push_back(itr->operation_id(db)); - --itr; + if(itr->account == account) + result.push_back(itr->operation_id(db)); + --itr; + if(itr->operation_id.instance.value <= stop.instance.value && itr->operation_id.instance.value != 0) break; } return result; } From b9a118b50c0786f2ddab295cd51fe4c8213a000a Mon Sep 17 00:00:00 2001 From: Alfredo Date: Fri, 16 Feb 2018 01:43:50 -0300 Subject: [PATCH 07/16] refactor with test cases --- libraries/app/api.cpp | 14 +- tests/tests/history_api_tests.cpp | 315 ++++++++++++++++++++++++++++++ 2 files changed, 323 insertions(+), 6 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 0489e464ba..f02fa16245 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -304,26 +304,28 @@ namespace graphene { namespace app { vector result; const auto& stats = account(db).statistics(db); if( stats.most_recent_op == account_transaction_history_id_type() ) return result; - if( start.instance.value < stop.instance.value) return result; - if( start.instance.value == stop.instance.value && start != operation_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; - if( start > node->operation_id ) + if( start.instance.value > node->operation_id.instance.value ) start = node->operation_id; const auto& hist_idx = db.get_index_type(); const auto& by_op_idx = hist_idx.indices().get(); auto index_end = by_op_idx.end(); + auto index_start = by_op_idx.begin(); auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); - while(itr != index_end && result.size() < limit) + while(itr != index_end && itr != index_start && itr->operation_id.instance.value > stop.instance.value && result.size() < limit) { - if(itr->account == account) + if(itr->account == account && itr->operation_id.instance.value <= start.instance.value) result.push_back(itr->operation_id(db)); --itr; - if(itr->operation_id.instance.value <= stop.instance.value && itr->operation_id.instance.value != 0) break; } + if(stop.instance.value == 0 && result.size() < limit && itr->account == account) { + result.push_back(index_start->operation_id(db)); + } + return result; } diff --git a/tests/tests/history_api_tests.cpp b/tests/tests/history_api_tests.cpp index 5ef1067b70..4cc98a2bca 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -34,6 +34,8 @@ #include #include +#include + #include #include @@ -62,6 +64,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 +75,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,12 +86,323 @@ 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 + + create_bitasset("USD", account_id_type()); // create op 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(); + fc::usleep(fc::milliseconds(2000)); + + // f(A, 0, 4, 9) = { 5, 3, 1, 0 } + vector 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 + GRAPHENE_REQUIRE_THROW(hist_api.get_account_history(account_id_type(18), operation_history_id_type(0), 4, operation_history_id_type(0)), fc::exception); + 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(); + fc::usleep(fc::milliseconds(2000)); + + // 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(get_account_history_operations) { try { graphene::app::history_api hist_api(app); From 7a9e2639e38401838f7877f13cc53f9cb912f35b Mon Sep 17 00:00:00 2001 From: Alfredo Date: Fri, 16 Feb 2018 13:38:34 -0300 Subject: [PATCH 08/16] remove early check, readd break, op 0 case change --- libraries/app/api.cpp | 4 ++-- tests/tests/history_api_tests.cpp | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index f02fa16245..90fd7f8440 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -303,7 +303,6 @@ namespace graphene { namespace app { 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; @@ -321,8 +320,9 @@ namespace graphene { namespace app { if(itr->account == account && itr->operation_id.instance.value <= start.instance.value) result.push_back(itr->operation_id(db)); --itr; + if(itr->account != account && itr->operation_id.instance.value <= stop.instance.value) break; } - if(stop.instance.value == 0 && result.size() < limit && itr->account == account) { + if(stop.instance.value == 0 && result.size() < limit && index_start->account == account) { result.push_back(index_start->operation_id(db)); } diff --git a/tests/tests/history_api_tests.cpp b/tests/tests/history_api_tests.cpp index 4cc98a2bca..5e04c688b7 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -100,7 +100,17 @@ BOOST_AUTO_TEST_CASE(get_account_history_additional) { // 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 + GRAPHENE_REQUIRE_THROW(hist_api.get_account_history(account_id_type(), operation_history_id_type(0), 4, operation_history_id_type(0)), fc::exception); + create_bitasset("USD", account_id_type()); // create op 0 + generate_block(); + // what if the account only has one history entry and it is 0? + vector 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; @@ -111,10 +121,9 @@ BOOST_AUTO_TEST_CASE(get_account_history_additional) { create_bitasset("OIL", dan.id); // create op 6 generate_block(); - fc::usleep(fc::milliseconds(2000)); // f(A, 0, 4, 9) = { 5, 3, 1, 0 } - vector histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type(9)); + 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); @@ -370,14 +379,12 @@ BOOST_AUTO_TEST_CASE(get_account_history_additional) { // non existent account GRAPHENE_REQUIRE_THROW(hist_api.get_account_history(account_id_type(18), operation_history_id_type(0), 4, operation_history_id_type(0)), fc::exception); - 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(); - fc::usleep(fc::milliseconds(2000)); // 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)); From f3156c3ea6f29eebc8d503eb73317871744cc888 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Fri, 16 Feb 2018 16:17:47 -0300 Subject: [PATCH 09/16] remove unused headers --- tests/tests/history_api_tests.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/tests/history_api_tests.cpp b/tests/tests/history_api_tests.cpp index 5e04c688b7..60a6484093 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -25,16 +25,6 @@ #include #include -#include -#include - -#include -#include -#include -#include -#include - -#include #include From 7439b62a09b806b5445ed67aa7bf10a2dc26beef Mon Sep 17 00:00:00 2001 From: Alfredo Date: Fri, 16 Feb 2018 20:42:51 -0300 Subject: [PATCH 10/16] handle exceptions, remove redundant checks --- libraries/app/api.cpp | 11 ++++++----- tests/tests/history_api_tests.cpp | 8 +++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 90fd7f8440..3a50e5d6d9 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -302,8 +302,10 @@ namespace graphene { namespace app { const auto& db = *_app.chain_database(); FC_ASSERT( limit <= 100 ); vector result; - const auto& stats = account(db).statistics(db); - const account_transaction_history_object* node = &stats.most_recent_op(db); + account_statistics_object stats; + try { stats = account(db).statistics(db); } catch(...) { return result; } + const account_transaction_history_object* node; + try { node = &stats.most_recent_op(db); } catch(...) { return result; } if( start == operation_history_id_type() ) start = node->operation_id; if( start.instance.value > node->operation_id.instance.value ) @@ -311,16 +313,15 @@ namespace graphene { namespace app { const auto& hist_idx = db.get_index_type(); const auto& by_op_idx = hist_idx.indices().get(); - auto index_end = by_op_idx.end(); auto index_start = by_op_idx.begin(); auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); - while(itr != index_end && itr != index_start && itr->operation_id.instance.value > stop.instance.value && result.size() < limit) + while(itr != index_start && itr->operation_id.instance.value > stop.instance.value && result.size() < limit) { if(itr->account == account && itr->operation_id.instance.value <= start.instance.value) result.push_back(itr->operation_id(db)); --itr; - if(itr->account != account && itr->operation_id.instance.value <= stop.instance.value) break; + if(itr->account != account) break; } if(stop.instance.value == 0 && result.size() < limit && index_start->account == account) { result.push_back(index_start->operation_id(db)); diff --git a/tests/tests/history_api_tests.cpp b/tests/tests/history_api_tests.cpp index 60a6484093..397cccf4af 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -91,12 +91,13 @@ BOOST_AUTO_TEST_CASE(get_account_history_additional) { // 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 - GRAPHENE_REQUIRE_THROW(hist_api.get_account_history(account_id_type(), operation_history_id_type(0), 4, operation_history_id_type(0)), fc::exception); + 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? - vector histories = hist_api.get_account_history(account_id_type(), operation_history_id_type(), 4, operation_history_id_type()); + 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); @@ -368,7 +369,8 @@ BOOST_AUTO_TEST_CASE(get_account_history_additional) { BOOST_CHECK_EQUAL(histories.size(), 0); // non existent account - GRAPHENE_REQUIRE_THROW(hist_api.get_account_history(account_id_type(18), operation_history_id_type(0), 4, operation_history_id_type(0)), fc::exception); + 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"); From 18e498fdeac0bfbce2da70f83adc62151bf500d3 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Sun, 18 Feb 2018 11:16:49 -0300 Subject: [PATCH 11/16] add track-account tests --- tests/common/database_fixture.cpp | 9 +++++- tests/tests/history_api_tests.cpp | 52 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index d7b79fe19f..2746946761 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -24,6 +24,7 @@ #include #include +# #include #include @@ -93,7 +94,13 @@ 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))); + } 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 397cccf4af..06f347e04f 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -402,6 +402,58 @@ BOOST_AUTO_TEST_CASE(get_account_history_additional) { 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(get_account_history_operations) { try { graphene::app::history_api hist_api(app); From 7164aa802b1464055b436011b15800dc75bb09f8 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Mon, 19 Feb 2018 13:21:42 -0300 Subject: [PATCH 12/16] fix operation 0 case --- libraries/app/api.cpp | 4 +-- tests/common/database_fixture.cpp | 10 ++++++ tests/tests/history_api_tests.cpp | 60 +++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 3a50e5d6d9..de5bdfa176 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -323,8 +323,8 @@ namespace graphene { namespace app { --itr; if(itr->account != account) break; } - if(stop.instance.value == 0 && result.size() < limit && index_start->account == account) { - result.push_back(index_start->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 2746946761..51773f7c7f 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -101,6 +101,16 @@ database_fixture::database_fixture() 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 06f347e04f..53b3ce799b 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -453,6 +453,66 @@ BOOST_AUTO_TEST_CASE(track_account) { 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; + } +} BOOST_AUTO_TEST_CASE(get_account_history_operations) { try { From e00f261d4004199c5384f414be8e0e4cbcebf127 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Mon, 19 Feb 2018 20:35:14 -0300 Subject: [PATCH 13/16] change while to check account and simplify body --- libraries/app/api.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index de5bdfa176..5f21cebb19 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -316,12 +316,11 @@ namespace graphene { namespace app { auto index_start = by_op_idx.begin(); auto itr = by_op_idx.lower_bound(boost::make_tuple(account, start)); - while(itr != index_start && itr->operation_id.instance.value > stop.instance.value && result.size() < limit) + while(itr != index_start && itr->account == account && itr->operation_id.instance.value > stop.instance.value && result.size() < limit) { - if(itr->account == account && itr->operation_id.instance.value <= start.instance.value) + if(itr->operation_id.instance.value <= start.instance.value) result.push_back(itr->operation_id(db)); --itr; - if(itr->account != account) break; } if(stop.instance.value == 0 && result.size() < limit && itr->account == account) { result.push_back(itr->operation_id(db)); From 753b899f80cee7ac4a235eef229d103011321689 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Tue, 20 Feb 2018 12:14:08 -0300 Subject: [PATCH 14/16] header tests in 1 block --- libraries/app/api.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 5f21cebb19..5924f39051 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -302,14 +302,14 @@ namespace graphene { namespace app { const auto& db = *_app.chain_database(); FC_ASSERT( limit <= 100 ); vector result; - account_statistics_object stats; - try { stats = account(db).statistics(db); } catch(...) { return result; } - const account_transaction_history_object* node; - try { node = &stats.most_recent_op(db); } catch(...) { return result; } - if( start == operation_history_id_type() ) - start = node->operation_id; - if( start.instance.value > node->operation_id.instance.value ) - start = node->operation_id; + try { + optional stats; + optional node; + stats = account(db).statistics(db); + node = stats->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(); From a0b87d26e6ed9abc39dffcfce93963363593ca0f Mon Sep 17 00:00:00 2001 From: Alfredo Date: Tue, 20 Feb 2018 18:40:04 -0300 Subject: [PATCH 15/16] changes inside try --- libraries/app/api.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 5924f39051..786c7a9f31 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -303,12 +303,9 @@ namespace graphene { namespace app { FC_ASSERT( limit <= 100 ); vector result; try { - optional stats; - optional node; - stats = account(db).statistics(db); - node = stats->most_recent_op(db); - if(start == operation_history_id_type() || start.instance.value > node->operation_id.instance.value) - start = node->operation_id; + 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(); From efe3310e1bcd8e3bc2e714bca0dd360816516af6 Mon Sep 17 00:00:00 2001 From: Alfredo Date: Wed, 21 Feb 2018 12:31:04 -0300 Subject: [PATCH 16/16] remove unintended character --- tests/common/database_fixture.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index 51773f7c7f..edab85706e 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -24,7 +24,6 @@ #include #include -# #include #include