Skip to content

Commit

Permalink
Merge pull request #1177 from bitshares/1176-cli-account-his
Browse files Browse the repository at this point in the history
Fix CLI get_account_history pagination issue #1176
  • Loading branch information
abitmore authored Jul 27, 2018
2 parents 1f625f8 + 883e50b commit 1608ce0
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 4 deletions.
32 changes: 28 additions & 4 deletions libraries/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2947,23 +2947,47 @@ vector<operation_detail> wallet_api::get_account_history(string name, int limit)

while( limit > 0 )
{
bool skip_first_row = false;
operation_history_id_type start;
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(name, operation_history_id_type(), std::min(100,limit), start);
for( auto& o : current ) {
vector<operation_history_object> current = my->_remote_hist->get_account_history( name, 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 } );
}
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;
Expand Down
89 changes: 89 additions & 0 deletions tests/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ std::shared_ptr<graphene::app::application> start_application(fc::temp_directory
cfg.emplace("seed-nodes", boost::program_options::variable_value(string("[]"), false));
app1->initialize(app_dir.path(), cfg);

app1->initialize_plugins(cfg);
app1->startup_plugins();

app1->startup();
fc::usleep(fc::milliseconds(500));
return app1;
Expand Down Expand Up @@ -483,3 +486,89 @@ BOOST_AUTO_TEST_CASE( cli_confidential_tx_test )
}
app1->shutdown();
}

/******
* Check account history pagination (see bitshares-core/issue/1176)
*/
BOOST_AUTO_TEST_CASE( account_history_pagination )
{
using namespace graphene::chain;
using namespace graphene::app;
std::shared_ptr<graphene::app::application> app1;
try
{
fc::temp_directory app_dir ( graphene::utilities::temp_directory_path() );

int server_port_number = 0;
app1 = start_application(app_dir, server_port_number);

// connect to the server
client_connection con(app1, app_dir, server_port_number);

// set wallet password
BOOST_TEST_MESSAGE("Setting wallet password");
con.wallet_api_ptr->set_password("supersecret");
con.wallet_api_ptr->unlock("supersecret");

// import Nathan account
BOOST_TEST_MESSAGE("Importing nathan key");
std::vector<std::string> nathan_keys{"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"};
BOOST_CHECK_EQUAL(nathan_keys[0], "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3");
BOOST_CHECK(con.wallet_api_ptr->import_key("nathan", nathan_keys[0]));

BOOST_TEST_MESSAGE("Importing nathan's balance");
std::vector<signed_transaction> import_txs = con.wallet_api_ptr->import_balance("nathan", nathan_keys, true);
account_object nathan_acct_before_upgrade = con.wallet_api_ptr->get_account("nathan");

// upgrade nathan
BOOST_TEST_MESSAGE("Upgrading Nathan to LTM");
signed_transaction upgrade_tx = con.wallet_api_ptr->upgrade_account("nathan", true);
account_object nathan_acct_after_upgrade = con.wallet_api_ptr->get_account("nathan");

// verify that the upgrade was successful
BOOST_CHECK_PREDICATE( std::not_equal_to<uint32_t>(),
(nathan_acct_before_upgrade.membership_expiration_date.sec_since_epoch())
(nathan_acct_after_upgrade.membership_expiration_date.sec_since_epoch()) );
BOOST_CHECK(nathan_acct_after_upgrade.is_lifetime_member());

// create a new account
graphene::wallet::brain_key_info bki = con.wallet_api_ptr->suggest_brain_key();
BOOST_CHECK(!bki.brain_priv_key.empty());
signed_transaction create_acct_tx = con.wallet_api_ptr->create_account_with_brain_key(
bki.brain_priv_key, "jmjatlanta", "nathan", "nathan", true);
// save the private key for this new account in the wallet file
BOOST_CHECK(con.wallet_api_ptr->import_key("jmjatlanta", bki.wif_priv_key));
con.wallet_api_ptr->save_wallet_file(con.wallet_filename);

// attempt to give jmjatlanta some bitsahres
BOOST_TEST_MESSAGE("Transferring bitshares from Nathan to jmjatlanta");
for(int i = 1; i <= 200; i++)
{
signed_transaction transfer_tx = con.wallet_api_ptr->transfer("nathan", "jmjatlanta", std::to_string(i),
"1.3.0", "Here are some BTS 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(201, 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;
}
app1->shutdown();

}

0 comments on commit 1608ce0

Please sign in to comment.