Scorum
account_history_api.cpp
Go to the documentation of this file.
9 
10 #include <map>
11 
12 namespace scorum {
13 namespace blockchain_history {
14 
15 namespace detail {
17 {
18 public:
20 
21 public:
23  : _app(app)
24  {
25  }
26 
27  template <typename history_object_type, typename fill_result_functor>
28  void get_history(const std::string& account, uint64_t from, uint32_t limit, fill_result_functor& funct) const
29  {
30  const auto db = _app.chain_database();
31 
32  FC_ASSERT(limit > 0, "Limit must be greater than zero");
33  FC_ASSERT(limit <= get_api_config(API_ACCOUNT_HISTORY).max_blockchain_history_depth,
34  "Limit of ${l} is greater than maxmimum allowed ${2}",
35  ("l", limit)("2", get_api_config(API_ACCOUNT_HISTORY).max_blockchain_history_depth));
36  FC_ASSERT(from >= limit, "From must be greater than limit");
37 
38  const auto& idx = db->get_index<account_history_index<history_object_type>, by_account>();
39  auto itr = idx.lower_bound(boost::make_tuple(account, from));
40  if (itr != idx.end())
41  {
42  auto end = idx.upper_bound(boost::make_tuple(account, int64_t(0)));
43  int64_t pos = int64_t(itr->sequence) - limit;
44  if (pos > 0)
45  {
46  end = idx.lower_bound(boost::make_tuple(account, pos));
47  }
48  while (itr != end)
49  {
50  funct(*itr);
51  ++itr;
52  }
53  }
54  }
55 
56  template <typename history_object_type>
57  std::map<uint32_t, applied_operation> get_history(const std::string& account, uint64_t from, uint32_t limit) const
58  {
59  std::map<uint32_t, applied_operation> result;
60 
61  const auto db = _app.chain_database();
62 
63  auto fill_funct = [&](const history_object_type& hobj) { result[hobj.sequence] = db->get(hobj.op); };
64  this->template get_history<history_object_type>(account, from, limit, fill_funct);
65 
66  return result;
67  }
68 };
69 } // namespace detail
70 
72  : _impl(new detail::account_history_api_impl(ctx.app))
73 {
74 }
75 
77 {
78 }
79 
81 {
82 }
83 
84 std::map<uint32_t, applied_operation>
85 account_history_api::get_account_scr_to_scr_transfers(const std::string& account, uint64_t from, uint32_t limit) const
86 {
87  const auto db = _impl->_app.chain_database();
88  return db->with_read_lock(
89  [&]() { return _impl->get_history<account_transfers_to_scr_history_object>(account, from, limit); });
90 }
91 
92 std::map<uint32_t, applied_operation>
93 account_history_api::get_account_scr_to_sp_transfers(const std::string& account, uint64_t from, uint32_t limit) const
94 {
95  const auto db = _impl->_app.chain_database();
96  return db->with_read_lock(
97  [&]() { return _impl->get_history<account_transfers_to_sp_history_object>(account, from, limit); });
98 }
99 
100 std::map<uint32_t, applied_operation>
101 account_history_api::get_account_history(const std::string& account, uint64_t from, uint32_t limit) const
102 {
103  const auto db = _impl->_app.chain_database();
104  return db->with_read_lock([&]() { return _impl->get_history<account_history_object>(account, from, limit); });
105 }
106 
107 std::map<uint32_t, applied_withdraw_operation>
108 account_history_api::get_account_sp_to_scr_transfers(const std::string& account, uint64_t from, uint32_t limit) const
109 {
110  const auto db = _impl->_app.chain_database();
111  return db->with_read_lock([&]() {
112  std::map<uint32_t, applied_withdraw_operation> result;
113 
114  auto fill_funct = [&](const account_withdrawals_to_scr_history_object& obj) {
115  auto it = result.emplace(obj.sequence, applied_withdraw_operation(db->get(obj.op))).first;
116  auto& applied_op = it->second;
117 
118  share_type to_withdraw = 0;
119  applied_op.op.weak_visit(
120  [&](const withdraw_scorumpower_operation& op) { to_withdraw = op.scorumpower.amount; });
121 
122  if (to_withdraw == 0u)
123  {
124  // If this is a zero-withdraw (such withdraw closes current active withdraw)
125  applied_op.status = applied_withdraw_operation::empty;
126  }
127  else if (!obj.progress.empty())
128  {
129  auto last_op = fc::raw::unpack<operation>(db->get(obj.progress.back()).serialized_op);
130 
131  last_op.weak_visit(
133  // if last 'progress' operation is 'acc_finished_' then withdraw was finished
134  applied_op.status = applied_withdraw_operation::finished;
135  },
136  [&](const withdraw_scorumpower_operation&) {
137  // if last 'progress' operation is 'withdraw_scorumpower_' then withdraw was either interrupted
138  // or finished depending on pre-last 'progress' operation
139  applied_op.status = applied_withdraw_operation::interrupted;
140  });
141 
142  if (obj.progress.size() > 1)
143  {
144  auto before_last_op_obj = db->get(*(obj.progress.rbegin() + 1));
145  auto before_last_op = fc::raw::unpack<operation>(before_last_op_obj.serialized_op);
146 
147  before_last_op.weak_visit([&](const acc_finished_vesting_withdraw_operation&) {
148  // if pre-last 'progress' operation is 'acc_finished_' then withdraw was finished
149  applied_op.status = applied_withdraw_operation::finished;
150  });
151  }
152 
153  for (auto& id : obj.progress)
154  {
155  auto op = fc::raw::unpack<operation>(db->get(id).serialized_op);
156 
157  op.weak_visit(
159  applied_op.withdrawn += op.withdrawn.amount;
160  },
162  applied_op.withdrawn += op.withdrawn.amount;
163  });
164  }
165  }
166  };
167  _impl->get_history<account_withdrawals_to_scr_history_object>(account, from, limit, fill_funct);
168 
169  return result;
170  });
171 }
172 
173 } // namespace blockchain_history
174 } // namespace scorum
#define API_ACCOUNT_HISTORY
std::shared_ptr< chain::database > chain_database() const
account_history_api(const scorum::app::api_context &ctx)
std::map< uint32_t, applied_operation > get_history(const std::string &account, uint64_t from, uint32_t limit) const
void get_history(const std::string &account, uint64_t from, uint32_t limit, fill_result_functor &funct) const
std::map< uint32_t, applied_operation > get_account_history(const std::string &account, uint64_t from, uint32_t limit) const
std::map< uint32_t, applied_operation > get_account_scr_to_scr_transfers(const std::string &account, uint64_t from, uint32_t limit) const
std::map< uint32_t, applied_operation > get_account_scr_to_sp_transfers(const std::string &account, uint64_t from, uint32_t limit) const
std::map< uint32_t, applied_withdraw_operation > get_account_sp_to_scr_transfers(const std::string &account, uint64_t from, uint32_t limit) const
shared_multi_index_container< history_object_t, indexed_by< ordered_unique< tag< by_id >, member< history_object_t, typename history_object_t::id_type, &history_object_t::id > >, ordered_unique< tag< by_account >, composite_key< history_object_t, member< history_object_t, account_name_type, &history_object_t::account >, member< history_object_t, uint32_t, &history_object_t::sequence > >, composite_key_compare< std::less< account_name_type >, std::greater< uint32_t > >> >> account_history_index
fc::safe< share_value_type > share_type
Definition: types.hpp:73
Definition: asset.cpp:15
config_api & get_api_config(std::string api_name)
Definition: config_api.cpp:114
share_type amount
Definition: asset.hpp:31