Merge commit '568ceb189eca96e77e38c4059b83a504008d7e91' into betting
This commit is contained in:
commit
3238ea735f
19 changed files with 229 additions and 104 deletions
|
|
@ -129,6 +129,10 @@ else( WIN32 ) # Apple AND Linux
|
|||
|
||||
if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-builtin-memcmp" )
|
||||
elseif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
||||
if( CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.0.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.0.0 )
|
||||
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-partial-specialization" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if( "${CMAKE_GENERATOR}" STREQUAL "Ninja" )
|
||||
|
|
|
|||
0
CONTRIBUTORS.txt
Normal file
0
CONTRIBUTORS.txt
Normal file
|
|
@ -1,5 +1,5 @@
|
|||
Copyright (c) 2015-2016 Cryptonomex Inc.
|
||||
Copyright (c) 2015-2017 contributors
|
||||
Copyright (c) 2015-2016 Cryptonomex Inc. <contact@cryptonomex.com>
|
||||
Copyright (c) 2015-2017 contributors <CONTRIBUTORS.txt>
|
||||
|
||||
The MIT License
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ Getting Started
|
|||
Build instructions and additional documentation are available in the
|
||||
[wiki](https://github.com/bitshares/bitshares-core/wiki).
|
||||
|
||||
We recommend building on Ubuntu 16.04 LTS, and the build dependencies may be installed with:
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install autoconf cmake git libboost-all-dev libssl-dev
|
||||
|
||||
To build after all dependencies are installed:
|
||||
|
||||
git clone https://github.com/bitshares/bitshares-core.git
|
||||
|
|
@ -220,5 +225,5 @@ FAQ
|
|||
|
||||
License
|
||||
-------
|
||||
BitShares Core is under the MIT license. See [LICENSE](https://github.com/bitshares/bitshares-core/blob/master/LICENSE)
|
||||
BitShares Core is under the MIT license. See [LICENSE](https://github.com/bitshares/bitshares-core/blob/master/LICENSE.txt)
|
||||
for more information.
|
||||
|
|
|
|||
2
docs
2
docs
|
|
@ -1 +1 @@
|
|||
Subproject commit 981d1ef1eb35e89bb9a9423c1762427fe8ef07cc
|
||||
Subproject commit d99948280c6ae98a337be8ae93ab7182896d525c
|
||||
|
|
@ -1 +1 @@
|
|||
2.0.170410
|
||||
2.0.170522
|
||||
|
|
|
|||
|
|
@ -512,21 +512,26 @@ namespace graphene { namespace app {
|
|||
FC_ASSERT(limit <= 100);
|
||||
vector<operation_history_object> result;
|
||||
if( start == 0 )
|
||||
start = account(db).statistics(db).total_ops;
|
||||
else start = min( account(db).statistics(db).total_ops, start );
|
||||
const auto& hist_idx = db.get_index_type<account_transaction_history_index>();
|
||||
const auto& by_seq_idx = hist_idx.indices().get<by_seq>();
|
||||
|
||||
auto itr = by_seq_idx.upper_bound( boost::make_tuple( account, start ) );
|
||||
auto itr_stop = by_seq_idx.lower_bound( boost::make_tuple( account, stop ) );
|
||||
--itr;
|
||||
|
||||
while ( itr != itr_stop && result.size() < limit )
|
||||
start = account(db).statistics(db).total_ops;
|
||||
else
|
||||
start = min( account(db).statistics(db).total_ops, start );
|
||||
|
||||
|
||||
if( start >= stop && start > 0 && limit > 0 )
|
||||
{
|
||||
result.push_back( itr->operation_id(db) );
|
||||
--itr;
|
||||
const auto& hist_idx = db.get_index_type<account_transaction_history_index>();
|
||||
const auto& by_seq_idx = hist_idx.indices().get<by_seq>();
|
||||
|
||||
auto itr = by_seq_idx.upper_bound( boost::make_tuple( account, start ) );
|
||||
auto itr_stop = by_seq_idx.lower_bound( boost::make_tuple( account, stop ) );
|
||||
|
||||
do
|
||||
{
|
||||
--itr;
|
||||
result.push_back( itr->operation_id(db) );
|
||||
}
|
||||
while ( itr != itr_stop && result.size() < limit );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -164,9 +164,12 @@ namespace detail {
|
|||
vector<string> seeds = {
|
||||
"104.236.144.84:1777", // puppies (USA)
|
||||
"128.199.143.47:2015", // Harvey (Singapore)
|
||||
"212.47.249.84:50696", // iHashFury (France)
|
||||
"23.92.53.182:1776", // sahkan (USA)
|
||||
"192.121.166.162:1776", // sahkan (UK)
|
||||
"51.15.61.160:1776", // lafona (France)
|
||||
"bts-seed1.abit-more.com:62015", // abit (China)
|
||||
"node.blckchnd.com:4243", // blckchnd (Germany)
|
||||
"seed.bitsharesdex.com:50696", // iHashFury (Europe)
|
||||
"seed.bitsharesnodes.com:1776", // wackou (Netherlands)
|
||||
"seed.blocktrades.us:1776", // BlockTrades (USA)
|
||||
"seed.cubeconnex.com:1777", // cube (USA)
|
||||
|
|
@ -384,79 +387,67 @@ namespace detail {
|
|||
}
|
||||
_chain_db->add_checkpoints( loaded_checkpoints );
|
||||
|
||||
if( _options->count("replay-blockchain") )
|
||||
bool replay = false;
|
||||
std::string replay_reason = "reason not provided";
|
||||
|
||||
// never replay if data dir is empty
|
||||
if( fc::exists( _data_dir ) && fc::directory_iterator( _data_dir ) != fc::directory_iterator() )
|
||||
{
|
||||
ilog("Replaying blockchain on user request.");
|
||||
_chain_db->reindex(_data_dir/"blockchain", initial_state());
|
||||
} else if( clean ) {
|
||||
|
||||
auto is_new = [&]() -> bool
|
||||
if( _options->count("replay-blockchain") )
|
||||
{
|
||||
// directory doesn't exist
|
||||
if( !fc::exists( _data_dir ) )
|
||||
return true;
|
||||
// if directory exists but is empty, return true; else false.
|
||||
return ( fc::directory_iterator( _data_dir ) == fc::directory_iterator() );
|
||||
};
|
||||
|
||||
auto is_outdated = [&]() -> bool
|
||||
replay = true;
|
||||
replay_reason = "replay-blockchain argument specified";
|
||||
}
|
||||
else if( !clean )
|
||||
{
|
||||
if( !fc::exists( _data_dir / "db_version" ) )
|
||||
return true;
|
||||
std::string version_str;
|
||||
fc::read_file_contents( _data_dir / "db_version", version_str );
|
||||
return (version_str != GRAPHENE_CURRENT_DB_VERSION);
|
||||
};
|
||||
|
||||
bool need_reindex = (!is_new() && is_outdated());
|
||||
std::string reindex_reason = "version upgrade";
|
||||
|
||||
if( !need_reindex )
|
||||
replay = true;
|
||||
replay_reason = "unclean shutdown detected";
|
||||
}
|
||||
else if( !fc::exists( _data_dir / "db_version" ) )
|
||||
{
|
||||
try
|
||||
replay = true;
|
||||
replay_reason = "db_version file not found";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string version_string;
|
||||
fc::read_file_contents( _data_dir / "db_version", version_string );
|
||||
|
||||
if( version_string != GRAPHENE_CURRENT_DB_VERSION )
|
||||
{
|
||||
_chain_db->open(_data_dir / "blockchain", initial_state);
|
||||
}
|
||||
catch( const fc::exception& e )
|
||||
{
|
||||
ilog( "caught exception ${e} in open()", ("e", e.to_detail_string()) );
|
||||
need_reindex = true;
|
||||
reindex_reason = "exception in open()";
|
||||
replay = true;
|
||||
replay_reason = "db_version file content mismatch";
|
||||
}
|
||||
}
|
||||
|
||||
if( need_reindex )
|
||||
{
|
||||
ilog("Replaying blockchain due to ${reason}", ("reason", reindex_reason) );
|
||||
|
||||
fc::remove_all( _data_dir / "db_version" );
|
||||
_chain_db->reindex(_data_dir / "blockchain", initial_state());
|
||||
|
||||
// doing this down here helps ensure that DB will be wiped
|
||||
// if any of the above steps were interrupted on a previous run
|
||||
if( !fc::exists( _data_dir / "db_version" ) )
|
||||
{
|
||||
std::ofstream db_version(
|
||||
(_data_dir / "db_version").generic_string().c_str(),
|
||||
std::ios::out | std::ios::binary | std::ios::trunc );
|
||||
std::string version_string = GRAPHENE_CURRENT_DB_VERSION;
|
||||
db_version.write( version_string.c_str(), version_string.size() );
|
||||
db_version.close();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wlog("Detected unclean shutdown. Replaying blockchain...");
|
||||
_chain_db->reindex(_data_dir / "blockchain", initial_state());
|
||||
}
|
||||
|
||||
if (!_options->count("genesis-json") &&
|
||||
_chain_db->get_chain_id() != graphene::egenesis::get_egenesis_chain_id()) {
|
||||
elog("Detected old database. Nuking and starting over.");
|
||||
_chain_db->wipe(_data_dir / "blockchain", true);
|
||||
_chain_db.reset();
|
||||
_chain_db = std::make_shared<chain::database>();
|
||||
_chain_db->add_checkpoints(loaded_checkpoints);
|
||||
_chain_db->open(_data_dir / "blockchain", initial_state);
|
||||
if( !replay )
|
||||
{
|
||||
try
|
||||
{
|
||||
_chain_db->open( _data_dir / "blockchain", initial_state );
|
||||
}
|
||||
catch( const fc::exception& e )
|
||||
{
|
||||
ilog( "Caught exception ${e} in open()", ("e", e.to_detail_string()) );
|
||||
|
||||
replay = true;
|
||||
replay_reason = "exception in open()";
|
||||
}
|
||||
}
|
||||
|
||||
if( replay )
|
||||
{
|
||||
ilog( "Replaying blockchain due to: ${reason}", ("reason", replay_reason) );
|
||||
|
||||
fc::remove_all( _data_dir / "db_version" );
|
||||
_chain_db->reindex( _data_dir / "blockchain", initial_state() );
|
||||
|
||||
const auto mode = std::ios::out | std::ios::binary | std::ios::trunc;
|
||||
std::ofstream db_version( (_data_dir / "db_version").generic_string().c_str(), mode );
|
||||
std::string version_string = GRAPHENE_CURRENT_DB_VERSION;
|
||||
db_version.write( version_string.c_str(), version_string.size() );
|
||||
db_version.close();
|
||||
}
|
||||
|
||||
if( _options->count("force-validate") )
|
||||
|
|
@ -844,6 +835,9 @@ namespace detail {
|
|||
return synopsis; // we have no blocks
|
||||
}
|
||||
|
||||
if( low_block_num == 0)
|
||||
low_block_num = 1;
|
||||
|
||||
// at this point:
|
||||
// low_block_num is the block before the first block we can undo,
|
||||
// non_fork_high_block_num is the block before the fork (if the peer is on a fork, or otherwise it is the same as high_block_num)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
|
|||
|
||||
// Blocks and transactions
|
||||
optional<block_header> get_block_header(uint32_t block_num)const;
|
||||
map<uint32_t, optional<block_header>> get_block_header_batch(const vector<uint32_t> block_nums)const;
|
||||
optional<signed_block> get_block(uint32_t block_num)const;
|
||||
processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const;
|
||||
|
||||
|
|
@ -369,6 +370,20 @@ optional<block_header> database_api_impl::get_block_header(uint32_t block_num) c
|
|||
return *result;
|
||||
return {};
|
||||
}
|
||||
map<uint32_t, optional<block_header>> database_api::get_block_header_batch(const vector<uint32_t> block_nums)const
|
||||
{
|
||||
return my->get_block_header_batch( block_nums );
|
||||
}
|
||||
|
||||
map<uint32_t, optional<block_header>> database_api_impl::get_block_header_batch(const vector<uint32_t> block_nums) const
|
||||
{
|
||||
map<uint32_t, optional<block_header>> results;
|
||||
for (const uint32_t block_num : block_nums)
|
||||
{
|
||||
results[block_num] = get_block_header(block_num);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
optional<signed_block> database_api::get_block(uint32_t block_num)const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -163,6 +163,14 @@ class database_api
|
|||
*/
|
||||
optional<block_header> get_block_header(uint32_t block_num)const;
|
||||
|
||||
/**
|
||||
* @brief Retrieve multiple block header by block numbers
|
||||
* @param block_num vector containing heights of the block whose header should be returned
|
||||
* @return array of headers of the referenced blocks, or null if no matching block was found
|
||||
*/
|
||||
map<uint32_t, optional<block_header>> get_block_header_batch(const vector<uint32_t> block_nums)const;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Retrieve a full, signed block
|
||||
* @param block_num Height of the block to be returned
|
||||
|
|
@ -622,6 +630,7 @@ FC_API(graphene::app::database_api,
|
|||
|
||||
// Blocks and transactions
|
||||
(get_block_header)
|
||||
(get_block_header_batch)
|
||||
(get_block)
|
||||
(get_transaction)
|
||||
(get_recent_transaction_by_id)
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ void database::_apply_block( const signed_block& next_block )
|
|||
* for transactions when validating broadcast transactions or
|
||||
* when building a block.
|
||||
*/
|
||||
apply_transaction( trx, skip | skip_transaction_signatures );
|
||||
apply_transaction( trx, skip );
|
||||
++_current_trx_in_block;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void database::reindex(fc::path data_dir, const genesis_state_type& initial_allo
|
|||
_undo_db.disable();
|
||||
for( uint32_t i = 1; i <= last_block_num; ++i )
|
||||
{
|
||||
if( i % 5000 == 0 ) std::cerr << " " << double(i*100)/last_block_num << "% "<<i << " of " <<last_block_num<<" \n";
|
||||
if( i % 10000 == 0 ) std::cerr << " " << double(i*100)/last_block_num << "% "<<i << " of " <<last_block_num<<" \n";
|
||||
fc::optional< signed_block > block = _block_id_to_block.fetch_by_number(i);
|
||||
if( !block.valid() )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -185,7 +185,18 @@ struct get_impacted_account_visitor
|
|||
{
|
||||
_impacted.insert( op.account_id );
|
||||
}
|
||||
|
||||
void operator()(const sport_create_operation&){}
|
||||
void operator()(const competitor_create_operation&){}
|
||||
void operator()(const event_group_create_operation&){}
|
||||
void operator()(const event_create_operation&){}
|
||||
void operator()(const betting_market_group_create_operation&){}
|
||||
void operator()(const betting_market_create_operation&){}
|
||||
void operator()(const bet_place_operation&){}
|
||||
void operator()(const betting_market_resolve_operation&){}
|
||||
void operator()(const betting_market_resolved_operation &){}
|
||||
void operator()(const bet_matched_operation &){}
|
||||
void operator()(const bet_cancel_operation&){}
|
||||
void operator()(const bet_canceled_operation &){}
|
||||
};
|
||||
|
||||
void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
|
||||
|
|
@ -389,4 +400,4 @@ void database::notify_changed_objects()
|
|||
}
|
||||
} FC_CAPTURE_AND_LOG( () ) }
|
||||
|
||||
} }
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 8eb2ccc1803e82a8312b08566b2cdda8b68dc249
|
||||
Subproject commit 7c88a95df11c16970412786e06d9b94b1aafddc4
|
||||
|
|
@ -4490,7 +4490,8 @@ namespace graphene { namespace net { namespace detail {
|
|||
error_message_stream << "\nStill waiting for port " << listen_endpoint.port() << " to become available\n";
|
||||
}
|
||||
std::string error_message = error_message_stream.str();
|
||||
ulog(error_message);
|
||||
wlog(error_message);
|
||||
std::cout << "\033[31m" << error_message;
|
||||
_delegate->error_encountered( error_message, fc::oexception() );
|
||||
fc::usleep( fc::seconds(5 ) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ class account_history_plugin_impl
|
|||
|
||||
account_history_plugin& _self;
|
||||
flat_set<account_id_type> _tracked_accounts;
|
||||
bool _partial_operations = false;
|
||||
primary_index< simple_index< operation_history_object > >* _oho_index;
|
||||
};
|
||||
|
||||
account_history_plugin_impl::~account_history_plugin_impl()
|
||||
|
|
@ -77,18 +79,35 @@ void account_history_plugin_impl::update_account_histories( const signed_block&
|
|||
const vector<optional< operation_history_object > >& hist = db.get_applied_operations();
|
||||
for( const optional< operation_history_object >& o_op : hist )
|
||||
{
|
||||
// add to the operation history index
|
||||
const auto& oho = db.create<operation_history_object>( [&]( operation_history_object& h )
|
||||
{
|
||||
if( o_op.valid() )
|
||||
h = *o_op;
|
||||
} );
|
||||
optional<operation_history_object> oho;
|
||||
|
||||
if( !o_op.valid() )
|
||||
auto create_oho = [&]() {
|
||||
return optional<operation_history_object>( db.create<operation_history_object>( [&]( operation_history_object& h )
|
||||
{
|
||||
if( o_op.valid() )
|
||||
h = *o_op;
|
||||
} ) );
|
||||
};
|
||||
|
||||
if (_partial_operations)
|
||||
{
|
||||
ilog( "removing failed operation with ID: ${id}", ("id", oho.id) );
|
||||
db.remove( oho );
|
||||
continue;
|
||||
if( !o_op.valid() )
|
||||
{
|
||||
_oho_index->use_next_id();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add to the operation history index
|
||||
oho = create_oho();
|
||||
|
||||
if( !o_op.valid() )
|
||||
{
|
||||
ilog( "removing failed operation with ID: ${id}", ("id", oho->id) );
|
||||
db.remove( *oho );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const operation_history_object& op = *o_op;
|
||||
|
|
@ -99,7 +118,10 @@ void account_history_plugin_impl::update_account_histories( const signed_block&
|
|||
operation_get_required_authorities( op.op, impacted, impacted, other );
|
||||
|
||||
if( op.op.which() == operation::tag< account_create_operation >::value )
|
||||
impacted.insert( oho.result.get<object_id_type>() );
|
||||
{
|
||||
if (!oho.valid()) { oho = create_oho(); }
|
||||
impacted.insert( oho->result.get<object_id_type>() );
|
||||
}
|
||||
else
|
||||
graphene::app::operation_get_impacted_accounts( op.op, impacted );
|
||||
|
||||
|
|
@ -110,6 +132,7 @@ void account_history_plugin_impl::update_account_histories( const signed_block&
|
|||
// for each operation this account applies to that is in the config link it into the history
|
||||
if( _tracked_accounts.size() == 0 )
|
||||
{
|
||||
if (!impacted.empty() && !oho.valid()) { oho = create_oho(); }
|
||||
for( auto& account_id : impacted )
|
||||
{
|
||||
// we don't do index_account_keys here anymore, because
|
||||
|
|
@ -118,7 +141,7 @@ void account_history_plugin_impl::update_account_histories( const signed_block&
|
|||
// add history
|
||||
const auto& stats_obj = account_id(db).statistics(db);
|
||||
const auto& ath = db.create<account_transaction_history_object>( [&]( account_transaction_history_object& obj ){
|
||||
obj.operation_id = oho.id;
|
||||
obj.operation_id = oho->id;
|
||||
obj.account = account_id;
|
||||
obj.sequence = stats_obj.total_ops+1;
|
||||
obj.next = stats_obj.most_recent_op;
|
||||
|
|
@ -135,10 +158,11 @@ void account_history_plugin_impl::update_account_histories( const signed_block&
|
|||
{
|
||||
if( impacted.find( account_id ) != impacted.end() )
|
||||
{
|
||||
if (!oho.valid()) { oho = create_oho(); }
|
||||
// add history
|
||||
const auto& stats_obj = account_id(db).statistics(db);
|
||||
const auto& ath = db.create<account_transaction_history_object>( [&]( account_transaction_history_object& obj ){
|
||||
obj.operation_id = oho.id;
|
||||
obj.operation_id = oho->id;
|
||||
obj.account = account_id;
|
||||
obj.sequence = stats_obj.total_ops+1;
|
||||
obj.next = stats_obj.most_recent_op;
|
||||
|
|
@ -150,6 +174,8 @@ void account_history_plugin_impl::update_account_histories( const signed_block&
|
|||
}
|
||||
}
|
||||
}
|
||||
if (_partial_operations && ! oho.valid())
|
||||
_oho_index->use_next_id();
|
||||
}
|
||||
}
|
||||
} // end namespace detail
|
||||
|
|
@ -180,6 +206,7 @@ void account_history_plugin::plugin_set_program_options(
|
|||
{
|
||||
cli.add_options()
|
||||
("track-account", boost::program_options::value<std::vector<std::string>>()->composing()->multitoken(), "Account ID to track history for (may specify multiple times)")
|
||||
("partial-operations", boost::program_options::value<bool>(), "Keep only those operations in memory that are related to account history tracking")
|
||||
;
|
||||
cfg.add(cli);
|
||||
}
|
||||
|
|
@ -187,10 +214,13 @@ void account_history_plugin::plugin_set_program_options(
|
|||
void account_history_plugin::plugin_initialize(const boost::program_options::variables_map& options)
|
||||
{
|
||||
database().applied_block.connect( [&]( const signed_block& b){ my->update_account_histories(b); } );
|
||||
database().add_index< primary_index< simple_index< operation_history_object > > >();
|
||||
my->_oho_index = database().add_index< primary_index< simple_index< operation_history_object > > >();
|
||||
database().add_index< primary_index< account_transaction_history_index > >();
|
||||
|
||||
LOAD_VALUE_SET(options, "track-account", my->_tracked_accounts, graphene::chain::account_id_type);
|
||||
if (options.count("partial-operations")) {
|
||||
my->_partial_operations = options["partial-operations"].as<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
void account_history_plugin::plugin_startup()
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ void bookie_plugin::plugin_set_program_options(
|
|||
void bookie_plugin::plugin_initialize(const boost::program_options::variables_map& options)
|
||||
{
|
||||
database().applied_block.connect( [&]( const signed_block& b){ my->on_block_applied(b); } );
|
||||
database().changed_objects.connect([&](const vector<object_id_type>& changed_object_ids){ my->on_objects_changed(changed_object_ids); });
|
||||
database().changed_objects.connect([&](const vector<object_id_type>& changed_object_ids, const fc::flat_set<graphene::chain::account_id_type>& impacted_accounts){ my->on_objects_changed(changed_object_ids); });
|
||||
auto event_index = database().add_index<primary_index<detail::persistent_event_object_index> >();
|
||||
event_index->add_secondary_index<detail::events_by_competitor_index>();
|
||||
|
||||
|
|
|
|||
|
|
@ -356,6 +356,15 @@ class wallet_api
|
|||
*/
|
||||
vector<operation_detail> get_account_history(string name, int limit)const;
|
||||
|
||||
/** Returns the relative operations on the named account from start number.
|
||||
*
|
||||
* @param name the name or id of the account
|
||||
* @param stop Sequence number of earliest operation.
|
||||
* @param limit the number of entries to return
|
||||
* @param start the sequence number where to start looping back throw the history
|
||||
* @returns a list of \c operation_history_objects
|
||||
*/
|
||||
vector<operation_detail> get_relative_account_history(string name, uint32_t stop, int limit, uint32_t start)const;
|
||||
|
||||
vector<bucket_object> get_market_history(string symbol, string symbol2, uint32_t bucket, fc::time_point_sec start, fc::time_point_sec end)const;
|
||||
vector<limit_order_object> get_limit_orders(string a, string b, uint32_t limit)const;
|
||||
|
|
@ -1718,6 +1727,7 @@ FC_API( graphene::wallet::wallet_api,
|
|||
(get_block)
|
||||
(get_account_count)
|
||||
(get_account_history)
|
||||
(get_relative_account_history)
|
||||
(is_public_key_registered)
|
||||
(get_market_history)
|
||||
(get_global_properties)
|
||||
|
|
|
|||
|
|
@ -2088,6 +2088,23 @@ public:
|
|||
|
||||
return ss.str();
|
||||
};
|
||||
m["get_relative_account_history"] = [this](variant result, const fc::variants& a)
|
||||
{
|
||||
auto r = result.as<vector<operation_detail>>();
|
||||
std::stringstream ss;
|
||||
|
||||
for( operation_detail& d : r )
|
||||
{
|
||||
operation_history_object& i = d.op;
|
||||
auto b = _remote_db->get_block_header(i.block_num);
|
||||
FC_ASSERT(b);
|
||||
ss << b->timestamp.to_iso_string() << " ";
|
||||
i.op.visit(operation_printer(ss, *this, i.result));
|
||||
ss << " \n";
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
m["list_account_balances"] = [this](variant result, const fc::variants& a)
|
||||
{
|
||||
|
|
@ -2818,6 +2835,30 @@ vector<operation_detail> wallet_api::get_account_history(string name, int limit)
|
|||
return result;
|
||||
}
|
||||
|
||||
vector<operation_detail> wallet_api::get_relative_account_history(string name, uint32_t stop, int limit, uint32_t start)const
|
||||
{
|
||||
|
||||
FC_ASSERT( start > 0 || limit <= 100 );
|
||||
|
||||
vector<operation_detail> result;
|
||||
auto account_id = get_account(name).get_id();
|
||||
|
||||
while( limit > 0 )
|
||||
{
|
||||
vector <operation_history_object> current = my->_remote_hist->get_relative_account_history(account_id, stop, std::min<uint32_t>(100, limit), start);
|
||||
for (auto &o : current) {
|
||||
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 (current.size() < std::min<uint32_t>(100, limit))
|
||||
break;
|
||||
limit -= current.size();
|
||||
start -= 100;
|
||||
if( start == 0 ) break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<bucket_object> wallet_api::get_market_history( string symbol1, string symbol2, uint32_t bucket , fc::time_point_sec start, fc::time_point_sec end )const
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue