Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
resource_limits.cpp
Go to the documentation of this file.
7#include <boost/tuple/tuple_io.hpp>
9#include <algorithm>
10
11namespace sysio { namespace chain { namespace resource_limits {
12
18>;
19
20static_assert( config::rate_limiting_precision > 0, "config::rate_limiting_precision must be positive" );
21
22static uint64_t update_elastic_limit(uint64_t current_limit, uint64_t average_usage, const elastic_limit_parameters& params) {
23 uint64_t result = current_limit;
24 if (average_usage > params.target ) {
25 result = result * params.contract_rate;
26 } else {
27 result = result * params.expand_rate;
28 }
29 return std::min(std::max(result, params.max), params.max * params.max_multiplier);
30}
31
33 // At the very least ensure parameters are not set to values that will cause divide by zero errors later on.
34 // Stricter checks for sensible values can be added later.
35 SYS_ASSERT( periods > 0, resource_limit_exception, "elastic limit parameter 'periods' cannot be zero" );
36 SYS_ASSERT( contract_rate.denominator > 0, resource_limit_exception, "elastic limit parameter 'contract_rate' is not a well-defined ratio" );
37 SYS_ASSERT( expand_rate.denominator > 0, resource_limit_exception, "elastic limit parameter 'expand_rate' is not a well-defined ratio" );
38}
39
40
41void resource_limits_state_object::update_virtual_cpu_limit( const resource_limits_config_object& cfg ) {
42 //idump((average_block_cpu_usage.average()));
43 virtual_cpu_limit = update_elastic_limit(virtual_cpu_limit, average_block_cpu_usage.average(), cfg.cpu_limit_parameters);
44 //idump((virtual_cpu_limit));
45}
46
47void resource_limits_state_object::update_virtual_net_limit( const resource_limits_config_object& cfg ) {
48 virtual_net_limit = update_elastic_limit(virtual_net_limit, average_block_net_usage.average(), cfg.net_limit_parameters);
49}
50
52 resource_index_set::add_indices(_db);
53}
54
57 // see default settings in the declaration
58 });
59
61 // see default settings in the declaration
62
63 // start the chain off in a way that it is "congested" aka slow-start
64 state.virtual_cpu_limit = config.cpu_limit_parameters.max;
65 state.virtual_net_limit = config.net_limit_parameters.max;
66 });
67
68 if (auto dm_logger = _get_deep_mind_logger()) {
69 dm_logger->on_init_resource_limits(config, state);
70 }
71}
72
74 resource_index_set::walk_indices([this, &snapshot]( auto utils ){
75 snapshot->write_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ){
76 decltype(utils)::walk(_db, [this, &section]( const auto &row ) {
77 section.add_row(row, _db);
78 });
79 });
80 });
81}
82
84 resource_index_set::walk_indices([this, &snapshot]( auto utils ){
85 snapshot->read_section<typename decltype(utils)::index_t::value_type>([this]( auto& section ) {
86 bool more = !section.empty();
87 while(more) {
88 decltype(utils)::create(_db, [this, &section, &more]( auto &row ) {
89 more = section.read_row(row, _db);
90 });
91 }
92 });
93 });
94}
95
97 const auto& limits = _db.create<resource_limits_object>([&]( resource_limits_object& bl ) {
98 bl.owner = account;
99 });
100
101 const auto& usage = _db.create<resource_usage_object>([&]( resource_usage_object& bu ) {
102 bu.owner = account;
103 });
104 if (auto dm_logger = _get_deep_mind_logger()) {
105 dm_logger->on_newaccount_resource_limits(limits, usage);
106 }
107}
108
109void resource_limits_manager::set_block_parameters(const elastic_limit_parameters& cpu_limit_parameters, const elastic_limit_parameters& net_limit_parameters ) {
110 cpu_limit_parameters.validate();
111 net_limit_parameters.validate();
112 const auto& config = _db.get<resource_limits_config_object>();
113 if( config.cpu_limit_parameters == cpu_limit_parameters && config.net_limit_parameters == net_limit_parameters )
114 return;
116 c.cpu_limit_parameters = cpu_limit_parameters;
117 c.net_limit_parameters = net_limit_parameters;
118
119 if (auto dm_logger = _get_deep_mind_logger()) {
120 dm_logger->on_update_resource_limits_config(c);
121 }
122 });
123}
124
125void resource_limits_manager::update_account_usage(const flat_set<account_name>& accounts, uint32_t time_slot ) {
126 const auto& config = _db.get<resource_limits_config_object>();
127 for( const auto& a : accounts ) {
128 const auto& usage = _db.get<resource_usage_object,by_owner>( a );
129 _db.modify( usage, [&]( auto& bu ){
130 bu.net_usage.add( 0, time_slot, config.account_net_usage_average_window );
131 bu.cpu_usage.add( 0, time_slot, config.account_cpu_usage_average_window );
132 });
133 }
134}
135
136void resource_limits_manager::add_transaction_usage(const flat_set<account_name>& accounts, uint64_t cpu_usage, uint64_t net_usage, uint32_t time_slot ) {
137 const auto& state = _db.get<resource_limits_state_object>();
138 const auto& config = _db.get<resource_limits_config_object>();
139
140 for( const auto& a : accounts ) {
141
142 const auto& usage = _db.get<resource_usage_object,by_owner>( a );
143 int64_t unused;
144 int64_t net_weight;
145 int64_t cpu_weight;
146 get_account_limits( a, unused, net_weight, cpu_weight );
147
148 _db.modify( usage, [&]( auto& bu ){
149 bu.net_usage.add( net_usage, time_slot, config.account_net_usage_average_window );
150 bu.cpu_usage.add( cpu_usage, time_slot, config.account_cpu_usage_average_window );
151
152 if (auto dm_logger = _get_deep_mind_logger()) {
153 dm_logger->on_update_account_usage(bu);
154 }
155 });
156
157 if( cpu_weight >= 0 && state.total_cpu_weight > 0 ) {
158 uint128_t window_size = config.account_cpu_usage_average_window;
159 auto virtual_network_capacity_in_window = (uint128_t)state.virtual_cpu_limit * window_size;
160 auto cpu_used_in_window = ((uint128_t)usage.cpu_usage.value_ex * window_size) / (uint128_t)config::rate_limiting_precision;
161
162 uint128_t user_weight = (uint128_t)cpu_weight;
163 uint128_t all_user_weight = state.total_cpu_weight;
164
165 auto max_user_use_in_window = (virtual_network_capacity_in_window * user_weight) / all_user_weight;
166
167 SYS_ASSERT( cpu_used_in_window <= max_user_use_in_window,
168 tx_cpu_usage_exceeded,
169 "authorizing account '${n}' has insufficient cpu resources for this transaction",
170 ("n", name(a))
171 ("cpu_used_in_window",cpu_used_in_window)
172 ("max_user_use_in_window",max_user_use_in_window) );
173 }
174
175 if( net_weight >= 0 && state.total_net_weight > 0) {
176
177 uint128_t window_size = config.account_net_usage_average_window;
178 auto virtual_network_capacity_in_window = (uint128_t)state.virtual_net_limit * window_size;
179 auto net_used_in_window = ((uint128_t)usage.net_usage.value_ex * window_size) / (uint128_t)config::rate_limiting_precision;
180
181 uint128_t user_weight = (uint128_t)net_weight;
182 uint128_t all_user_weight = state.total_net_weight;
183
184 auto max_user_use_in_window = (virtual_network_capacity_in_window * user_weight) / all_user_weight;
185
186 SYS_ASSERT( net_used_in_window <= max_user_use_in_window,
187 tx_net_usage_exceeded,
188 "authorizing account '${n}' has insufficient net resources for this transaction",
189 ("n", name(a))
190 ("net_used_in_window",net_used_in_window)
191 ("max_user_use_in_window",max_user_use_in_window) );
192
193 }
194 }
195
196 // account for this transaction in the block and do not exceed those limits either
198 rls.pending_cpu_usage += cpu_usage;
199 rls.pending_net_usage += net_usage;
200 });
201
202 SYS_ASSERT( state.pending_cpu_usage <= config.cpu_limit_parameters.max, block_resource_exhausted, "Block has insufficient cpu resources" );
203 SYS_ASSERT( state.pending_net_usage <= config.net_limit_parameters.max, block_resource_exhausted, "Block has insufficient net resources" );
204}
205
207 if (ram_delta == 0) {
208 return;
209 }
210
211 const auto& usage = _db.get<resource_usage_object,by_owner>( account );
212
213 SYS_ASSERT( ram_delta <= 0 || UINT64_MAX - usage.ram_usage >= (uint64_t)ram_delta, transaction_exception,
214 "Ram usage delta would overflow UINT64_MAX");
215 SYS_ASSERT(ram_delta >= 0 || usage.ram_usage >= (uint64_t)(-ram_delta), transaction_exception,
216 "Ram usage delta would underflow UINT64_MAX");
217
218 _db.modify( usage, [&]( auto& u ) {
219 u.ram_usage += ram_delta;
220
221 if (auto dm_logger = _get_deep_mind_logger()) {
222 dm_logger->on_ram_event(account, u.ram_usage, ram_delta);
223 }
224 });
225}
226
228 int64_t ram_bytes; int64_t net_weight; int64_t cpu_weight;
229 get_account_limits( account, ram_bytes, net_weight, cpu_weight );
230 const auto& usage = _db.get<resource_usage_object,by_owner>( account );
231
232 if( ram_bytes >= 0 ) {
233 SYS_ASSERT( usage.ram_usage <= static_cast<uint64_t>(ram_bytes), ram_usage_exceeded,
234 "account ${account} has insufficient ram; needs ${needs} bytes has ${available} bytes",
235 ("account", account)("needs",usage.ram_usage)("available",ram_bytes) );
236 }
237}
238
240 return _db.get<resource_usage_object,by_owner>( name ).ram_usage;
241}
242
243
244bool resource_limits_manager::set_account_limits( const account_name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight) {
245 //const auto& usage = _db.get<resource_usage_object,by_owner>( account );
246 /*
247 * Since we need to delay these until the next resource limiting boundary, these are created in a "pending"
248 * state or adjusted in an existing "pending" state. The chain controller will collapse "pending" state into
249 * the actual state at the next appropriate boundary.
250 */
251 auto find_or_create_pending_limits = [&]() -> const resource_limits_object& {
252 const auto* pending_limits = _db.find<resource_limits_object, by_owner>( boost::make_tuple(true, account) );
253 if (pending_limits == nullptr) {
254 const auto& limits = _db.get<resource_limits_object, by_owner>( boost::make_tuple(false, account));
255 return _db.create<resource_limits_object>([&](resource_limits_object& pending_limits){
256 pending_limits.owner = limits.owner;
257 pending_limits.ram_bytes = limits.ram_bytes;
258 pending_limits.net_weight = limits.net_weight;
259 pending_limits.cpu_weight = limits.cpu_weight;
260 pending_limits.pending = true;
261 });
262 } else {
263 return *pending_limits;
264 }
265 };
266
267 // update the users weights directly
268 auto& limits = find_or_create_pending_limits();
269
270 bool decreased_limit = false;
271
272 if( ram_bytes >= 0 ) {
273
274 decreased_limit = ( (limits.ram_bytes < 0) || (ram_bytes < limits.ram_bytes) );
275
276 /*
277 if( limits.ram_bytes < 0 ) {
278 SYS_ASSERT(ram_bytes >= usage.ram_usage, wasm_execution_error, "converting unlimited account would result in overcommitment [commit=${c}, desired limit=${l}]", ("c", usage.ram_usage)("l", ram_bytes));
279 } else {
280 SYS_ASSERT(ram_bytes >= usage.ram_usage, wasm_execution_error, "attempting to release committed ram resources [commit=${c}, desired limit=${l}]", ("c", usage.ram_usage)("l", ram_bytes));
281 }
282 */
283 }
284
285 _db.modify( limits, [&]( resource_limits_object& pending_limits ){
286 pending_limits.ram_bytes = ram_bytes;
287 pending_limits.net_weight = net_weight;
288 pending_limits.cpu_weight = cpu_weight;
289
290 if (auto dm_logger = _get_deep_mind_logger()) {
291 dm_logger->on_set_account_limits(pending_limits);
292 }
293 });
294
295 return decreased_limit;
296}
297
298void resource_limits_manager::get_account_limits( const account_name& account, int64_t& ram_bytes, int64_t& net_weight, int64_t& cpu_weight ) const {
299 const auto* pending_buo = _db.find<resource_limits_object,by_owner>( boost::make_tuple(true, account) );
300 if (pending_buo) {
301 ram_bytes = pending_buo->ram_bytes;
302 net_weight = pending_buo->net_weight;
303 cpu_weight = pending_buo->cpu_weight;
304 } else {
305 const auto& buo = _db.get<resource_limits_object,by_owner>( boost::make_tuple( false, account ) );
306 ram_bytes = buo.ram_bytes;
307 net_weight = buo.net_weight;
308 cpu_weight = buo.cpu_weight;
309 }
310}
311
313 const auto* buo = _db.find<resource_limits_object,by_owner>( boost::make_tuple(false, account) );
314 if (buo) {
315 return buo->cpu_weight == -1;
316 }
317 return false;
318}
319
321 auto& multi_index = _db.get_mutable_index<resource_limits_index>();
322 auto& by_owner_index = multi_index.indices().get<by_owner>();
323
324 // convenience local lambda to reduce clutter
325 auto update_state_and_value = [](uint64_t &total, int64_t &value, int64_t pending_value, const char* debug_which) -> void {
326 if (value > 0) {
327 SYS_ASSERT(total >= static_cast<uint64_t>(value), rate_limiting_state_inconsistent, "underflow when reverting old value to ${which}", ("which", debug_which));
328 total -= value;
329 }
330
331 if (pending_value > 0) {
332 SYS_ASSERT(UINT64_MAX - total >= static_cast<uint64_t>(pending_value), rate_limiting_state_inconsistent, "overflow when applying new value to ${which}", ("which", debug_which));
333 total += pending_value;
334 }
335
336 value = pending_value;
337 };
338
339 const auto& state = _db.get<resource_limits_state_object>();
341 while(!by_owner_index.empty()) {
342 const auto& itr = by_owner_index.lower_bound(boost::make_tuple(true));
343 if (itr == by_owner_index.end() || itr->pending!= true) {
344 break;
345 }
346
347 const auto& actual_entry = _db.get<resource_limits_object, by_owner>(boost::make_tuple(false, itr->owner));
348 _db.modify(actual_entry, [&](resource_limits_object& rlo){
349 update_state_and_value(rso.total_ram_bytes, rlo.ram_bytes, itr->ram_bytes, "ram_bytes");
350 update_state_and_value(rso.total_cpu_weight, rlo.cpu_weight, itr->cpu_weight, "cpu_weight");
351 update_state_and_value(rso.total_net_weight, rlo.net_weight, itr->net_weight, "net_weight");
352 });
353
354 multi_index.remove(*itr);
355 }
356
357 if (auto dm_logger = _get_deep_mind_logger()) {
358 dm_logger->on_update_resource_limits_state(state);
359 }
360 });
361}
362
364 const auto& s = _db.get<resource_limits_state_object>();
365 const auto& config = _db.get<resource_limits_config_object>();
367 // apply pending usage, update virtual limits and reset the pending
368
369 state.average_block_cpu_usage.add(state.pending_cpu_usage, block_num, config.cpu_limit_parameters.periods);
370 state.update_virtual_cpu_limit(config);
371 state.pending_cpu_usage = 0;
372
373 state.average_block_net_usage.add(state.pending_net_usage, block_num, config.net_limit_parameters.periods);
374 state.update_virtual_net_limit(config);
375 state.pending_net_usage = 0;
376
377 if (auto dm_logger = _get_deep_mind_logger()) {
378 dm_logger->on_update_resource_limits_state(state);
379 }
380 });
381
382}
383
385 const auto& state = _db.get<resource_limits_state_object>();
386 return state.total_cpu_weight;
387}
388
390 const auto& state = _db.get<resource_limits_state_object>();
391 return state.total_net_weight;
392}
393
395 const auto& state = _db.get<resource_limits_state_object>();
396 return state.virtual_cpu_limit;
397}
398
400 const auto& state = _db.get<resource_limits_state_object>();
401 return state.virtual_net_limit;
402}
403
405 const auto& state = _db.get<resource_limits_state_object>();
406 const auto& config = _db.get<resource_limits_config_object>();
407 return config.cpu_limit_parameters.max - state.pending_cpu_usage;
408}
409
411 const auto& state = _db.get<resource_limits_state_object>();
412 const auto& config = _db.get<resource_limits_config_object>();
413 return config.net_limit_parameters.max - state.pending_net_usage;
414}
415
416std::pair<int64_t, bool> resource_limits_manager::get_account_cpu_limit( const account_name& name, uint32_t greylist_limit ) const {
417 auto [arl, greylisted] = get_account_cpu_limit_ex(name, greylist_limit);
418 return {arl.available, greylisted};
419}
420
421std::pair<account_resource_limit, bool> resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, uint32_t greylist_limit ) const {
422
423 const auto& state = _db.get<resource_limits_state_object>();
424 const auto& usage = _db.get<resource_usage_object, by_owner>(name);
425 const auto& config = _db.get<resource_limits_config_object>();
426
427 int64_t cpu_weight, x, y;
428 get_account_limits( name, x, y, cpu_weight );
429
430 if( cpu_weight < 0 || state.total_cpu_weight == 0 ) {
431 return {{ -1, -1, -1 }, false};
432 }
433
435
436 uint128_t window_size = config.account_cpu_usage_average_window;
437
438 bool greylisted = false;
439 uint128_t virtual_cpu_capacity_in_window = window_size;
440 if( greylist_limit < config::maximum_elastic_resource_multiplier ) {
441 uint64_t greylisted_virtual_cpu_limit = config.cpu_limit_parameters.max * greylist_limit;
442 if( greylisted_virtual_cpu_limit < state.virtual_cpu_limit ) {
443 virtual_cpu_capacity_in_window *= greylisted_virtual_cpu_limit;
444 greylisted = true;
445 } else {
446 virtual_cpu_capacity_in_window *= state.virtual_cpu_limit;
447 }
448 } else {
449 virtual_cpu_capacity_in_window *= state.virtual_cpu_limit;
450 }
451
452 uint128_t user_weight = (uint128_t)cpu_weight;
453 uint128_t all_user_weight = (uint128_t)state.total_cpu_weight;
454
455 auto max_user_use_in_window = (virtual_cpu_capacity_in_window * user_weight) / all_user_weight;
456 auto cpu_used_in_window = impl::integer_divide_ceil((uint128_t)usage.cpu_usage.value_ex * window_size, (uint128_t)config::rate_limiting_precision);
457
458 if( max_user_use_in_window <= cpu_used_in_window )
459 arl.available = 0;
460 else
461 arl.available = impl::downgrade_cast<int64_t>(max_user_use_in_window - cpu_used_in_window);
462
463 arl.used = impl::downgrade_cast<int64_t>(cpu_used_in_window);
464 arl.max = impl::downgrade_cast<int64_t>(max_user_use_in_window);
465 return {arl, greylisted};
466}
467
468std::pair<int64_t, bool> resource_limits_manager::get_account_net_limit( const account_name& name, uint32_t greylist_limit ) const {
469 auto [arl, greylisted] = get_account_net_limit_ex(name, greylist_limit);
470 return {arl.available, greylisted};
471}
472
473std::pair<account_resource_limit, bool> resource_limits_manager::get_account_net_limit_ex( const account_name& name, uint32_t greylist_limit ) const {
474 const auto& config = _db.get<resource_limits_config_object>();
475 const auto& state = _db.get<resource_limits_state_object>();
476 const auto& usage = _db.get<resource_usage_object, by_owner>(name);
477
478 int64_t net_weight, x, y;
479 get_account_limits( name, x, net_weight, y );
480
481 if( net_weight < 0 || state.total_net_weight == 0) {
482 return {{ -1, -1, -1 }, false};
483 }
484
486
487 uint128_t window_size = config.account_net_usage_average_window;
488
489 bool greylisted = false;
490 uint128_t virtual_network_capacity_in_window = window_size;
491 if( greylist_limit < config::maximum_elastic_resource_multiplier ) {
492 uint64_t greylisted_virtual_net_limit = config.net_limit_parameters.max * greylist_limit;
493 if( greylisted_virtual_net_limit < state.virtual_net_limit ) {
494 virtual_network_capacity_in_window *= greylisted_virtual_net_limit;
495 greylisted = true;
496 } else {
497 virtual_network_capacity_in_window *= state.virtual_net_limit;
498 }
499 } else {
500 virtual_network_capacity_in_window *= state.virtual_net_limit;
501 }
502
503 uint128_t user_weight = (uint128_t)net_weight;
504 uint128_t all_user_weight = (uint128_t)state.total_net_weight;
505
506 auto max_user_use_in_window = (virtual_network_capacity_in_window * user_weight) / all_user_weight;
507 auto net_used_in_window = impl::integer_divide_ceil((uint128_t)usage.net_usage.value_ex * window_size, (uint128_t)config::rate_limiting_precision);
508
509 if( max_user_use_in_window <= net_used_in_window )
510 arl.available = 0;
511 else
512 arl.available = impl::downgrade_cast<int64_t>(max_user_use_in_window - net_used_in_window);
513
514 arl.used = impl::downgrade_cast<int64_t>(net_used_in_window);
515 arl.max = impl::downgrade_cast<int64_t>(max_user_use_in_window);
516 return {arl, greylisted};
517}
518
519} } }
std::string name
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
void modify(const ObjectType &obj, Modifier &&m)
const ObjectType * find(CompatibleKey &&key) const
const ObjectType & create(Constructor &&con)
generic_index< MultiIndexType > & get_mutable_index()
const ObjectType & get(CompatibleKey &&key) const
bool is_unlimited_cpu(const account_name &account) const
void get_account_limits(const account_name &account, int64_t &ram_bytes, int64_t &net_weight, int64_t &cpu_weight) const
std::pair< account_resource_limit, bool > get_account_cpu_limit_ex(const account_name &name, uint32_t greylist_limit=config::maximum_elastic_resource_multiplier) const
void read_from_snapshot(const snapshot_reader_ptr &snapshot)
bool set_account_limits(const account_name &account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight)
set_account_limits returns true if new ram_bytes limit is more restrictive than the previously set on...
void set_block_parameters(const elastic_limit_parameters &cpu_limit_parameters, const elastic_limit_parameters &net_limit_parameters)
std::pair< int64_t, bool > get_account_cpu_limit(const account_name &name, uint32_t greylist_limit=config::maximum_elastic_resource_multiplier) const
std::pair< int64_t, bool > get_account_net_limit(const account_name &name, uint32_t greylist_limit=config::maximum_elastic_resource_multiplier) const
void add_to_snapshot(const snapshot_writer_ptr &snapshot) const
void add_pending_ram_usage(const account_name account, int64_t ram_delta)
void update_account_usage(const flat_set< account_name > &accounts, uint32_t ordinal)
void add_transaction_usage(const flat_set< account_name > &accounts, uint64_t cpu_usage, uint64_t net_usage, uint32_t ordinal)
int64_t get_account_ram_usage(const account_name &name) const
void verify_account_ram_usage(const account_name accunt) const
std::pair< account_resource_limit, bool > get_account_net_limit_ex(const account_name &name, uint32_t greylist_limit=config::maximum_elastic_resource_multiplier) const
uint64_t y
Definition sha3.cpp:34
constexpr UnsignedIntType integer_divide_ceil(UnsignedIntType num, UnsignedIntType den)
constexpr auto downgrade_cast(GreaterIntType val) -> std::enable_if_t< is_valid_downgrade_cast< LesserIntType, GreaterIntType > &&std::is_signed< LesserIntType >::value==std::is_signed< GreaterIntType >::value, LesserIntType >
chainbase::shared_multi_index_container< resource_usage_object, indexed_by< ordered_unique< tag< by_id >, member< resource_usage_object, resource_usage_object::id_type, &resource_usage_object::id > >, ordered_unique< tag< by_owner >, member< resource_usage_object, account_name, &resource_usage_object::owner > > > > resource_usage_index
chainbase::shared_multi_index_container< resource_limits_object, indexed_by< ordered_unique< tag< by_id >, member< resource_limits_object, resource_limits_object::id_type, &resource_limits_object::id > >, ordered_unique< tag< by_owner >, composite_key< resource_limits_object, BOOST_MULTI_INDEX_MEMBER(resource_limits_object, bool, pending), > > > > resource_limits_index
chainbase::shared_multi_index_container< resource_limits_state_object, indexed_by< ordered_unique< tag< by_id >, member< resource_limits_state_object, resource_limits_state_object::id_type, &resource_limits_state_object::id > > > > resource_limits_state_index
chainbase::shared_multi_index_container< resource_limits_config_object, indexed_by< ordered_unique< tag< by_id >, member< resource_limits_config_object, resource_limits_config_object::id_type, &resource_limits_config_object::id > > > > resource_limits_config_index
key Invalid authority Invalid transaction Invalid block ID Invalid packed transaction Invalid chain ID Invalid symbol Signature type is not a currently activated type Block can not be found Unlinkable block Block does not guarantee concurrent execution without conflicts Block exhausted allowed resources Block is from the future Block is not signed by expected producer Block includes an ill formed protocol feature activation extension Block includes an ill formed additional block signature extension transaction_exception
std::shared_ptr< snapshot_writer > snapshot_writer_ptr
Definition snapshot.hpp:155
unsigned __int128 uint128_t
Definition types.hpp:242
std::shared_ptr< snapshot_reader > snapshot_reader_ptr
Definition snapshot.hpp:294
#define value
Definition pkcs11.h:157
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
#define UINT64_MAX
Definition stdint.h:189
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
Immutable except for fc::from_variant.
Definition name.hpp:43
int64_t used
quantity used in current window
int64_t max
max per window under current congestion
int64_t available
quantity available in current window (based upon fractional reserve)
char * s