Fixed duplicate ops returned from get_account_history

This commit is contained in:
Sandip Patel 2019-09-04 12:45:43 +05:30
parent 96161db8a5
commit dfba08536b
2 changed files with 71 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 );
}
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;
auto account_id = get_account(name).get_id();
while( limit > 0 )
while (limit > 0)
{
bool skip_first_row = false;
operation_history_id_type start;
if( result.size() )
if (result.size())
{
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);
for( auto& o : current ) {
vector<operation_history_object> current = my->_remote_hist->get_account_history(account_id, operation_history_id_type(),
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;
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;
limit -= current.size();
if (skip_first_row)
++limit;
}
return result;

View file

@ -438,3 +438,42 @@ BOOST_FIXTURE_TEST_CASE( cli_vote_for_2_witnesses, cli_fixture )
throw;
}
}
///////////////////////
// Check account history pagination (see peerplay-core/issue/1176)
///////////////////////
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;
}
}