9 #include <fc/static_variant.hpp>
11 #include <boost/lambda/lambda.hpp>
14 namespace blockchain_history {
22 std::shared_ptr<chain::database>
_db;
25 template <
typename ObjectType>
applied_operation get_filtered_operation(
const ObjectType& obj)
const
27 return _db->get(obj.op);
32 return get_filtered_operation(obj);
37 return get_filtered_operation(obj);
42 return get_filtered_operation(obj);
45 applied_operation get_operation(
const operation_object& obj)
const
47 applied_operation temp;
52 inline uint32_t get_head_block()
const
54 return _db->obtain_service<dbs_dynamic_global_property>().get().head_block_number;
68 FC_ASSERT(limit > 0,
"Limit must be greater than zero");
70 "Limit of ${l} is greater than maxmimum allowed ${2}",
72 FC_ASSERT(from_op >= limit,
"From must be greater than limit");
74 if (from_op != std::numeric_limits<decltype(from_op)>::max())
81 const auto& idx =
_db->get_index<IndexType, by_id>();
86 auto itr = idx.lower_bound(from_op);
90 auto start = (int64_t(itr->id._id) - limit);
91 auto end = itr->id._id;
92 auto range = idx.range(start < boost::lambda::_1, boost::lambda::_1 <= end);
94 for (
auto it = range.first; it != range.second; ++it)
97 FC_ASSERT(
id._id >= 0,
"Invalid operation_object id");
98 result[(uint32_t)
id._id] = get_operation(*it);
104 template <
typename IndexType>
106 const fc::time_point_sec& to,
108 uint32_t limit)
const
110 FC_ASSERT(from <= to,
"'From' is greater than 'to'");
112 "Timestamp range can't be more then ${t} seconds",
114 FC_ASSERT(limit > 0,
"Limit must be greater than zero");
116 "Limit of ${l} is greater than maxmimum allowed ${2}",
118 FC_ASSERT(from_op >= limit,
"From must be greater than limit");
122 const auto& idx =
_db->get_index<IndexType, by_timestamp>();
126 auto range = idx.range(::boost::lambda::_1 >= std::make_tuple(from, 0),
127 ::boost::lambda::_1 <= std::make_tuple(to,
ALL_IDS));
129 for (
auto it = range.first; limit && it != range.second; ++it)
132 FC_ASSERT(
id._id >= 0,
"Invalid operation_object id");
138 result[(uint32_t)
id._id] = get_operation(op);
150 auto range = idx.equal_range(block_num);
152 for (
auto it = range.first; it != range.second; ++it)
156 if (operation_filter(temp.
op))
158 FC_ASSERT(
id._id >= 0,
"Invalid operation_object id");
159 result[(uint32_t)
id._id] = temp;
171 FC_ASSERT(
false,
"This node's operator has disabled operation indexing by transaction_id");
173 FC_ASSERT(!
_app.
is_read_only(),
"get_transaction is not available in read-only mode.");
175 const auto& idx =
_db->get_index<
operation_index>().indices().get<by_transaction_id>();
176 auto itr = idx.lower_bound(
id);
177 if (itr != idx.end() && itr->trx_id == id)
179 auto blk =
_db->fetch_block_by_number(itr->block);
180 FC_ASSERT(blk.valid());
181 FC_ASSERT(blk->transactions.size() > itr->trx_in_block);
183 result.block_num = itr->block;
184 result.transaction_num = itr->trx_in_block;
187 FC_ASSERT(
false,
"Unknown Transaction ${t}", (
"t",
id));
191 optional<signed_block>
get_block(uint32_t block_num)
const
193 return _db->fetch_block_by_number(block_num);
199 "Limit of ${l} is greater than maxmimum allowed ${2}",
201 FC_ASSERT(limit > 0,
"Limit must be greater than zero");
202 FC_ASSERT(block_num >= limit,
"block_num must be greater than limit");
206 uint32_t head_block_num = get_head_block();
207 if (block_num > head_block_num)
209 block_num = head_block_num;
212 uint32_t from_block_num = (block_num > limit) ? block_num - limit : 0;
214 std::map<uint32_t, T>
result;
215 optional<signed_block> b;
216 while (from_block_num != block_num)
218 b =
_db->fetch_block_by_number(block_num);
229 std::vector<block_api_object>
get_blocks(uint32_t block_num, uint32_t limit)
const
232 "Limit of ${l} is greater than maxmimum allowed ${2}",
234 FC_ASSERT(limit > 0,
"Limit must be greater than zero");
235 FC_ASSERT(block_num >= limit,
"block_num must be greater than limit");
239 uint32_t head_block_num = get_head_block();
240 if (block_num > head_block_num)
242 block_num = head_block_num;
245 uint32_t from_block_num = (block_num > limit) ? block_num - limit : 0;
247 std::vector<block_api_object>
result;
248 optional<signed_block> b;
249 while (from_block_num != block_num)
251 b =
_db->fetch_block_by_number(block_num);
260 for (
auto pair : operations)
279 : _impl(new detail::blockchain_history_api_impl(ctx.app))
294 return _impl->_app.chain_database()->with_read_lock([&]() {
295 switch (type_of_operation)
311 const fc::time_point_sec& to,
313 uint32_t limit)
const
315 return _impl->_app.chain_database()->with_read_lock(
316 [&]() {
return _impl->get_ops_history_by_time<
operation_index>(from, to, from_op, limit); });
319 std::map<uint32_t, applied_operation>
322 return _impl->_app.chain_database()->with_read_lock([&]() {
323 switch (type_of_operation)
334 return _impl->get_ops_in_block(block_num, [&](
const operation& op) {
return true; });
340 return _impl->_app.chain_database()->with_read_lock([&]() {
return _impl->get_transaction(
id); });
349 return _impl->_db->with_read_lock([&]() {
return _impl->get_block(block_num); });
354 return _impl->_db->with_read_lock([&]() {
return _impl->get_block(block_num); });
358 uint32_t limit)
const
360 FC_ASSERT(!_impl->_app.is_read_only(),
"Disabled for read only mode");
361 return _impl->_db->with_read_lock(
362 [&]() {
return _impl->get_blocks_history_by_number<
block_header>(block_num, limit); });
366 uint32_t limit)
const
368 FC_ASSERT(!_impl->_app.is_read_only(),
"Disabled for read only mode");
369 return _impl->_db->with_read_lock(
375 return _impl->_db->with_read_lock([&]() {
return _impl->get_blocks(from, limit); });
#define API_BLOCKCHAIN_HISTORY
bool is_read_only() const
blockchain_history_api(const scorum::app::api_context &ctx)
~blockchain_history_api()
std::map< uint32_t, T > get_blocks_history_by_number(uint32_t block_num, uint32_t limit) const
std::shared_ptr< chain::database > _db
result_type get_ops_history(uint32_t from_op, uint32_t limit) const
scorum::app::application & _app
result_type get_ops_history_by_time(const fc::time_point_sec &from, const fc::time_point_sec &to, uint32_t from_op, uint32_t limit) const
blockchain_history_api_impl(scorum::app::application &app)
std::vector< block_api_object > get_blocks(uint32_t block_num, uint32_t limit) const
result_type get_ops_in_block(uint32_t block_num, Filter operation_filter) const
optional< signed_block > get_block(uint32_t block_num) const
annotated_signed_transaction get_transaction(transaction_id_type id) const
std::map< uint32_t, applied_operation > result_type
std::map< uint32_t, applied_operation > get_ops_history_by_time(const fc::time_point_sec &from, const fc::time_point_sec &to, uint32_t from_op, uint32_t limit) const
This method returns all operations in timestamp range [from, to].
annotated_signed_transaction get_transaction(transaction_id_type trx_id) const
This method returns signed transaction by transaction id.
std::vector< block_api_object > get_blocks(uint32_t from, uint32_t limit) const
Retrieve the list of blocks from block log in range [from-limit, from].
std::map< uint32_t, block_header > get_block_headers_history(uint32_t block_num, uint32_t limit) const
Retrieve the list of block headers in range [from-limit, from].
std::map< uint32_t, applied_operation > get_ops_history(uint32_t from_op, uint32_t limit, applied_operation_type type_of_operation) const
This method returns all operations in ids range [from-limit, from].
optional< block_header > get_block_header(uint32_t block_num) const
Retrieve a block header.
std::map< uint32_t, signed_block_api_obj > get_blocks_history(uint32_t block_num, uint32_t limit) const
Retrieve the list of signed block from block log (irreversible blocks) in range [from-limit,...
std::map< uint32_t, applied_operation > get_ops_in_block(uint32_t block_num, applied_operation_type type_of_operation) const
Returns sequence of operations included/generated in a specified block.
optional< signed_block_api_obj > get_block(uint32_t block_num) const
Retrieve a full, signed block.
filtered_operation_index< filtered_market_operations_history > filtered_market_operations_history_index
filtered_operation_index< filtered_virt_operations_history > filtered_virt_operations_history_index
shared_multi_index_container< operation_object, indexed_by< ordered_unique< tag< by_id >, member< operation_object, operation_object::id_type, &operation_object::id > >, ordered_unique< tag< by_location >, composite_key< operation_object, member< operation_object, uint32_t, &operation_object::block >, member< operation_object, uint32_t, &operation_object::trx_in_block >, member< operation_object, uint16_t, &operation_object::op_in_trx >, member< operation_object, operation_object::id_type, &operation_object::id > > >, ordered_unique< tag< by_timestamp >, composite_key< operation_object, member< operation_object, fc::time_point_sec, &operation_object::timestamp >, member< operation_object, operation_object::id_type, &operation_object::id > > >, ordered_unique< tag< by_transaction_id >, composite_key< operation_object, member< operation_object, transaction_id_type, &operation_object::trx_id >, member< operation_object, operation_object::id_type, &operation_object::id > > > > > operation_index
filtered_operation_index< filtered_not_virt_operations_history > filtered_not_virt_operations_history_index
filtered_operation_object< filtered_market_operations_history > filtered_market_operations_history_object
fc::ripemd160 transaction_id_type
fc::static_variant< vote_operation, comment_operation, transfer_operation, transfer_to_scorumpower_operation, withdraw_scorumpower_operation, account_create_by_committee_operation, account_create_operation, account_create_with_delegation_operation, account_update_operation, witness_update_operation, account_witness_vote_operation, account_witness_proxy_operation, delete_comment_operation, comment_options_operation, set_withdraw_scorumpower_route_to_account_operation, set_withdraw_scorumpower_route_to_dev_pool_operation, prove_authority_operation, request_account_recovery_operation, recover_account_operation, change_recovery_account_operation, escrow_approve_operation, escrow_dispute_operation, escrow_release_operation, escrow_transfer_operation, decline_voting_rights_operation, delegate_scorumpower_operation, create_budget_operation, close_budget_operation, proposal_vote_operation, proposal_create_operation, atomicswap_initiate_operation, atomicswap_redeem_operation, atomicswap_refund_operation, close_budget_by_advertising_moderator_operation, update_budget_operation, create_game_operation, cancel_game_operation, update_game_markets_operation, update_game_start_time_operation, post_game_results_operation, post_bet_operation, cancel_pending_bets_operation, delegate_sp_from_reg_pool_operation, create_nft_operation, update_nft_meta_operation, create_game_round_operation, update_game_round_result_operation, adjust_nft_experience_operation, update_nft_name_operation, author_reward_operation, comment_benefficiary_reward_operation, comment_payout_update_operation, comment_reward_operation, curation_reward_operation, hardfork_operation, producer_reward_operation, active_sp_holders_reward_operation, return_scorumpower_delegation_operation, shutdown_witness_operation, witness_miss_block_operation, expired_contract_refund_operation, acc_finished_vesting_withdraw_operation, devpool_finished_vesting_withdraw_operation, acc_to_acc_vesting_withdraw_operation, devpool_to_acc_vesting_withdraw_operation, acc_to_devpool_vesting_withdraw_operation, devpool_to_devpool_vesting_withdraw_operation, proposal_virtual_operation, budget_outgo_operation, budget_owner_income_operation, active_sp_holders_reward_legacy_operation, budget_closing_operation, bets_matched_operation, game_status_changed_operation, bet_resolved_operation, bet_cancelled_operation, bet_restored_operation, bet_updated_operation > operation
bool is_virtual_operation(const operation &op)
bool is_market_operation(const operation &op)
config_api & get_api_config(std::string api_name)
std::vector< block_api_operation_object > operations