BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
market_history_plugin.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
26 
35 
36 #include <fc/thread/thread.hpp>
37 
38 namespace graphene { namespace market_history {
39 
40 namespace detail
41 {
42 
44 {
45  public:
47  :_self( _plugin ) {}
48 
52  void update_market_histories( const signed_block& b );
53 
56  const lp_ticker_meta_object*& lp_meta );
57 
59  {
60  return _self.database();
61  }
62 
64  flat_set<uint32_t> _tracked_buckets;
68 };
69 
70 
72 {
76 
78  :_plugin(mhp),_now(n),_meta(meta) {}
79 
80  typedef void result_type;
81 
83  template<typename T>
84  void operator()( const T& )const{}
85 
86  void operator()( const fill_order_operation& o )const
87  {
88  //ilog( "processing ${o}", ("o",o) );
89  auto& db = _plugin.database();
90  const auto& order_his_idx = db.get_index_type<history_index>().indices();
91  const auto& history_idx = order_his_idx.get<by_key>();
92  const auto& his_time_idx = order_his_idx.get<by_market_time>();
93 
94  // To save new filled order data
95  history_key hkey;
96  hkey.base = o.pays.asset_id;
97  hkey.quote = o.receives.asset_id;
98  if( hkey.base > hkey.quote )
99  std::swap( hkey.base, hkey.quote );
100  hkey.sequence = std::numeric_limits<int64_t>::min();
101 
102  auto itr = history_idx.lower_bound( hkey );
103 
104  if( itr != history_idx.end() && itr->key.base == hkey.base && itr->key.quote == hkey.quote )
105  hkey.sequence = itr->key.sequence - 1;
106  else
107  hkey.sequence = 0;
108 
109  const auto& new_order_his_obj = db.create<order_history_object>( [&]( order_history_object& ho ) {
110  ho.key = hkey;
111  ho.time = _now;
112  ho.op = o;
113  });
114 
115  // save a reference to market ticker meta object
116  if( _meta == nullptr )
117  {
118  const auto& meta_idx = db.get_index_type<simple_index<market_ticker_meta_object>>();
119  if( meta_idx.size() == 0 )
120  _meta = &db.create<market_ticker_meta_object>( [&]( market_ticker_meta_object& mtm ) {
121  mtm.rolling_min_order_his_id = new_order_his_obj.id;
122  mtm.skip_min_order_his_id = false;
123  });
124  else
125  _meta = &( *meta_idx.begin() );
126  }
127 
128  // To remove old filled order data
129  const auto max_records = _plugin.max_order_his_records_per_market();
130  hkey.sequence += max_records;
131  itr = history_idx.lower_bound( hkey );
132  if( itr != history_idx.end() && itr->key.base == hkey.base && itr->key.quote == hkey.quote )
133  {
134  const auto max_seconds = _plugin.max_order_his_seconds_per_market();
135  fc::time_point_sec min_time;
136  if( min_time + max_seconds < _now )
137  min_time = _now - max_seconds;
138  auto time_itr = his_time_idx.lower_bound( std::make_tuple( hkey.base, hkey.quote, min_time ) );
139  if( time_itr != his_time_idx.end() && time_itr->key.base == hkey.base && time_itr->key.quote == hkey.quote )
140  {
141  if( itr->key.sequence >= time_itr->key.sequence )
142  {
143  while( itr != history_idx.end() && itr->key.base == hkey.base && itr->key.quote == hkey.quote )
144  {
145  auto old_itr = itr;
146  ++itr;
147  db.remove( *old_itr );
148  }
149  }
150  else
151  {
152  while( time_itr != his_time_idx.end() && time_itr->key.base == hkey.base && time_itr->key.quote == hkey.quote )
153  {
154  auto old_itr = time_itr;
155  ++time_itr;
156  db.remove( *old_itr );
157  }
158  }
159  }
160  }
161 
162  // To update ticker data and buckets data, only update for maker orders
163  if( !o.is_maker )
164  return;
165 
166  bucket_key key;
167  key.base = o.pays.asset_id;
168  key.quote = o.receives.asset_id;
169 
170  price trade_price = o.pays / o.receives;
171 
172  if( key.base > key.quote )
173  {
174  std::swap( key.base, key.quote );
175  trade_price = ~trade_price;
176  }
177 
178  price fill_price = o.fill_price;
179  if( fill_price.base.asset_id > fill_price.quote.asset_id )
180  fill_price = ~fill_price;
181 
182  // To update ticker data
183  const auto& ticker_idx = db.get_index_type<market_ticker_index>().indices().get<by_market>();
184  auto ticker_itr = ticker_idx.find( std::make_tuple( key.base, key.quote ) );
185  if( ticker_itr == ticker_idx.end() )
186  {
187  db.create<market_ticker_object>( [&]( market_ticker_object& mt ) {
188  mt.base = key.base;
189  mt.quote = key.quote;
190  mt.last_day_base = 0;
191  mt.last_day_quote = 0;
192  mt.latest_base = fill_price.base.amount;
193  mt.latest_quote = fill_price.quote.amount;
194  mt.base_volume = trade_price.base.amount.value;
195  mt.quote_volume = trade_price.quote.amount.value;
196  });
197  }
198  else
199  {
200  db.modify( *ticker_itr, [&]( market_ticker_object& mt ) {
201  mt.latest_base = fill_price.base.amount;
202  mt.latest_quote = fill_price.quote.amount;
203  mt.base_volume += trade_price.base.amount.value; // ignore overflow
204  mt.quote_volume += trade_price.quote.amount.value; // ignore overflow
205  });
206  }
207 
208  // To update buckets data
209  const auto max_history = _plugin.max_history();
210  if( max_history == 0 ) return;
211 
212  const auto& buckets = _plugin.tracked_buckets();
213  if( buckets.size() == 0 ) return;
214 
215  const auto& bucket_idx = db.get_index_type<bucket_index>();
216  for( auto bucket : buckets )
217  {
218  auto bucket_num = _now.sec_since_epoch() / bucket;
219  fc::time_point_sec cutoff;
220  if( bucket_num > max_history )
221  cutoff = cutoff + ( bucket * ( bucket_num - max_history ) );
222 
223  key.seconds = bucket;
224  key.open = fc::time_point_sec() + ( bucket_num * bucket );
225 
226  const auto& by_key_idx = bucket_idx.indices().get<by_key>();
227  auto bucket_itr = by_key_idx.find( key );
228  if( bucket_itr == by_key_idx.end() )
229  { // create new bucket
230  /* const auto& obj = */
231  db.create<bucket_object>( [&]( bucket_object& b ){
232  b.key = key;
233  b.base_volume = trade_price.base.amount;
234  b.quote_volume = trade_price.quote.amount;
235  b.open_base = fill_price.base.amount;
236  b.open_quote = fill_price.quote.amount;
237  b.close_base = fill_price.base.amount;
238  b.close_quote = fill_price.quote.amount;
239  b.high_base = b.close_base;
240  b.high_quote = b.close_quote;
241  b.low_base = b.close_base;
242  b.low_quote = b.close_quote;
243  });
244  //wlog( " creating bucket ${b}", ("b",obj) );
245  }
246  else
247  { // update existing bucket
248  //wlog( " before updating bucket ${b}", ("b",*bucket_itr) );
249  db.modify( *bucket_itr, [&]( bucket_object& b ){
250  try {
251  b.base_volume += trade_price.base.amount;
252  } catch( fc::overflow_exception& ) {
253  b.base_volume = std::numeric_limits<int64_t>::max();
254  }
255  try {
256  b.quote_volume += trade_price.quote.amount;
257  } catch( fc::overflow_exception& ) {
258  b.quote_volume = std::numeric_limits<int64_t>::max();
259  }
260  b.close_base = fill_price.base.amount;
261  b.close_quote = fill_price.quote.amount;
262  if( b.high() < fill_price )
263  {
264  b.high_base = b.close_base;
265  b.high_quote = b.close_quote;
266  }
267  if( b.low() > fill_price )
268  {
269  b.low_base = b.close_base;
270  b.low_quote = b.close_quote;
271  }
272  });
273  //wlog( " after bucket bucket ${b}", ("b",*bucket_itr) );
274  }
275 
276  {
277  key.open = fc::time_point_sec();
278  bucket_itr = by_key_idx.lower_bound( key );
279 
280  while( bucket_itr != by_key_idx.end() &&
281  bucket_itr->key.base == key.base &&
282  bucket_itr->key.quote == key.quote &&
283  bucket_itr->key.seconds == bucket &&
284  bucket_itr->key.open < cutoff )
285  {
286  // elog( " removing old bucket ${b}", ("b", *bucket_itr) );
287  auto old_bucket_itr = bucket_itr;
288  ++bucket_itr;
289  db.remove( *old_bucket_itr );
290  }
291  }
292  }
293  }
294 };
295 
297 {
299 
300  const market_ticker_meta_object* _meta = nullptr;
301  const auto& meta_idx = db.get_index_type<simple_index<market_ticker_meta_object>>();
302  if( meta_idx.size() > 0 )
303  _meta = &( *meta_idx.begin() );
304 
305  const lp_ticker_meta_object* _lp_meta = nullptr;
306  const auto& lp_meta_idx = db.get_index_type<simple_index<lp_ticker_meta_object>>();
307  if( lp_meta_idx.size() > 0 )
308  _lp_meta = &( *lp_meta_idx.begin() );
309 
310  const vector<optional< operation_history_object > >& hist = db.get_applied_operations();
311  for( const optional< operation_history_object >& o_op : hist )
312  {
313  if( o_op.valid() )
314  {
315  // process market history
316  try
317  {
318  o_op->op.visit( operation_process_fill_order( _self, b.timestamp, _meta ) );
319  } FC_CAPTURE_AND_LOG( (o_op) )
320  // process liquidity pool history
321  update_liquidity_pool_histories( b.timestamp, *o_op, _lp_meta );
322  }
323  }
324  // roll out expired data from ticker
325  if( _meta != nullptr )
326  {
327  time_point_sec last_day = b.timestamp - 86400;
328  object_id_type last_min_his_id = _meta->rolling_min_order_his_id;
329  bool skip = _meta->skip_min_order_his_id;
330 
331  const auto& ticker_idx = db.get_index_type<market_ticker_index>().indices().get<by_market>();
332  const auto& history_idx = db.get_index_type<history_index>().indices().get<by_id>();
333  auto history_itr = history_idx.lower_bound( _meta->rolling_min_order_his_id );
334  while( history_itr != history_idx.end() && history_itr->time < last_day )
335  {
336  const fill_order_operation& o = history_itr->op;
337  if( skip && history_itr->id == _meta->rolling_min_order_his_id )
338  skip = false;
339  else if( o.is_maker )
340  {
341  bucket_key key;
342  key.base = o.pays.asset_id;
343  key.quote = o.receives.asset_id;
344 
345  price trade_price = o.pays / o.receives;
346 
347  if( key.base > key.quote )
348  {
349  std::swap( key.base, key.quote );
350  trade_price = ~trade_price;
351  }
352 
353  price fill_price = o.fill_price;
354  if( fill_price.base.asset_id > fill_price.quote.asset_id )
355  fill_price = ~fill_price;
356 
357  auto ticker_itr = ticker_idx.find( std::make_tuple( key.base, key.quote ) );
358  if( ticker_itr != ticker_idx.end() ) // should always be true
359  {
360  db.modify( *ticker_itr, [&]( market_ticker_object& mt ) {
361  mt.last_day_base = fill_price.base.amount;
362  mt.last_day_quote = fill_price.quote.amount;
363  mt.base_volume -= trade_price.base.amount.value; // ignore underflow
364  mt.quote_volume -= trade_price.quote.amount.value; // ignore underflow
365  });
366  }
367  }
368  last_min_his_id = history_itr->id;
369  ++history_itr;
370  }
371  // update meta
372  if( history_itr != history_idx.end() ) // if still has some data rolling
373  {
374  if( history_itr->id != _meta->rolling_min_order_his_id ) // if rolled out some
375  {
376  db.modify( *_meta, [&]( market_ticker_meta_object& mtm ) {
377  mtm.rolling_min_order_his_id = history_itr->id;
378  mtm.skip_min_order_his_id = false;
379  });
380  }
381  }
382  else // if all data are rolled out
383  {
384  if( !_meta->skip_min_order_his_id
385  || last_min_his_id != _meta->rolling_min_order_his_id ) // if rolled out some
386  {
387  db.modify( *_meta, [&]( market_ticker_meta_object& mtm ) {
388  mtm.rolling_min_order_his_id = last_min_his_id;
389  mtm.skip_min_order_his_id = true;
390  });
391  }
392  }
393  }
394  // roll out expired data from LP ticker
395  if( _lp_meta != nullptr )
396  {
397  time_point_sec last_day = b.timestamp - 86400;
398  object_id_type last_min_his_id = _lp_meta->rolling_min_lp_his_id;
399  bool skip = _lp_meta->skip_min_lp_his_id;
400 
401  const auto& history_idx = db.get_index_type<liquidity_pool_history_index>().indices().get<by_id>();
402  auto history_itr = history_idx.lower_bound( _lp_meta->rolling_min_lp_his_id );
403  while( history_itr != history_idx.end() && history_itr->time < last_day )
404  {
405  if( skip && history_itr->id == _lp_meta->rolling_min_lp_his_id )
406  skip = false;
407  else
408  {
409  liquidity_pool_ticker_id_type ticker_id( history_itr->pool.instance );
410  const liquidity_pool_ticker_object* ticker = db.find( ticker_id );
411  if( ticker != nullptr ) // should always be true
412  {
413  const operation_history_object& oho = history_itr->op;
415  {
416  auto& result = oho.result.get< generic_exchange_operation_result >();
417  db.modify( *ticker, [&result]( liquidity_pool_ticker_object& t ) {
418  t._24h_deposit_count -= 1;
419  t._24h_deposit_amount_a -= result.paid.front().amount.value;
420  t._24h_deposit_amount_b -= result.paid.back().amount.value;
421  t._24h_deposit_share_amount -= result.received.front().amount.value;
422  t._24h_balance_delta_a -= result.paid.front().amount.value;
423  t._24h_balance_delta_b -= result.paid.back().amount.value;
424  });
425  }
426  else if( oho.op.is_type< liquidity_pool_withdraw_operation >() )
427  {
428  auto& op = oho.op.get< liquidity_pool_withdraw_operation >();
429  auto& result = oho.result.get< generic_exchange_operation_result >();
430  db.modify( *ticker, [&op,&result]( liquidity_pool_ticker_object& t ) {
431  t._24h_withdrawal_count -= 1;
432  t._24h_withdrawal_amount_a -= result.received.front().amount.value;
433  t._24h_withdrawal_amount_b -= result.received.back().amount.value;
434  t._24h_withdrawal_share_amount -= op.share_amount.amount.value;
435  t._24h_withdrawal_fee_a -= result.fees.front().amount.value;
436  t._24h_withdrawal_fee_b -= result.fees.back().amount.value;
437  t._24h_balance_delta_a += result.received.front().amount.value;
438  t._24h_balance_delta_b += result.received.back().amount.value;
439  });
440  }
441  else if( oho.op.is_type< liquidity_pool_exchange_operation >() )
442  {
443  auto& op = oho.op.get< liquidity_pool_exchange_operation >();
444  auto& result = oho.result.get< generic_exchange_operation_result >();
445  db.modify( *ticker, [&op,&result]( liquidity_pool_ticker_object& t ) {
446  auto amount_in = op.amount_to_sell.amount - result.fees.front().amount;
447  auto amount_out = result.received.front().amount + result.fees.at(1).amount;
448  if( op.amount_to_sell.asset_id < op.min_to_receive.asset_id ) // pool got a, paid b
449  {
451  t._24h_exchange_a2b_amount_a -= amount_in.value;
452  t._24h_exchange_a2b_amount_b -= amount_out.value;
453  t._24h_exchange_fee_b -= result.fees.back().amount.value;
454  t._24h_balance_delta_a -= amount_in.value;
455  t._24h_balance_delta_b += amount_out.value;
456  }
457  else // pool got b, paid a
458  {
460  t._24h_exchange_b2a_amount_a -= amount_out.value;
461  t._24h_exchange_b2a_amount_b -= amount_in.value;
462  t._24h_exchange_fee_a -= result.fees.back().amount.value;
463  t._24h_balance_delta_a += amount_out.value;
464  t._24h_balance_delta_b -= amount_in.value;
465  }
466  });
467  }
468  }
469  }
470  last_min_his_id = history_itr->id;
471  ++history_itr;
472  }
473  // update meta
474  if( history_itr != history_idx.end() ) // if still has some data rolling
475  {
476  if( history_itr->id != _lp_meta->rolling_min_lp_his_id ) // if rolled out some
477  {
478  db.modify( *_lp_meta, [history_itr]( lp_ticker_meta_object& mtm ) {
479  mtm.rolling_min_lp_his_id = history_itr->id;
480  mtm.skip_min_lp_his_id = false;
481  });
482  }
483  }
484  else // if all data are rolled out
485  {
486  if( !_lp_meta->skip_min_lp_his_id
487  || last_min_his_id != _lp_meta->rolling_min_lp_his_id ) // if rolled out some
488  {
489  db.modify( *_lp_meta, [last_min_his_id]( lp_ticker_meta_object& mtm ) {
490  mtm.rolling_min_lp_his_id = last_min_his_id;
491  mtm.skip_min_lp_his_id = true;
492  });
493  }
494  }
495  }
496 }
497 
499 {
501 
503  template<typename T>
504  result_type operator()( const T& )const
505  {
506  return {};
507  }
508 
510  {
511  return o.pool;
512  }
513 
515  {
516  return o.pool;
517  }
518 
520  {
521  return o.pool;
522  }
523 
525  {
526  return o.pool;
527  }
528 
530  {
531  return o.pool;
532  }
533 
534 };
535 
537  time_point_sec time, const operation_history_object& oho,
538  const lp_ticker_meta_object*& lp_meta )
539 { try {
540 
542  uint64_t sequence = 0;
544  {
545  pool = *oho.result.get<generic_operation_result>().new_objects.begin();
546  sequence = 1;
547  }
548  else
549  {
550  pool = oho.op.visit( get_liquidity_pool_id_visitor() );
551  }
552 
553  if( pool.valid() )
554  {
555  auto& db = database();
556  const auto& his_index = db.get_index_type<liquidity_pool_history_index>().indices();
557  const auto& his_seq_idx = his_index.get<by_pool_seq>();
558  const auto& his_time_idx = his_index.get<by_pool_time>();
559 
560  if( sequence == 0 )
561  {
562  auto itr = his_seq_idx.lower_bound( *pool );
563  if( itr != his_seq_idx.end() && itr->pool == *pool )
564  sequence = itr->sequence + 1;
565  else
566  sequence = 2;
567  }
568 
569  // To save new data
570  const auto& new_his_obj = db.create<liquidity_pool_history_object>( [&pool,sequence,time,&oho](
572  ho.pool = *pool;
573  ho.sequence = sequence;
574  ho.time = time;
575  ho.op_type = oho.op.which();
576  ho.op = oho;
577  });
578 
579  // save a reference to the ticker meta object
580  if( lp_meta == nullptr )
581  {
582  const auto& lp_meta_idx = db.get_index_type<simple_index<lp_ticker_meta_object>>();
583  if( lp_meta_idx.size() == 0 )
584  lp_meta = &db.create<lp_ticker_meta_object>( [&new_his_obj]( lp_ticker_meta_object& lptm ) {
585  lptm.rolling_min_lp_his_id = new_his_obj.id;
586  lptm.skip_min_lp_his_id = false;
587  });
588  else
589  lp_meta = &( *lp_meta_idx.begin() );
590  }
591 
592  // To remove old history data
593  if( sequence > _max_order_his_records_per_market )
594  {
595  const auto min_seq = sequence - _max_order_his_records_per_market;
596  auto itr = his_seq_idx.lower_bound( std::make_tuple( *pool, min_seq ) );
597  if( itr != his_seq_idx.end() && itr->pool == *pool )
598  {
599  fc::time_point_sec min_time;
600  if( min_time + _max_order_his_seconds_per_market < time )
601  min_time = time - _max_order_his_seconds_per_market;
602  auto time_itr = his_time_idx.lower_bound( std::make_tuple( *pool, min_time ) );
603  if( time_itr != his_time_idx.end() && time_itr->pool == *pool )
604  {
605  if( itr->sequence <= time_itr->sequence )
606  {
607  while( itr != his_seq_idx.end() && itr->pool == *pool )
608  {
609  auto old_itr = itr;
610  ++itr;
611  db.remove( *old_itr );
612  }
613  }
614  else
615  {
616  while( time_itr != his_time_idx.end() && time_itr->pool == *pool )
617  {
618  auto old_itr = time_itr;
619  ++time_itr;
620  db.remove( *old_itr );
621  }
622  }
623  }
624  }
625  }
626 
627  // To update ticker data
628  if( sequence == 1 ) // create
629  {
630  const liquidity_pool_ticker_object* ticker = nullptr;
631  do {
632  ticker = &db.create<liquidity_pool_ticker_object>( []( liquidity_pool_ticker_object& lpt ) {
633  });
634  } while( ticker->id.instance() < pool->instance );
635  }
636  else
637  {
638  liquidity_pool_ticker_id_type ticker_id( pool->instance );
639  const liquidity_pool_ticker_object* ticker = db.find( ticker_id );
640  if( ticker != nullptr )
641  {
643  {
644  auto& result = oho.result.get< generic_exchange_operation_result >();
645 
646  db.modify( *ticker, [&result]( liquidity_pool_ticker_object& t ) {
647  t._24h_deposit_count += 1;
648  t._24h_deposit_amount_a += result.paid.front().amount.value;
649  t._24h_deposit_amount_b += result.paid.back().amount.value;
650  t._24h_deposit_share_amount += result.received.front().amount.value;
651  t._24h_balance_delta_a += result.paid.front().amount.value;
652  t._24h_balance_delta_b += result.paid.back().amount.value;
653  t.total_deposit_count += 1;
654  t.total_deposit_amount_a += result.paid.front().amount.value;
655  t.total_deposit_amount_b += result.paid.back().amount.value;
656  t.total_deposit_share_amount += result.received.front().amount.value;
657  });
658 
659  }
660  else if( oho.op.is_type< liquidity_pool_withdraw_operation >() )
661  {
662  auto& op = oho.op.get< liquidity_pool_withdraw_operation >();
663  auto& result = oho.result.get< generic_exchange_operation_result >();
664 
665  db.modify( *ticker, [&op,&result]( liquidity_pool_ticker_object& t ) {
666  t._24h_withdrawal_count += 1;
667  t._24h_withdrawal_amount_a += result.received.front().amount.value;
668  t._24h_withdrawal_amount_b += result.received.back().amount.value;
669  t._24h_withdrawal_share_amount += op.share_amount.amount.value;
670  t._24h_withdrawal_fee_a += result.fees.front().amount.value;
671  t._24h_withdrawal_fee_b += result.fees.back().amount.value;
672  t._24h_balance_delta_a -= result.received.front().amount.value;
673  t._24h_balance_delta_b -= result.received.back().amount.value;
674  t.total_withdrawal_count += 1;
675  t.total_withdrawal_amount_a += result.received.front().amount.value;
676  t.total_withdrawal_amount_b += result.received.back().amount.value;
677  t.total_withdrawal_share_amount += op.share_amount.amount.value;
678  t.total_withdrawal_fee_a += result.fees.front().amount.value;
679  t.total_withdrawal_fee_b += result.fees.back().amount.value;
680  });
681 
682  }
683  else if( oho.op.is_type< liquidity_pool_exchange_operation >() )
684  {
685  auto& op = oho.op.get< liquidity_pool_exchange_operation >();
686  auto& result = oho.result.get< generic_exchange_operation_result >();
687 
688  db.modify( *ticker, [&op,&result]( liquidity_pool_ticker_object& t ) {
689  auto amount_in = op.amount_to_sell.amount - result.fees.front().amount;
690  auto amount_out = result.received.front().amount + result.fees.at(1).amount;
691  if( op.amount_to_sell.asset_id < op.min_to_receive.asset_id ) // pool got a, paid b
692  {
694  t._24h_exchange_a2b_amount_a += amount_in.value;
695  t._24h_exchange_a2b_amount_b += amount_out.value;
696  t._24h_exchange_fee_b += result.fees.back().amount.value;
697  t._24h_balance_delta_a += amount_in.value;
698  t._24h_balance_delta_b -= amount_out.value;
700  t.total_exchange_a2b_amount_a += amount_in.value;
701  t.total_exchange_a2b_amount_b += amount_out.value;
702  t.total_exchange_fee_b += result.fees.back().amount.value;
703  }
704  else // pool got b, paid a
705  {
707  t._24h_exchange_b2a_amount_a += amount_out.value;
708  t._24h_exchange_b2a_amount_b += amount_in.value;
709  t._24h_exchange_fee_a += result.fees.back().amount.value;
710  t._24h_balance_delta_a -= amount_out.value;
711  t._24h_balance_delta_b += amount_in.value;
713  t.total_exchange_b2a_amount_a += amount_out.value;
714  t.total_exchange_b2a_amount_b += amount_in.value;
715  t.total_exchange_fee_a += result.fees.back().amount.value;
716  }
717  });
718 
719  }
720  }
721  }
722 
723 
724  }
725 
726 } FC_CAPTURE_AND_LOG( (time)(oho) ) }
727 
728 
729 } // end namespace detail
730 
731 
733  plugin(app),
734  my( std::make_unique<detail::market_history_plugin_impl>(*this) )
735 {
736  // Nothing else to do
737 }
738 
740 
742 {
743  return "market_history";
744 }
745 
747  boost::program_options::options_description& cli,
748  boost::program_options::options_description& cfg
749  )
750 {
751  cli.add_options()
752  ("bucket-size",
753  // 1m, 5m, 15m, 1h, 4h, 1d, 1w
754  boost::program_options::value<string>()->default_value("[60,300,900,3600,14400,86400,604800]"),
755  "Track market history by grouping orders into buckets of equal size measured "
756  "in seconds specified as a JSON array of numbers")
757  ("history-per-size", boost::program_options::value<uint32_t>()->default_value(1500),
758  "How far back in time to track history for each bucket size, "
759  "measured in the number of buckets (default: 1500)")
760  ("max-order-his-records-per-market", boost::program_options::value<uint32_t>()->default_value(1000),
761  "Will only store this amount of matched orders for each market in order history for querying, "
762  "or those meet the other option, which has more data (default: 1000). "
763  "This parameter is reused for liquidity pools as maximum operations per pool in history.")
764  ("max-order-his-seconds-per-market", boost::program_options::value<uint32_t>()->default_value(259200),
765  "Will only store matched orders in last X seconds for each market in order history for querying, "
766  "or those meet the other option, which has more data (default: 259200 (3 days)). "
767  "This parameter is reused for liquidity pools as operations in last X seconds per pool in history. "
768  "Note: this parameter need to be greater than 24 hours to be able to serve market ticker data correctly.")
769  ;
770  cfg.add(cli);
771 }
772 
773 void market_history_plugin::plugin_initialize(const boost::program_options::variables_map& options)
774 { try {
775  // connect with group 0 to process before some special steps (e.g. snapshot or next_object_id)
776  database().applied_block.connect( 0, [this]( const signed_block& b){ my->update_market_histories(b); } );
777 
780  database().add_index< primary_index< market_ticker_index, 8 > >(); // 256 markets per chunk
782 
786 
787  if( options.count( "bucket-size" ) > 0 )
788  {
789  const std::string& buckets = options["bucket-size"].as<string>();
790  my->_tracked_buckets = fc::json::from_string(buckets).as<flat_set<uint32_t>>(2);
791  my->_tracked_buckets.erase( 0 );
792  }
793  if( options.count( "history-per-size" ) > 0 )
794  my->_maximum_history_per_bucket_size = options["history-per-size"].as<uint32_t>();
795  if( options.count( "max-order-his-records-per-market" ) > 0 )
796  my->_max_order_his_records_per_market = options["max-order-his-records-per-market"].as<uint32_t>();
797  if( options.count( "max-order-his-seconds-per-market" ) > 0 )
798  my->_max_order_his_seconds_per_market = options["max-order-his-seconds-per-market"].as<uint32_t>();
800 
802 {
803 }
804 
805 const flat_set<uint32_t>& market_history_plugin::tracked_buckets() const
806 {
807  return my->_tracked_buckets;
808 }
809 
811 {
812  return my->_maximum_history_per_bucket_size;
813 }
814 
816 {
817  return my->_max_order_his_records_per_market;
818 }
819 
821 {
822  return my->_max_order_his_seconds_per_market;
823 }
824 
825 } }
graphene::market_history::liquidity_pool_ticker_object
Stores ticker data for liquidity pools.
Definition: market_history_plugin.hpp:301
fc::time_point_sec::sec_since_epoch
uint32_t sec_since_epoch() const
Definition: time.hpp:90
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
graphene::market_history::detail::get_liquidity_pool_id_visitor::operator()
result_type operator()(const liquidity_pool_update_operation &o) const
Definition: market_history_plugin.cpp:514
graphene::market_history::liquidity_pool_ticker_object::total_withdrawal_count
uint64_t total_withdrawal_count
Definition: market_history_plugin.hpp:328
graphene::market_history::market_ticker_object::last_day_quote
share_type last_day_quote
Definition: market_history_plugin.hpp:144
graphene::market_history::market_history_plugin::tracked_buckets
const flat_set< uint32_t > & tracked_buckets() const
Definition: market_history_plugin.cpp:805
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
graphene::protocol::liquidity_pool_exchange_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:144
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::market_history::market_ticker_object::latest_quote
share_type latest_quote
Definition: market_history_plugin.hpp:146
graphene::market_history::detail::operation_process_fill_order::operation_process_fill_order
operation_process_fill_order(market_history_plugin &mhp, fc::time_point_sec n, const market_ticker_meta_object *&meta)
Definition: market_history_plugin.cpp:77
graphene::protocol::fill_order_operation
Definition: market.hpp:206
graphene::market_history::liquidity_pool_history_object::time
fc::time_point_sec time
Definition: market_history_plugin.hpp:222
graphene::market_history::liquidity_pool_ticker_object::_24h_balance_delta_a
share_type _24h_balance_delta_a
Definition: market_history_plugin.hpp:322
graphene::market_history::bucket_object::low_quote
share_type low_quote
Definition: market_history_plugin.hpp:94
graphene::market_history::liquidity_pool_ticker_object::total_deposit_amount_a
fc::uint128_t total_deposit_amount_a
Definition: market_history_plugin.hpp:325
graphene::protocol::price
The price struct stores asset prices in the BitShares system.
Definition: asset.hpp:108
database.hpp
graphene::market_history::detail::market_history_plugin_impl::_self
market_history_plugin & _self
Definition: market_history_plugin.cpp:63
graphene::db::primary_index
Wraps a derived index to intercept calls to create, modify, and remove so that callbacks may be fired...
Definition: index.hpp:312
graphene::chain::operation_history_object::op
operation op
Definition: operation_history_object.hpp:58
graphene::app::plugin::database
chain::database & database()
Definition: plugin.hpp:115
graphene::market_history::market_history_plugin::max_order_his_records_per_market
uint32_t max_order_his_records_per_market() const
Definition: market_history_plugin.cpp:815
graphene::market_history::detail::get_liquidity_pool_id_visitor::operator()
result_type operator()(const liquidity_pool_exchange_operation &o) const
Definition: market_history_plugin.cpp:529
graphene::db::simple_index
A simple index uses a vector<unique_ptr<T>> to store data.
Definition: simple_index.hpp:38
graphene::protocol::liquidity_pool_exchange_operation
Exchange with a liquidity pool.
Definition: liquidity_pool.hpp:138
account_evaluator.hpp
graphene::market_history::detail::market_history_plugin_impl::market_history_plugin_impl
market_history_plugin_impl(market_history_plugin &_plugin)
Definition: market_history_plugin.cpp:46
graphene::protocol::fill_order_operation::fill_price
price fill_price
Definition: market.hpp:219
graphene::market_history::market_ticker_meta_object::skip_min_order_his_id
bool skip_min_order_his_id
Definition: market_history_plugin.hpp:155
graphene::market_history::liquidity_pool_ticker_object::total_withdrawal_fee_a
fc::uint128_t total_withdrawal_fee_a
Definition: market_history_plugin.hpp:332
graphene::market_history::detail::operation_process_fill_order::_meta
const market_ticker_meta_object *& _meta
Definition: market_history_plugin.cpp:75
graphene::market_history::detail::market_history_plugin_impl::update_market_histories
void update_market_histories(const signed_block &b)
Definition: market_history_plugin.cpp:296
graphene::market_history::liquidity_pool_ticker_object::_24h_exchange_b2a_count
uint32_t _24h_exchange_b2a_count
Definition: market_history_plugin.hpp:317
graphene::market_history::liquidity_pool_ticker_object::total_exchange_a2b_amount_b
fc::uint128_t total_exchange_a2b_amount_b
Definition: market_history_plugin.hpp:336
graphene::market_history::detail::market_history_plugin_impl::database
graphene::chain::database & database()
Definition: market_history_plugin.cpp:58
graphene::market_history::liquidity_pool_history_object::sequence
uint64_t sequence
Definition: market_history_plugin.hpp:221
graphene::market_history::bucket_object::close_quote
share_type close_quote
Definition: market_history_plugin.hpp:98
graphene::market_history::liquidity_pool_ticker_object::_24h_exchange_fee_b
fc::uint128_t _24h_exchange_fee_b
Definition: market_history_plugin.hpp:321
graphene::market_history::liquidity_pool_ticker_object::_24h_withdrawal_fee_b
fc::uint128_t _24h_withdrawal_fee_b
Definition: market_history_plugin.hpp:313
graphene::market_history::liquidity_pool_ticker_object::_24h_deposit_share_amount
fc::uint128_t _24h_deposit_share_amount
Definition: market_history_plugin.hpp:307
fee_schedule.hpp
graphene::market_history::liquidity_pool_ticker_object::_24h_exchange_b2a_amount_a
fc::uint128_t _24h_exchange_b2a_amount_a
Definition: market_history_plugin.hpp:318
graphene::market_history::bucket_object
Definition: market_history_plugin.hpp:85
fc::json::from_string
static variant from_string(const string &utf8_str, parse_type ptype=legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:458
graphene::protocol::fill_order_operation::is_maker
bool is_maker
Definition: market.hpp:220
market_history_plugin.hpp
graphene::market_history::liquidity_pool_ticker_object::_24h_withdrawal_amount_a
fc::uint128_t _24h_withdrawal_amount_a
Definition: market_history_plugin.hpp:309
graphene::market_history::bucket_object::high_quote
share_type high_quote
Definition: market_history_plugin.hpp:92
graphene::market_history::bucket_object::high
price high() const
Definition: market_history_plugin.hpp:87
graphene::market_history::history_key
Definition: market_history_plugin.hpp:103
graphene::protocol::liquidity_pool_create_operation
Create a new liquidity pool.
Definition: liquidity_pool.hpp:34
graphene::market_history::liquidity_pool_ticker_object::total_deposit_share_amount
fc::uint128_t total_deposit_share_amount
Definition: market_history_plugin.hpp:327
graphene::market_history::detail::market_history_plugin_impl::_max_order_his_records_per_market
uint32_t _max_order_his_records_per_market
Definition: market_history_plugin.cpp:66
graphene::chain::database::get_applied_operations
const vector< optional< operation_history_object > > & get_applied_operations() const
Definition: db_block.cpp:566
graphene::market_history::bucket_key::base
asset_id_type base
Definition: market_history_plugin.hpp:70
graphene::chain::database::applied_block
fc::signal< void(const signed_block &)> applied_block
Definition: database.hpp:624
graphene::market_history::detail::market_history_plugin_impl::_maximum_history_per_bucket_size
uint32_t _maximum_history_per_bucket_size
Definition: market_history_plugin.cpp:65
graphene::market_history::bucket_key::open
fc::time_point_sec open
Definition: market_history_plugin.hpp:73
graphene::market_history::liquidity_pool_ticker_object::_24h_exchange_a2b_count
uint32_t _24h_exchange_a2b_count
Definition: market_history_plugin.hpp:314
graphene::protocol::liquidity_pool_delete_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:62
graphene::market_history::lp_ticker_meta_object::rolling_min_lp_his_id
object_id_type rolling_min_lp_his_id
Definition: market_history_plugin.hpp:294
graphene::market_history::liquidity_pool_ticker_object::total_deposit_count
uint64_t total_deposit_count
Definition: market_history_plugin.hpp:324
graphene::market_history::bucket_object::low_base
share_type low_base
Definition: market_history_plugin.hpp:93
graphene::market_history::market_history_plugin::max_history
uint32_t max_history() const
Definition: market_history_plugin.cpp:810
graphene::app::application
Definition: application.hpp:91
graphene::db::object_database::find
const T * find(const object_id_type &id) const
Definition: object_database.hpp:126
graphene::market_history::detail::operation_process_fill_order::_plugin
market_history_plugin & _plugin
Definition: market_history_plugin.cpp:73
graphene::market_history::liquidity_pool_ticker_object::_24h_deposit_count
uint32_t _24h_deposit_count
Definition: market_history_plugin.hpp:304
graphene::market_history::market_history_plugin::plugin_initialize
void plugin_initialize(const boost::program_options::variables_map &options) override
Perform early startup routines and register plugin indexes, callbacks, etc.
Definition: market_history_plugin.cpp:773
graphene::protocol::liquidity_pool_withdraw_operation
Withdraw from a liquidity pool.
Definition: liquidity_pool.hpp:114
graphene::market_history::order_history_object
Definition: market_history_plugin.hpp:115
graphene::market_history::bucket_key::seconds
uint32_t seconds
Definition: market_history_plugin.hpp:72
graphene::market_history::market_history_plugin
Definition: market_history_plugin.hpp:364
graphene::market_history::detail::market_history_plugin_impl::update_liquidity_pool_histories
void update_liquidity_pool_histories(time_point_sec time, const operation_history_object &oho, const lp_ticker_meta_object *&lp_meta)
process all operations related to liquidity pools
Definition: market_history_plugin.cpp:536
graphene::market_history::market_ticker_object::base_volume
fc::uint128_t base_volume
Definition: market_history_plugin.hpp:147
graphene::market_history::liquidity_pool_ticker_object::total_withdrawal_amount_b
fc::uint128_t total_withdrawal_amount_b
Definition: market_history_plugin.hpp:330
graphene::market_history::liquidity_pool_ticker_object::total_exchange_fee_b
fc::uint128_t total_exchange_fee_b
Definition: market_history_plugin.hpp:341
graphene::db::object_id_type::instance
uint64_t instance() const
Definition: object_id.hpp:49
graphene::market_history::detail::get_liquidity_pool_id_visitor::operator()
result_type operator()(const T &) const
Definition: market_history_plugin.cpp:504
graphene::protocol::fill_order_operation::pays
asset pays
Definition: market.hpp:216
graphene::market_history::market_ticker_meta_object::rolling_min_order_his_id
object_id_type rolling_min_order_his_id
Definition: market_history_plugin.hpp:154
graphene::market_history::detail::operation_process_fill_order::result_type
void result_type
Definition: market_history_plugin.cpp:80
graphene::market_history::history_key::base
asset_id_type base
Definition: market_history_plugin.hpp:104
graphene::market_history::detail::get_liquidity_pool_id_visitor::operator()
result_type operator()(const liquidity_pool_withdraw_operation &o) const
Definition: market_history_plugin.cpp:524
graphene::market_history::bucket_key::quote
asset_id_type quote
Definition: market_history_plugin.hpp:71
graphene::market_history::bucket_object::high_base
share_type high_base
Definition: market_history_plugin.hpp:91
graphene::market_history::liquidity_pool_ticker_object::_24h_withdrawal_count
uint32_t _24h_withdrawal_count
Definition: market_history_plugin.hpp:308
graphene::db::object_database::add_index
IndexType * add_index()
Definition: object_database.hpp:144
graphene::db::index::get
const object & get(object_id_type id) const
Definition: index.hpp:110
FC_CAPTURE_AND_LOG
#define FC_CAPTURE_AND_LOG(...)
Definition: exception.hpp:438
fc::optional::valid
bool valid() const
Definition: optional.hpp:186
graphene::market_history::market_history_plugin::plugin_startup
void plugin_startup() override
Begin normal runtime operations.
Definition: market_history_plugin.cpp:801
graphene::market_history::market_ticker_object::latest_base
share_type latest_base
Definition: market_history_plugin.hpp:145
config.hpp
graphene::market_history::detail::market_history_plugin_impl::_max_order_his_seconds_per_market
uint32_t _max_order_his_seconds_per_market
Definition: market_history_plugin.cpp:67
evaluator.hpp
graphene::market_history::liquidity_pool_ticker_object::_24h_withdrawal_fee_a
fc::uint128_t _24h_withdrawal_fee_a
Definition: market_history_plugin.hpp:312
fc::time_point_sec
Definition: time.hpp:74
graphene::protocol::asset::asset_id
asset_id_type asset_id
Definition: asset.hpp:37
graphene::market_history::liquidity_pool_ticker_object::total_withdrawal_share_amount
fc::uint128_t total_withdrawal_share_amount
Definition: market_history_plugin.hpp:331
account_object.hpp
thread.hpp
graphene::protocol::generic_exchange_operation_result
Definition: base.hpp:95
graphene::market_history::market_history_plugin::market_history_plugin
market_history_plugin(graphene::app::application &app)
Definition: market_history_plugin.cpp:732
fc::variant::as
T as(uint32_t max_depth) const
Definition: variant.hpp:337
graphene::protocol::liquidity_pool_deposit_operation
Deposit to a liquidity pool.
Definition: liquidity_pool.hpp:94
graphene::market_history::bucket_object::base_volume
share_type base_volume
Definition: market_history_plugin.hpp:99
graphene::market_history::liquidity_pool_ticker_object::_24h_exchange_b2a_amount_b
fc::uint128_t _24h_exchange_b2a_amount_b
Definition: market_history_plugin.hpp:319
graphene::market_history::bucket_object::close_base
share_type close_base
Definition: market_history_plugin.hpp:97
graphene::protocol::liquidity_pool_withdraw_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:120
graphene::market_history::detail::get_liquidity_pool_id_visitor
Definition: market_history_plugin.cpp:498
graphene::market_history::liquidity_pool_ticker_object::total_withdrawal_amount_a
fc::uint128_t total_withdrawal_amount_a
Definition: market_history_plugin.hpp:329
graphene::market_history::detail::operation_process_fill_order
Definition: market_history_plugin.cpp:71
graphene::market_history::market_ticker_object::last_day_base
share_type last_day_base
Definition: market_history_plugin.hpp:143
graphene::market_history::liquidity_pool_ticker_object::total_withdrawal_fee_b
fc::uint128_t total_withdrawal_fee_b
Definition: market_history_plugin.hpp:333
graphene::market_history::liquidity_pool_ticker_object::_24h_withdrawal_amount_b
fc::uint128_t _24h_withdrawal_amount_b
Definition: market_history_plugin.hpp:310
graphene::market_history::detail::operation_process_fill_order::operator()
void operator()(const T &) const
Definition: market_history_plugin.cpp:84
graphene::market_history::liquidity_pool_ticker_object::_24h_deposit_amount_a
fc::uint128_t _24h_deposit_amount_a
Definition: market_history_plugin.hpp:305
graphene::market_history::detail::get_liquidity_pool_id_visitor::operator()
result_type operator()(const liquidity_pool_delete_operation &o) const
Definition: market_history_plugin.cpp:509
graphene::market_history::market_history_plugin::~market_history_plugin
~market_history_plugin() override
graphene::market_history::liquidity_pool_ticker_object::_24h_exchange_fee_a
fc::uint128_t _24h_exchange_fee_a
Definition: market_history_plugin.hpp:320
graphene::protocol::liquidity_pool_deposit_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:100
graphene::market_history::liquidity_pool_ticker_object::_24h_deposit_amount_b
fc::uint128_t _24h_deposit_amount_b
Definition: market_history_plugin.hpp:306
graphene::protocol::liquidity_pool_update_operation
Update a liquidity pool.
Definition: liquidity_pool.hpp:74
graphene::market_history::liquidity_pool_ticker_object::total_exchange_b2a_amount_b
fc::uint128_t total_exchange_b2a_amount_b
Definition: market_history_plugin.hpp:339
graphene::market_history::detail::market_history_plugin_impl::_tracked_buckets
flat_set< uint32_t > _tracked_buckets
Definition: market_history_plugin.cpp:64
graphene::market_history::lp_ticker_meta_object::skip_min_lp_his_id
bool skip_min_lp_his_id
Definition: market_history_plugin.hpp:295
graphene::market_history::liquidity_pool_ticker_object::total_exchange_b2a_count
uint64_t total_exchange_b2a_count
Definition: market_history_plugin.hpp:337
graphene::market_history::liquidity_pool_history_object::op_type
int64_t op_type
Definition: market_history_plugin.hpp:223
fc::static_variant::is_type
bool is_type() const
Definition: static_variant.hpp:332
graphene::market_history::bucket_key
Definition: market_history_plugin.hpp:64
graphene::market_history::detail::operation_process_fill_order::operator()
void operator()(const fill_order_operation &o) const
Definition: market_history_plugin.cpp:86
graphene::db::object_id_type
Definition: object_id.hpp:30
graphene::protocol::asset::amount
share_type amount
Definition: asset.hpp:36
operation_history_object.hpp
fc::static_variant::get
X & get()
Definition: static_variant.hpp:236
graphene::db::object_id
Definition: object_id.hpp:103
std
Definition: zeroed_array.hpp:76
graphene::market_history::detail::get_liquidity_pool_id_visitor::operator()
result_type operator()(const liquidity_pool_deposit_operation &o) const
Definition: market_history_plugin.cpp:519
graphene::protocol::liquidity_pool_delete_operation
Delete a liquidity pool.
Definition: liquidity_pool.hpp:56
fc::static_variant::which
tag_type which() const
Definition: static_variant.hpp:329
graphene::market_history::bucket_object::low
price low() const
Definition: market_history_plugin.hpp:88
graphene::chain::operation_history_object::result
operation_result result
Definition: operation_history_object.hpp:59
transaction_evaluation_state.hpp
graphene::market_history::lp_ticker_meta_object
Stores meta data for liquidity pool tickers.
Definition: market_history_plugin.hpp:291
graphene::market_history::liquidity_pool_ticker_object::total_exchange_fee_a
fc::uint128_t total_exchange_fee_a
Definition: market_history_plugin.hpp:340
graphene::protocol::fill_order_operation::receives
asset receives
Definition: market.hpp:217
graphene::protocol::price::base
asset base
Definition: asset.hpp:113
graphene::db::generic_index
Definition: generic_index.hpp:43
graphene::market_history::liquidity_pool_history_object
Definition: market_history_plugin.hpp:217
graphene::market_history::market_history_plugin::plugin_set_program_options
void plugin_set_program_options(boost::program_options::options_description &cli, boost::program_options::options_description &cfg) override
Fill in command line parameters used by the plugin.
Definition: market_history_plugin.cpp:746
graphene::market_history::detail::get_liquidity_pool_id_visitor::result_type
optional< liquidity_pool_id_type > result_type
Definition: market_history_plugin.cpp:500
fc::static_variant::visit
visitor::result_type visit(visitor &v)
Definition: static_variant.hpp:256
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
graphene::market_history::market_history_plugin::max_order_his_seconds_per_market
uint32_t max_order_his_seconds_per_market() const
Definition: market_history_plugin.cpp:820
graphene::market_history::liquidity_pool_ticker_object::total_exchange_b2a_amount_a
fc::uint128_t total_exchange_b2a_amount_a
Definition: market_history_plugin.hpp:338
graphene::market_history::liquidity_pool_ticker_object::total_exchange_a2b_amount_a
fc::uint128_t total_exchange_a2b_amount_a
Definition: market_history_plugin.hpp:335
graphene::protocol::liquidity_pool_update_operation::pool
liquidity_pool_id_type pool
ID of the liquidity pool.
Definition: liquidity_pool.hpp:80
graphene::market_history::detail::market_history_plugin_impl
Definition: market_history_plugin.cpp:43
graphene::protocol::signed_block
Definition: block.hpp:64
graphene::market_history::bucket_object::quote_volume
share_type quote_volume
Definition: market_history_plugin.hpp:100
graphene::db::object_database::get_index_type
const IndexType & get_index_type() const
Definition: object_database.hpp:77
fc::safe::value
T value
Definition: safe.hpp:28
graphene::market_history::market_ticker_object::quote_volume
fc::uint128_t quote_volume
Definition: market_history_plugin.hpp:148
graphene::market_history::liquidity_pool_ticker_object::_24h_exchange_a2b_amount_a
fc::uint128_t _24h_exchange_a2b_amount_a
Definition: market_history_plugin.hpp:315
graphene::market_history::liquidity_pool_ticker_object::_24h_withdrawal_share_amount
fc::uint128_t _24h_withdrawal_share_amount
Definition: market_history_plugin.hpp:311
graphene::market_history::detail::operation_process_fill_order::_now
fc::time_point_sec _now
Definition: market_history_plugin.cpp:74
graphene::protocol::generic_operation_result
Definition: base.hpp:88
graphene::market_history::liquidity_pool_ticker_object::total_exchange_a2b_count
uint64_t total_exchange_a2b_count
Definition: market_history_plugin.hpp:334
graphene::protocol::price::quote
asset quote
Definition: asset.hpp:114
graphene
Definition: api.cpp:48
graphene::market_history::market_ticker_object
Definition: market_history_plugin.hpp:138
graphene::market_history::liquidity_pool_ticker_object::_24h_exchange_a2b_amount_b
fc::uint128_t _24h_exchange_a2b_amount_b
Definition: market_history_plugin.hpp:316
graphene::market_history::market_ticker_meta_object
Definition: market_history_plugin.hpp:151
graphene::db::object_database::modify
void modify(const T &obj, const Lambda &m)
Definition: object_database.hpp:99
graphene::market_history::liquidity_pool_ticker_object::total_deposit_amount_b
fc::uint128_t total_deposit_amount_b
Definition: market_history_plugin.hpp:326
graphene::chain::operation_history_object
tracks the history of all logical operations on blockchain state
Definition: operation_history_object.hpp:48
graphene::market_history::liquidity_pool_ticker_object::_24h_balance_delta_b
share_type _24h_balance_delta_b
Definition: market_history_plugin.hpp:323
graphene::market_history::market_history_plugin::plugin_name
std::string plugin_name() const override
Get the name of the plugin.
Definition: market_history_plugin.cpp:741