Skip to content

Commit

Permalink
Merge remote-tracking branch 'graphene/develop' into bitshares
Browse files Browse the repository at this point in the history
  • Loading branch information
theoreticalbts committed Mar 16, 2016
2 parents ff0da57 + 006d548 commit 4dbfe53
Show file tree
Hide file tree
Showing 38 changed files with 1,622 additions and 186 deletions.
3 changes: 2 additions & 1 deletion libraries/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ add_library( graphene_app
${EGENESIS_HEADERS}
)

target_link_libraries( graphene_app graphene_market_history graphene_chain fc graphene_db graphene_net graphene_time graphene_utilities )
# need to link graphene_debug_witness because plugins aren't sufficiently isolated #246
target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_chain fc graphene_db graphene_net graphene_time graphene_utilities graphene_debug_witness )
target_include_directories( graphene_app
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../egenesis/include" )
Expand Down
67 changes: 56 additions & 11 deletions libraries/app/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ namespace graphene { namespace app {
{
_crypto_api = std::make_shared< crypto_api >();
}
else if( api_name == "debug_api" )
{
// can only enable this API if the plugin was loaded
if( _app.get_plugin( "debug_witness" ) )
_debug_api = std::make_shared< graphene::debug_witness::debug_api >( std::ref(_app) );
}
return;
}

Expand Down Expand Up @@ -211,6 +217,12 @@ namespace graphene { namespace app {
return *_crypto_api;
}

fc::api<graphene::debug_witness::debug_api> login_api::debug() const
{
FC_ASSERT(_debug_api);
return *_debug_api;
}

vector<account_id_type> get_relevant_accounts( const object* obj )
{
vector<account_id_type> result;
Expand Down Expand Up @@ -380,25 +392,58 @@ namespace graphene { namespace app {
return result;
}

vector<operation_history_object> history_api::get_account_history(account_id_type account, operation_history_id_type stop, unsigned limit, operation_history_id_type start) const
vector<operation_history_object> history_api::get_account_history( account_id_type account,
operation_history_id_type stop,
unsigned limit,
operation_history_id_type start ) const
{
FC_ASSERT(_app.chain_database());
const auto& db = *_app.chain_database();
FC_ASSERT(limit <= 100);
FC_ASSERT( _app.chain_database() );
const auto& db = *_app.chain_database();
FC_ASSERT( limit <= 100 );
vector<operation_history_object> result;
const auto& stats = account(db).statistics(db);
if(stats.most_recent_op == account_transaction_history_id_type()) return result;
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->id;
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->id.instance() <= start.instance.value)
result.push_back(node->operation_id(db));
if(node->next == account_transaction_history_id_type())
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 = db.find(node->next);
else node = &node->next(db);
}

return result;
}

vector<operation_history_object> history_api::get_relative_account_history( account_id_type account,
uint32_t stop,
unsigned limit,
uint32_t start) const
{
FC_ASSERT( _app.chain_database() );
const auto& db = *_app.chain_database();
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 )
{
result.push_back( itr->operation_id(db) );
--itr;
}

return result;
}

Expand Down
8 changes: 4 additions & 4 deletions libraries/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ namespace detail {
if( !_options->count("rpc-endpoint") )
return;

bool enable_deflate_compression = _options->count("disable-permessage-deflate") == 0;
bool enable_deflate_compression = _options->count("enable-permessage-deflate") != 0;

_websocket_server = std::make_shared<fc::http::websocket_server>(enable_deflate_compression);

Expand Down Expand Up @@ -254,7 +254,7 @@ namespace detail {
}

string password = _options->count("server-pem-password") ? _options->at("server-pem-password").as<string>() : "";
bool enable_deflate_compression = _options->count("disable-permessage-deflate") == 0;
bool enable_deflate_compression = _options->count("enable-permessage-deflate") != 0;
_websocket_tls_server = std::make_shared<fc::http::websocket_tls_server>( _options->at("server-pem").as<string>(), password, enable_deflate_compression );

_websocket_tls_server->on_connection([&]( const fc::http::websocket_connection_ptr& c ){
Expand Down Expand Up @@ -949,8 +949,8 @@ void application::set_program_options(boost::program_options::options_descriptio
("checkpoint,c", bpo::value<vector<string>>()->composing(), "Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints.")
("rpc-endpoint", bpo::value<string>()->implicit_value("127.0.0.1:8090"), "Endpoint for websocket RPC to listen on")
("rpc-tls-endpoint", bpo::value<string>()->implicit_value("127.0.0.1:8089"), "Endpoint for TLS websocket RPC to listen on")
("disable-permessage-deflate", "Disable support for per-message deflate compression in the websocket servers "
"(--rpc-endpoint and --rpc-tls-endpoint), enabled by default")
("enable-permessage-deflate", "Enable support for per-message deflate compression in the websocket servers "
"(--rpc-endpoint and --rpc-tls-endpoint), disabled by default")
("server-pem,p", bpo::value<string>()->implicit_value("server.pem"), "The TLS certificate file for this server")
("server-pem-password,P", bpo::value<string>()->implicit_value(""), "Password for this certificate")
("genesis-json", bpo::value<boost::filesystem::path>(), "File to read Genesis State from")
Expand Down
103 changes: 47 additions & 56 deletions libraries/app/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include <fc/crypto/hex.hpp>

#include <boost/range/iterator_range.hpp>
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>

#include <cctype>

Expand Down Expand Up @@ -1025,56 +1027,37 @@ market_ticker database_api_impl::get_ticker( const string& base, const string& q
try {
if( base_id > quote_id ) std::swap(base_id, quote_id);

const auto& bidx = _db.get_index_type<bucket_index>();
const auto& by_key_idx = bidx.indices().get<by_key>();
uint32_t bucket_size = 86400;
uint32_t day = 86400;
auto now = fc::time_point_sec( fc::time_point::now() );

auto itr = by_key_idx.lower_bound( bucket_key( base_id, quote_id, bucket_size,
now - bucket_size ) );

auto orders = get_order_book( base, quote, 1 );
auto trades = get_trade_history( base, quote, now, fc::time_point_sec( now.sec_since_epoch() - day ), 100 );

result.latest = trades[0].price;

if( itr != by_key_idx.end() && itr->key.base == base_id && itr->key.quote == quote_id && itr->key.seconds == bucket_size )
for ( market_trade t: trades )
{
auto trades = get_trade_history( base, quote, now, fc::time_point_sec( now.sec_since_epoch() - bucket_size ), 100 );
result.base_volume += t.value;
result.quote_volume += t.amount;
}

if (assets[0]->id == base_id)
{
result.latest = trades[0].price;
result.percent_change = ( result.latest / ( price_to_real( itr->open_quote, assets[1]->precision ) / price_to_real( itr->open_base, assets[0]->precision ) ) - 1 ) * 100;
//result.lowest_ask = price_to_real( itr->low_quote, assets[1]->precision ) / price_to_real( itr->low_base, assets[0]->precision );
//result.highest_bid = price_to_real( itr->high_quote, assets[1]->precision ) / price_to_real( itr->high_base, assets[0]->precision );
result.lowest_ask = orders.asks[0].first;
result.highest_bid = orders.bids[0].first;
}
else
{
result.latest = trades[0].price;
result.percent_change = ( result.latest / ( price_to_real( itr->open_base, assets[1]->precision ) / price_to_real( itr->open_quote, assets[0]->precision ) ) - 1) * 100;
//result.lowest_ask = price_to_real( itr->low_base, assets[1]->precision ) / price_to_real( itr->low_quote, assets[0]->precision );
//result.highest_bid = price_to_real( itr->high_base, assets[1]->precision ) / price_to_real( itr->high_quote, assets[0]->precision );
result.lowest_ask = orders.bids[0].first;
result.highest_bid = orders.asks[0].first;
}
while (trades.size() == 100)
{
trades = get_trade_history( base, quote, trades[99].date, fc::time_point_sec( now.sec_since_epoch() - day ), 100 );

for ( market_trade t: trades )
{
result.base_volume += t.amount;
result.quote_volume += t.value;
result.base_volume += t.value;
result.quote_volume += t.amount;
}
}

while (trades.size() == 100)
{
for ( market_trade t: trades )
{
result.base_volume += t.amount;
result.quote_volume += t.value;
}

trades = get_trade_history( base, quote, trades[99].date, fc::time_point_sec( now.sec_since_epoch() - bucket_size ), 100 );
}
trades = get_trade_history( base, quote, trades.back().date, fc::time_point_sec(), 1 );
result.percent_change = trades.size() > 0 ? ( ( result.latest / trades.back().price ) - 1 ) * 100 : 0;

//if (assets[0]->id == base_id)
{
result.lowest_ask = orders.asks[0].price;
result.highest_bid = orders.bids[0].price;
}

return result;
Expand Down Expand Up @@ -1111,19 +1094,19 @@ market_volume database_api_impl::get_24_volume( const string& base, const string

for ( market_trade t: trades )
{
result.base_volume += t.amount;
result.quote_volume += t.value;
result.base_volume += t.value;
result.quote_volume += t.amount;
}

while (trades.size() == 100)
{
trades = get_trade_history( base, quote, trades[99].date, fc::time_point_sec( now.sec_since_epoch() - bucket_size ), 100 );

for ( market_trade t: trades )
{
result.base_volume += t.amount;
result.quote_volume += t.value;
result.base_volume += t.value;
result.quote_volume += t.amount;
}

trades = get_trade_history( base, quote, trades[99].date, fc::time_point_sec( now.sec_since_epoch() - bucket_size ), 100 );
}

return result;
Expand All @@ -1137,6 +1120,7 @@ order_book database_api::get_order_book( const string& base, const string& quote

order_book database_api_impl::get_order_book( const string& base, const string& quote, unsigned limit )const
{
using boost::multiprecision::uint128_t;
FC_ASSERT( limit <= 50 );

order_book result;
Expand All @@ -1156,21 +1140,28 @@ order_book database_api_impl::get_order_book( const string& base, const string&
auto price_to_real = [&]( const price& p )
{
if( p.base.asset_id == base_id )
return asset_to_real( p.quote, assets[1]->precision ) / asset_to_real( p.base, assets[0]->precision );
return asset_to_real( p.base, assets[0]->precision ) / asset_to_real( p.quote, assets[1]->precision );
else
return asset_to_real( p.base, assets[1]->precision ) / asset_to_real( p.quote, assets[0]->precision );
return asset_to_real( p.quote, assets[0]->precision ) / asset_to_real( p.base, assets[1]->precision );
};

for( const auto& o : orders ) {
for( const auto& o : orders )
{
if( o.sell_price.base.asset_id == base_id )
{
result.asks.push_back( std::make_pair( price_to_real(o.sell_price),
asset_to_real(o.sell_price.base, assets[0]->precision)) );
order ord;
ord.price = price_to_real( o.sell_price );
ord.quote = asset_to_real( share_type( ( uint128_t( o.for_sale.value ) * o.sell_price.quote.amount.value ) / o.sell_price.base.amount.value ), assets[1]->precision );
ord.base = asset_to_real( o.for_sale, assets[0]->precision );
result.bids.push_back( ord );
}
else
{
result.bids.push_back( std::make_pair( price_to_real(o.sell_price),
asset_to_real(o.sell_price.quote, assets[0]->precision ) ) );
order ord;
ord.price = price_to_real( o.sell_price );
ord.quote = asset_to_real( o.for_sale, assets[1]->precision );
ord.base = asset_to_real( share_type( ( uint64_t( o.for_sale.value ) * o.sell_price.quote.amount.value ) / o.sell_price.base.amount.value ), assets[0]->precision );
result.asks.push_back( ord );
}
}

Expand Down Expand Up @@ -1225,13 +1216,13 @@ vector<market_trade> database_api_impl::get_trade_history( const string& base,

if( assets[0]->id == itr->op.receives.asset_id )
{
trade.amount = price_to_real( itr->op.receives.amount, assets[0]->precision );
trade.value = price_to_real( itr->op.pays.amount, assets[1]->precision );
trade.amount = price_to_real( itr->op.pays.amount, assets[1]->precision );
trade.value = price_to_real( itr->op.receives.amount, assets[0]->precision );
}
else
{
trade.amount = price_to_real( itr->op.pays.amount, assets[0]->precision );
trade.value = price_to_real( itr->op.receives.amount, assets[1]->precision );
trade.amount = price_to_real( itr->op.receives.amount, assets[1]->precision );
trade.value = price_to_real( itr->op.pays.amount, assets[0]->precision );
}

trade.date = itr->time;
Expand Down
23 changes: 23 additions & 0 deletions libraries/app/include/graphene/app/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include <graphene/market_history/market_history_plugin.hpp>

#include <graphene/debug_witness/debug_api.hpp>

#include <graphene/net/node.hpp>

#include <fc/api.hpp>
Expand Down Expand Up @@ -91,6 +93,22 @@ namespace graphene { namespace app {
operation_history_id_type stop = operation_history_id_type(),
unsigned limit = 100,
operation_history_id_type start = operation_history_id_type())const;
/**
* @breif Get operations relevant to the specified account referenced
* by an event numbering specific to the account. The current number of operations
* for the account can be found in the account statistics (or use 0 for start).
* @param account The account whose history should be queried
* @param stop Sequence number of earliest operation. 0 is default and will
* query 'limit' number of operations.
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start Sequence number of the most recent operation to retrieve.
* 0 is default, which will start querying from the most recent operation.
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
vector<operation_history_object> get_relative_account_history( account_id_type account,
uint32_t stop = 0,
unsigned limit = 100,
uint32_t start = 0) const;

vector<order_history_object> get_fill_order_history( asset_id_type a, asset_id_type b, uint32_t limit )const;
vector<bucket_object> get_market_history( asset_id_type a, asset_id_type b, uint32_t bucket_seconds,
Expand Down Expand Up @@ -265,6 +283,8 @@ namespace graphene { namespace app {
fc::api<network_node_api> network_node()const;
/// @brief Retrieve the cryptography API
fc::api<crypto_api> crypto()const;
/// @brief Retrieve the debug API (if available)
fc::api<graphene::debug_witness::debug_api> debug()const;

private:
/// @brief Called to enable an API, not reflected.
Expand All @@ -276,6 +296,7 @@ namespace graphene { namespace app {
optional< fc::api<network_node_api> > _network_node_api;
optional< fc::api<history_api> > _history_api;
optional< fc::api<crypto_api> > _crypto_api;
optional< fc::api<graphene::debug_witness::debug_api> > _debug_api;
};

}} // graphene::app
Expand All @@ -291,6 +312,7 @@ FC_REFLECT( graphene::app::verify_range_proof_rewind_result,

FC_API(graphene::app::history_api,
(get_account_history)
(get_relative_account_history)
(get_fill_order_history)
(get_market_history)
(get_market_history_buckets)
Expand Down Expand Up @@ -326,4 +348,5 @@ FC_API(graphene::app::login_api,
(history)
(network_node)
(crypto)
(debug)
)
Loading

0 comments on commit 4dbfe53

Please sign in to comment.