Merge pull request #109 from peerplays-network/feature/GRPH-86

[GRPH-86] fix duplicate ops returned in get_account_history
This commit is contained in:
Alfredo Garcia 2019-09-18 14:57:22 -03:00 committed by GitHub
commit 2e85219ca4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 8 deletions

View file

@ -3449,30 +3449,54 @@ asset wallet_api::get_lottery_balance( asset_id_type lottery_id )const
return my->_remote_db->get_lottery_balance( lottery_id ); return my->_remote_db->get_lottery_balance( lottery_id );
} }
vector<operation_detail> wallet_api::get_account_history(string name, int limit)const vector<operation_detail> wallet_api::get_account_history(string name, int limit) const
{ {
vector<operation_detail> result; vector<operation_detail> result;
auto account_id = get_account(name).get_id(); auto account_id = get_account(name).get_id();
while( limit > 0 ) while (limit > 0)
{ {
bool skip_first_row = false;
operation_history_id_type start; operation_history_id_type start;
if( result.size() ) if (result.size())
{ {
start = result.back().op.id; start = result.back().op.id;
start = start + 1; if (start == operation_history_id_type()) // no more data
break;
start = start + (-1);
if (start == operation_history_id_type()) // will return most recent history if directly call remote API with this
{
start = start + 1;
skip_first_row = true;
}
} }
int page_limit = skip_first_row ? std::min(100, limit + 1) : std::min(100, limit);
vector<operation_history_object> current = my->_remote_hist->get_account_history(account_id, operation_history_id_type(), std::min(100,limit), start); vector<operation_history_object> current = my->_remote_hist->get_account_history(account_id, operation_history_id_type(),
for( auto& o : current ) { page_limit, start);
bool first_row = true;
for (auto &o : current)
{
if (first_row)
{
first_row = false;
if (skip_first_row)
{
continue;
}
}
std::stringstream ss; std::stringstream ss;
auto memo = o.op.visit(detail::operation_printer(ss, *my, o.result)); auto memo = o.op.visit(detail::operation_printer(ss, *my, o.result));
result.push_back( operation_detail{ memo, ss.str(), o } ); result.push_back(operation_detail{memo, ss.str(), o});
} }
if( (int)current.size() < std::min(100,limit) )
if (int(current.size()) < page_limit)
break; break;
limit -= current.size(); limit -= current.size();
if (skip_first_row)
++limit;
} }
return result; return result;

View file

@ -27,6 +27,7 @@
#include <graphene/utilities/tempdir.hpp> #include <graphene/utilities/tempdir.hpp>
#include <graphene/bookie/bookie_plugin.hpp> #include <graphene/bookie/bookie_plugin.hpp>
#include <graphene/account_history/account_history_plugin.hpp>
#include <graphene/egenesis/egenesis.hpp> #include <graphene/egenesis/egenesis.hpp>
#include <graphene/wallet/wallet.hpp> #include <graphene/wallet/wallet.hpp>
@ -117,6 +118,7 @@ std::shared_ptr<graphene::app::application> start_application(fc::temp_directory
std::shared_ptr<graphene::app::application> app1(new graphene::app::application{}); std::shared_ptr<graphene::app::application> app1(new graphene::app::application{});
app1->register_plugin< graphene::bookie::bookie_plugin>(); app1->register_plugin< graphene::bookie::bookie_plugin>();
app1->register_plugin<graphene::account_history::account_history_plugin>();
app1->startup_plugins(); app1->startup_plugins();
boost::program_options::variables_map cfg; boost::program_options::variables_map cfg;
#ifdef _WIN32 #ifdef _WIN32
@ -438,3 +440,42 @@ BOOST_FIXTURE_TEST_CASE( cli_vote_for_2_witnesses, cli_fixture )
throw; throw;
} }
} }
///////////////////////
// Check account history pagination
///////////////////////
BOOST_FIXTURE_TEST_CASE( account_history_pagination, cli_fixture )
{
try
{
INVOKE(create_new_account);
// attempt to give jmjatlanta some peerplay
BOOST_TEST_MESSAGE("Transferring peerplay from Nathan to jmjatlanta");
for(int i = 1; i <= 199; i++)
{
signed_transaction transfer_tx = con.wallet_api_ptr->transfer("nathan", "jmjatlanta", std::to_string(i),
"1.3.0", "Here are some CORE token for your new account", true);
}
BOOST_CHECK(generate_block(app1));
// now get account history and make sure everything is there (and no duplicates)
std::vector<graphene::wallet::operation_detail> history = con.wallet_api_ptr->get_account_history("jmjatlanta", 300);
BOOST_CHECK_EQUAL(201u, history.size() );
std::set<object_id_type> operation_ids;
for(auto& op : history)
{
if( operation_ids.find(op.op.id) != operation_ids.end() )
{
BOOST_FAIL("Duplicate found");
}
operation_ids.insert(op.op.id);
}
} catch( fc::exception& e ) {
edump((e.to_detail_string()));
throw;
}
}