COOPENOMICS  v1
Кооперативная Экономика
block_info.hpp
См. документацию.
1#pragma once
2
3#include <eosio/multi_index.hpp>
4#include <eosio/name.hpp>
5#include <eosio/time.hpp>
6
7#include <limits>
8#include <optional>
9
11
12static constexpr uint32_t rolling_window_size = 10;
13
23struct [[eosio::table, eosio::contract("eosio.system")]] block_info_record
24{
25 uint8_t version = 0;
26 uint32_t block_height;
28
29 uint64_t primary_key() const { return block_height; }
30
31 EOSLIB_SERIALIZE(block_info_record, (version)(block_height)(block_timestamp))
32};
33
34using block_info_table = eosio::multi_index<"blockinfo"_n, block_info_record>;
35
37{
42};
43
45{
46 enum error_code_enum : uint32_t
47 {
52 };
53
54 std::optional<block_batch_info> result;
56};
57
85 uint32_t batch_size,
86 eosio::name system_account_name = "eosio"_n)
87{
89
90 if (batch_size == 0) {
92 return result;
93 }
94
95 block_info_table t(system_account_name, 0);
96
97 // Find information on latest block recorded in the blockinfo table.
98
99 if (t.cbegin() == t.cend()) {
100 // The blockinfo table is empty.
102 return result;
103 }
104
105 auto latest_block_info_itr = --t.cend();
106
107 if (latest_block_info_itr->version != 0) {
108 // Compiled code for this function within the calling contract has not been updated to support new version of
109 // the blockinfo table.
111 return result;
112 }
113
114 uint32_t latest_block_batch_end_height = latest_block_info_itr->block_height;
115
116 if (latest_block_batch_end_height < batch_start_height_offset) {
117 // Caller asking for a block batch that has not even begun to be recorded yet.
119 return result;
120 }
121
122 // Calculate height for the starting block of the latest block batch.
123
124 uint32_t latest_block_batch_start_height =
125 latest_block_batch_end_height - ((latest_block_batch_end_height - batch_start_height_offset) % batch_size);
126
127 // Note: 1 <= (latest_block_batch_end_height - latest_block_batch_start_height + 1) <= batch_size
128
129 if (latest_block_batch_start_height == latest_block_batch_end_height) {
130 // When batch_size == 1, this function effectively simplifies to just returning the info of the latest recorded
131 // block. In that case, the start block and the end block of the batch are the same and there is no need for
132 // another lookup. So shortcut the rest of the process and return a successful result immediately.
133 result.result.emplace(block_batch_info{
134 .batch_start_height = latest_block_batch_start_height,
135 .batch_start_timestamp = latest_block_info_itr->block_timestamp,
136 .batch_current_end_height = latest_block_batch_end_height,
137 .batch_current_end_timestamp = latest_block_info_itr->block_timestamp,
138 });
139 return result;
140 }
141
142 // Find information on start block of the latest block batch recorded in the blockinfo table.
143
144 auto start_block_info_itr = t.find(latest_block_batch_start_height);
145 if (start_block_info_itr == t.cend() || start_block_info_itr->block_height != latest_block_batch_start_height) {
146 // Record for information on start block of the latest block batch could not be found in blockinfo table.
147 // This is either because of:
148 // * a gap in recording info due to a failed onblock action;
149 // * a requested start block that was processed by onblock prior to deployment of the system contract code
150 // introducing the blockinfo table;
151 // * or, most likely, because the record for the requested start block was pruned from the blockinfo table as
152 // it fell out of the rolling window.
154 return result;
155 }
156
157 if (start_block_info_itr->version != 0) {
158 // Compiled code for this function within the calling contract has not been updated to support new version of
159 // the blockinfo table.
161 return result;
162 }
163
164 // Successfully return block_batch_info for the found latest block batch in its current state.
165
166 result.result.emplace(block_batch_info{
167 .batch_start_height = latest_block_batch_start_height,
168 .batch_start_timestamp = start_block_info_itr->block_timestamp,
169 .batch_current_end_height = latest_block_batch_end_height,
170 .batch_current_end_timestamp = latest_block_info_itr->block_timestamp,
171 });
172 return result;
173}
174
175} // namespace eosiosystem::block_info
contract
Definition: eosio.msig_tests.cpp:977
Definition: eosio.msig.hpp:34
Definition: block_info.hpp:10
latest_block_batch_info_result get_latest_block_batch_info(uint32_t batch_start_height_offset, uint32_t batch_size, eosio::name system_account_name="eosio"_n)
Definition: block_info.hpp:84
static constexpr uint32_t rolling_window_size
Definition: block_info.hpp:12
eosio::multi_index<"blockinfo"_n, block_info_record > block_info_table
Definition: block_info.hpp:34
eosio::time_point time_point
Definition: blockinfo_tester.hpp:30
Definition: block_info.hpp:37
uint32_t batch_current_end_height
Definition: block_info.hpp:40
uint32_t batch_start_height
Definition: block_info.hpp:38
eosio::time_point batch_current_end_timestamp
Definition: block_info.hpp:41
eosio::time_point batch_start_timestamp
Definition: block_info.hpp:39
Definition: block_info.hpp:24
uint32_t block_height
Definition: block_info.hpp:26
uint64_t primary_key() const
Definition: block_info.hpp:29
eosio::time_point block_timestamp
Definition: block_info.hpp:27
std::optional< block_batch_info > result
Definition: block_info.hpp:54
error_code_enum error_code
Definition: block_info.hpp:55