Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
apply_context.hpp
Go to the documentation of this file.
1#pragma once
6#include <fc/utility.hpp>
7#include <sstream>
8#include <algorithm>
9#include <set>
10
11namespace chainbase { class database; }
12
13namespace sysio { namespace chain {
14
15class controller;
16class transaction_context;
17
19 private:
20 template<typename T>
21 class iterator_cache {
22 public:
23 iterator_cache(){
24 _end_iterator_to_table.reserve(8);
25 _iterator_to_object.reserve(32);
26 }
27
29 int cache_table( const table_id_object& tobj ) {
30 auto itr = _table_cache.find(tobj.id);
31 if( itr != _table_cache.end() )
32 return itr->second.second;
33
34 auto ei = index_to_end_iterator(_end_iterator_to_table.size());
35 _end_iterator_to_table.push_back( &tobj );
36 _table_cache.emplace( tobj.id, make_pair(&tobj, ei) );
37 return ei;
38 }
39
40 const table_id_object& get_table( table_id_object::id_type i )const {
41 auto itr = _table_cache.find(i);
42 SYS_ASSERT( itr != _table_cache.end(), table_not_in_cache, "an invariant was broken, table should be in cache" );
43 return *itr->second.first;
44 }
45
46 int get_end_iterator_by_table_id( table_id_object::id_type i )const {
47 auto itr = _table_cache.find(i);
48 SYS_ASSERT( itr != _table_cache.end(), table_not_in_cache, "an invariant was broken, table should be in cache" );
49 return itr->second.second;
50 }
51
52 const table_id_object* find_table_by_end_iterator( int ei )const {
53 SYS_ASSERT( ei < -1, invalid_table_iterator, "not an end iterator" );
54 auto indx = end_iterator_to_index(ei);
55 if( indx >= _end_iterator_to_table.size() ) return nullptr;
56 return _end_iterator_to_table[indx];
57 }
58
59 const T& get( int iterator ) {
60 SYS_ASSERT( iterator != -1, invalid_table_iterator, "invalid iterator" );
61 SYS_ASSERT( iterator >= 0, table_operation_not_permitted, "dereference of end iterator" );
62 SYS_ASSERT( (size_t)iterator < _iterator_to_object.size(), invalid_table_iterator, "iterator out of range" );
63 auto result = _iterator_to_object[iterator];
64 SYS_ASSERT( result, table_operation_not_permitted, "dereference of deleted object" );
65 return *result;
66 }
67
68 void remove( int iterator ) {
69 SYS_ASSERT( iterator != -1, invalid_table_iterator, "invalid iterator" );
70 SYS_ASSERT( iterator >= 0, table_operation_not_permitted, "cannot call remove on end iterators" );
71 SYS_ASSERT( (size_t)iterator < _iterator_to_object.size(), invalid_table_iterator, "iterator out of range" );
72
73 auto obj_ptr = _iterator_to_object[iterator];
74 if( !obj_ptr ) return;
75 _iterator_to_object[iterator] = nullptr;
76 _object_to_iterator.erase( obj_ptr );
77 }
78
79 int add( const T& obj ) {
80 auto itr = _object_to_iterator.find( &obj );
81 if( itr != _object_to_iterator.end() )
82 return itr->second;
83
84 _iterator_to_object.push_back( &obj );
85 _object_to_iterator[&obj] = _iterator_to_object.size() - 1;
86
87 return _iterator_to_object.size() - 1;
88 }
89
90 private:
91 map<table_id_object::id_type, pair<const table_id_object*, int>> _table_cache;
92 vector<const table_id_object*> _end_iterator_to_table;
93 vector<const T*> _iterator_to_object;
94 map<const T*,int> _object_to_iterator;
95
98 inline size_t end_iterator_to_index( int ei )const { return (-ei - 2); }
100 inline int index_to_end_iterator( size_t indx )const { return -(indx + 2); }
101 };
102
103 template<typename>
104 struct array_size;
105
106 template<typename T, size_t N>
107 struct array_size< std::array<T,N> > {
108 static constexpr size_t size = N;
109 };
110
111 template <typename SecondaryKey, typename SecondaryKeyProxy, typename SecondaryKeyProxyConst, typename Enable = void>
112 class secondary_key_helper;
113
114 template<typename SecondaryKey, typename SecondaryKeyProxy, typename SecondaryKeyProxyConst>
115 class secondary_key_helper<SecondaryKey, SecondaryKeyProxy, SecondaryKeyProxyConst,
116 typename std::enable_if<std::is_same<SecondaryKey, typename std::decay<SecondaryKeyProxy>::type>::value>::type >
117 {
118 public:
119 typedef SecondaryKey secondary_key_type;
120
121 static void set(secondary_key_type& sk_in_table, const secondary_key_type& sk_from_wasm) {
122 sk_in_table = sk_from_wasm;
123 }
124
125 static void get(secondary_key_type& sk_from_wasm, const secondary_key_type& sk_in_table ) {
126 sk_from_wasm = sk_in_table;
127 }
128
129 static auto create_tuple(const table_id_object& tab, const secondary_key_type& secondary) {
130 return boost::make_tuple( tab.id, secondary );
131 }
132 };
133
134 template<typename SecondaryKey, typename SecondaryKeyProxy, typename SecondaryKeyProxyConst>
135 class secondary_key_helper<SecondaryKey, SecondaryKeyProxy, SecondaryKeyProxyConst,
136 typename std::enable_if<!std::is_same<SecondaryKey, typename std::decay<SecondaryKeyProxy>::type>::value &&
137 std::is_pointer<typename std::decay<SecondaryKeyProxy>::type>::value>::type >
138 {
139 public:
140 typedef SecondaryKey secondary_key_type;
141 typedef SecondaryKeyProxy secondary_key_proxy_type;
142 typedef SecondaryKeyProxyConst secondary_key_proxy_const_type;
143
144 static constexpr size_t N = array_size<SecondaryKey>::size;
145
146 static void set(secondary_key_type& sk_in_table, secondary_key_proxy_const_type sk_from_wasm) {
147 std::copy(sk_from_wasm, sk_from_wasm + N, sk_in_table.begin());
148 }
149
150 static void get(secondary_key_proxy_type sk_from_wasm, const secondary_key_type& sk_in_table) {
151 std::copy(sk_in_table.begin(), sk_in_table.end(), sk_from_wasm);
152 }
153
154 static auto create_tuple(const table_id_object& tab, secondary_key_proxy_const_type sk_from_wasm) {
155 secondary_key_type secondary;
156 std::copy(sk_from_wasm, sk_from_wasm + N, secondary.begin());
157 return boost::make_tuple( tab.id, secondary );
158 }
159 };
160
161 public:
162 template<typename ObjectType,
163 typename SecondaryKeyProxy = typename std::add_lvalue_reference<typename ObjectType::secondary_key_type>::type,
164 typename SecondaryKeyProxyConst = typename std::add_lvalue_reference<
165 typename std::add_const<typename ObjectType::secondary_key_type>::type>::type >
167 {
168 public:
169 typedef typename ObjectType::secondary_key_type secondary_key_type;
170 typedef SecondaryKeyProxy secondary_key_proxy_type;
171 typedef SecondaryKeyProxyConst secondary_key_proxy_const_type;
172
173 using secondary_key_helper_t = secondary_key_helper<secondary_key_type, secondary_key_proxy_type, secondary_key_proxy_const_type>;
174
176
177 int store( uint64_t scope, uint64_t table, const account_name& payer,
179 {
180 SYS_ASSERT( payer != account_name(), invalid_table_payer, "must specify a valid account to pay for new record" );
181
182// context.require_write_lock( scope );
183
184 const auto& tab = context.find_or_create_table( context.receiver, name(scope), name(table), payer );
185
186 const auto& obj = context.db.create<ObjectType>( [&]( auto& o ){
187 o.t_id = tab.id;
188 o.primary_key = id;
189 secondary_key_helper_t::set(o.secondary_key, value);
190 o.payer = payer;
191 });
192
193 context.db.modify( tab, [&]( auto& t ) {
194 ++t.count;
195
196 if (auto dm_logger = context.control.get_deep_mind_logger()) {
197 std::string event_id = RAM_EVENT_ID("${code}:${scope}:${table}:${index_name}",
198 ("code", t.code)
199 ("scope", t.scope)
200 ("table", t.table)
201 ("index_name", name(id))
202 );
203 dm_logger->on_ram_trace(std::move(event_id), "secondary_index", "add", "secondary_index_add");
204 }
205 });
206
207 context.update_db_usage( payer, config::billable_size_v<ObjectType> );
208
209 itr_cache.cache_table( tab );
210 return itr_cache.add( obj );
211 }
212
213 void remove( int iterator ) {
214 const auto& obj = itr_cache.get( iterator );
215
216 const auto& table_obj = itr_cache.get_table( obj.t_id );
217 SYS_ASSERT( table_obj.code == context.receiver, table_access_violation, "db access violation" );
218
219 if (auto dm_logger = context.control.get_deep_mind_logger()) {
220 std::string event_id = RAM_EVENT_ID("${code}:${scope}:${table}:${index_name}",
221 ("code", table_obj.code)
222 ("scope", table_obj.scope)
223 ("table", table_obj.table)
224 ("index_name", name(obj.primary_key))
225 );
226 dm_logger->on_ram_trace(std::move(event_id), "secondary_index", "remove", "secondary_index_remove");
227 }
228
229 context.update_db_usage( obj.payer, -( config::billable_size_v<ObjectType> ) );
230
231// context.require_write_lock( table_obj.scope );
232
233 context.db.modify( table_obj, [&]( auto& t ) {
234 --t.count;
235 });
236 context.db.remove( obj );
237
238 if (table_obj.count == 0) {
239 context.remove_table(table_obj);
240 }
241
242 itr_cache.remove( iterator );
243 }
244
245 void update( int iterator, account_name payer, secondary_key_proxy_const_type secondary ) {
246 const auto& obj = itr_cache.get( iterator );
247
248 const auto& table_obj = itr_cache.get_table( obj.t_id );
249 SYS_ASSERT( table_obj.code == context.receiver, table_access_violation, "db access violation" );
250
251// context.require_write_lock( table_obj.scope );
252
253 if( payer == account_name() ) payer = obj.payer;
254
256
257 std::string event_id;
258 if (context.control.get_deep_mind_logger() != nullptr) {
259 event_id = RAM_EVENT_ID("${code}:${scope}:${table}:${index_name}",
260 ("code", table_obj.code)
261 ("scope", table_obj.scope)
262 ("table", table_obj.table)
263 ("index_name", name(obj.primary_key))
264 );
265 }
266
267 if( obj.payer != payer ) {
268 if (auto dm_logger = context.control.get_deep_mind_logger())
269 {
270 dm_logger->on_ram_trace(std::string(event_id), "secondary_index", "remove", "secondary_index_remove");
271 }
272 context.update_db_usage( obj.payer, -(billing_size) );
273 if (auto dm_logger = context.control.get_deep_mind_logger())
274 {
275 dm_logger->on_ram_trace(std::move(event_id), "secondary_index", "add", "secondary_index_update_add_new_payer");
276 }
277 context.update_db_usage( payer, +(billing_size) );
278 }
279
280 context.db.modify( obj, [&]( auto& o ) {
281 secondary_key_helper_t::set(o.secondary_key, secondary);
282 o.payer = payer;
283 });
284 }
285
286 int find_secondary( uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_const_type secondary, uint64_t& primary ) {
287 auto tab = context.find_table( name(code), name(scope), name(table) );
288 if( !tab ) return -1;
289
290 auto table_end_itr = itr_cache.cache_table( *tab );
291
292 const auto* obj = context.db.find<ObjectType, by_secondary>( secondary_key_helper_t::create_tuple( *tab, secondary ) );
293 if( !obj ) return table_end_itr;
294
295 primary = obj->primary_key;
296
297 return itr_cache.add( *obj );
298 }
299
300 int lowerbound_secondary( uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_type secondary, uint64_t& primary ) {
301 auto tab = context.find_table( name(code), name(scope), name(table) );
302 if( !tab ) return -1;
303
304 auto table_end_itr = itr_cache.cache_table( *tab );
305
306 const auto& idx = context.db.get_index< typename chainbase::get_index_type<ObjectType>::type, by_secondary >();
307 auto itr = idx.lower_bound( secondary_key_helper_t::create_tuple( *tab, secondary ) );
308 if( itr == idx.end() ) return table_end_itr;
309 if( itr->t_id != tab->id ) return table_end_itr;
310
311 primary = itr->primary_key;
312 secondary_key_helper_t::get(secondary, itr->secondary_key);
313
314 return itr_cache.add( *itr );
315 }
316
317 int upperbound_secondary( uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_type secondary, uint64_t& primary ) {
318 auto tab = context.find_table( name(code), name(scope), name(table) );
319 if( !tab ) return -1;
320
321 auto table_end_itr = itr_cache.cache_table( *tab );
322
323 const auto& idx = context.db.get_index< typename chainbase::get_index_type<ObjectType>::type, by_secondary >();
324 auto itr = idx.upper_bound( secondary_key_helper_t::create_tuple( *tab, secondary ) );
325 if( itr == idx.end() ) return table_end_itr;
326 if( itr->t_id != tab->id ) return table_end_itr;
327
328 primary = itr->primary_key;
329 secondary_key_helper_t::get(secondary, itr->secondary_key);
330
331 return itr_cache.add( *itr );
332 }
333
334 int end_secondary( uint64_t code, uint64_t scope, uint64_t table ) {
335 auto tab = context.find_table( name(code), name(scope), name(table) );
336 if( !tab ) return -1;
337
338 return itr_cache.cache_table( *tab );
339 }
340
341 int next_secondary( int iterator, uint64_t& primary ) {
342 if( iterator < -1 ) return -1; // cannot increment past end iterator of index
343
344 const auto& obj = itr_cache.get(iterator); // Check for iterator != -1 happens in this call
345 const auto& idx = context.db.get_index<typename chainbase::get_index_type<ObjectType>::type, by_secondary>();
346
347 auto itr = idx.iterator_to(obj);
348 ++itr;
349
350 if( itr == idx.end() || itr->t_id != obj.t_id ) return itr_cache.get_end_iterator_by_table_id(obj.t_id);
351
352 primary = itr->primary_key;
353 return itr_cache.add(*itr);
354 }
355
356 int previous_secondary( int iterator, uint64_t& primary ) {
357 const auto& idx = context.db.get_index<typename chainbase::get_index_type<ObjectType>::type, by_secondary>();
358
359 if( iterator < -1 ) // is end iterator
360 {
361 auto tab = itr_cache.find_table_by_end_iterator(iterator);
362 SYS_ASSERT( tab, invalid_table_iterator, "not a valid end iterator" );
363
364 auto itr = idx.upper_bound(tab->id);
365 if( idx.begin() == idx.end() || itr == idx.begin() ) return -1; // Empty index
366
367 --itr;
368
369 if( itr->t_id != tab->id ) return -1; // Empty index
370
371 primary = itr->primary_key;
372 return itr_cache.add(*itr);
373 }
374
375 const auto& obj = itr_cache.get(iterator); // Check for iterator != -1 happens in this call
376
377 auto itr = idx.iterator_to(obj);
378 if( itr == idx.begin() ) return -1; // cannot decrement past beginning iterator of index
379
380 --itr;
381
382 if( itr->t_id != obj.t_id ) return -1; // cannot decrement past beginning iterator of index
383
384 primary = itr->primary_key;
385 return itr_cache.add(*itr);
386 }
387
388 int find_primary( uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_type secondary, uint64_t primary ) {
389 auto tab = context.find_table( name(code), name(scope), name(table) );
390 if( !tab ) return -1;
391
392 auto table_end_itr = itr_cache.cache_table( *tab );
393
394 const auto* obj = context.db.find<ObjectType, by_primary>( boost::make_tuple( tab->id, primary ) );
395 if( !obj ) return table_end_itr;
396 secondary_key_helper_t::get(secondary, obj->secondary_key);
397
398 return itr_cache.add( *obj );
399 }
400
401 int lowerbound_primary( uint64_t code, uint64_t scope, uint64_t table, uint64_t primary ) {
402 auto tab = context.find_table( name(code), name(scope), name(table) );
403 if (!tab) return -1;
404
405 auto table_end_itr = itr_cache.cache_table( *tab );
406
407 const auto& idx = context.db.get_index<typename chainbase::get_index_type<ObjectType>::type, by_primary>();
408 auto itr = idx.lower_bound(boost::make_tuple(tab->id, primary));
409 if (itr == idx.end()) return table_end_itr;
410 if (itr->t_id != tab->id) return table_end_itr;
411
412 return itr_cache.add(*itr);
413 }
414
415 int upperbound_primary( uint64_t code, uint64_t scope, uint64_t table, uint64_t primary ) {
416 auto tab = context.find_table( name(code), name(scope), name(table) );
417 if ( !tab ) return -1;
418
419 auto table_end_itr = itr_cache.cache_table( *tab );
420
421 const auto& idx = context.db.get_index<typename chainbase::get_index_type<ObjectType>::type, by_primary>();
422 auto itr = idx.upper_bound(boost::make_tuple(tab->id, primary));
423 if (itr == idx.end()) return table_end_itr;
424 if (itr->t_id != tab->id) return table_end_itr;
425
426 itr_cache.cache_table(*tab);
427 return itr_cache.add(*itr);
428 }
429
430 int next_primary( int iterator, uint64_t& primary ) {
431 if( iterator < -1 ) return -1; // cannot increment past end iterator of table
432
433 const auto& obj = itr_cache.get(iterator); // Check for iterator != -1 happens in this call
434 const auto& idx = context.db.get_index<typename chainbase::get_index_type<ObjectType>::type, by_primary>();
435
436 auto itr = idx.iterator_to(obj);
437 ++itr;
438
439 if( itr == idx.end() || itr->t_id != obj.t_id ) return itr_cache.get_end_iterator_by_table_id(obj.t_id);
440
441 primary = itr->primary_key;
442 return itr_cache.add(*itr);
443 }
444
445 int previous_primary( int iterator, uint64_t& primary ) {
446 const auto& idx = context.db.get_index<typename chainbase::get_index_type<ObjectType>::type, by_primary>();
447
448 if( iterator < -1 ) // is end iterator
449 {
450 auto tab = itr_cache.find_table_by_end_iterator(iterator);
451 SYS_ASSERT( tab, invalid_table_iterator, "not a valid end iterator" );
452
453 auto itr = idx.upper_bound(tab->id);
454 if( idx.begin() == idx.end() || itr == idx.begin() ) return -1; // Empty table
455
456 --itr;
457
458 if( itr->t_id != tab->id ) return -1; // Empty table
459
460 primary = itr->primary_key;
461 return itr_cache.add(*itr);
462 }
463
464 const auto& obj = itr_cache.get(iterator); // Check for iterator != -1 happens in this call
465
466 auto itr = idx.iterator_to(obj);
467 if( itr == idx.begin() ) return -1; // cannot decrement past beginning iterator of table
468
469 --itr;
470
471 if( itr->t_id != obj.t_id ) return -1; // cannot decrement past beginning iterator of index
472
473 primary = itr->primary_key;
474 return itr_cache.add(*itr);
475 }
476
477 void get( int iterator, uint64_t& primary, secondary_key_proxy_type secondary ) {
478 const auto& obj = itr_cache.get( iterator );
479 primary = obj.primary_key;
480 secondary_key_helper_t::get(secondary, obj.secondary_key);
481 }
482
483 private:
485 iterator_cache<ObjectType> itr_cache;
486 };
487
488
490 public:
491 apply_context(controller& con, transaction_context& trx_ctx, uint32_t action_ordinal, uint32_t depth=0);
492
494 public:
495
496 void exec_one();
497 void exec();
498 void execute_inline( action&& a );
500 void schedule_deferred_transaction( const uint128_t& sender_id, account_name payer, transaction&& trx, bool replace_existing );
501 bool cancel_deferred_transaction( const uint128_t& sender_id, account_name sender );
502 bool cancel_deferred_transaction( const uint128_t& sender_id ) { return cancel_deferred_transaction(sender_id, receiver); }
503
504 protected:
505 uint32_t schedule_action( uint32_t ordinal_of_action_to_schedule, account_name receiver, bool context_free );
506 uint32_t schedule_action( action&& act_to_schedule, account_name receiver, bool context_free );
507
508
510 public:
511
521 void require_authorization(const account_name& account);
522 bool has_authorization(const account_name& account) const;
523 void require_authorization(const account_name& account, const permission_name& permission);
524
528 bool is_account(const account_name& account)const;
529
530 void get_code_hash(
531 account_name account, uint64_t& code_sequence, fc::sha256& code_hash, uint8_t& vm_type, uint8_t& vm_version) const;
532
536 void require_recipient(account_name account);
537
542 bool has_recipient(account_name account)const;
543
545 public:
546
547 void console_append( std::string_view val ) {
548 _pending_console_output += val;
549 }
550
552 public:
553
554 void update_db_usage( const account_name& payer, int64_t delta );
555
556 int db_store_i64( name scope, name table, const account_name& payer, uint64_t id, const char* buffer, size_t buffer_size );
557 void db_update_i64( int iterator, account_name payer, const char* buffer, size_t buffer_size );
558 void db_remove_i64( int iterator );
559 int db_get_i64( int iterator, char* buffer, size_t buffer_size );
560 int db_next_i64( int iterator, uint64_t& primary );
561 int db_previous_i64( int iterator, uint64_t& primary );
562 int db_find_i64( name code, name scope, name table, uint64_t id );
563 int db_lowerbound_i64( name code, name scope, name table, uint64_t id );
564 int db_upperbound_i64( name code, name scope, name table, uint64_t id );
565 int db_end_i64( name code, name scope, name table );
566
567 private:
568
569 const table_id_object* find_table( name code, name scope, name table );
570 const table_id_object& find_or_create_table( name code, name scope, name table, const account_name &payer );
571 void remove_table( const table_id_object& tid );
572
573 int db_store_i64( name code, name scope, name table, const account_name& payer, uint64_t id, const char* buffer, size_t buffer_size );
574
575
577 public:
578
579
580 int get_action( uint32_t type, uint32_t index, char* buffer, size_t buffer_size )const;
581 int get_context_free_data( uint32_t index, char* buffer, size_t buffer_size )const;
583
585 uint64_t next_recv_sequence( const account_metadata_object& receiver_account );
587
588 void add_ram_usage( account_name account, int64_t ram_delta );
589 void finalize_trace( action_trace& trace, const fc::time_point& start );
590
591 bool is_context_free()const { return context_free; }
592 bool is_privileged()const { return privileged; }
593 action_name get_receiver()const { return receiver; }
594 const action& get_action()const { return *act; }
595
596 action_name get_sender() const;
597
599 public:
600
604
605 private:
606 const action* act = nullptr;
607 // act pointer may be invalidated on call to trx_context.schedule_action
608 account_name receiver;
609 uint32_t recurse_depth;
610 uint32_t first_receiver_action_ordinal = 0;
611 uint32_t action_ordinal = 0;
612 bool privileged = false;
613 bool context_free = false;
614
615 public:
616 std::vector<char> action_return_value;
622
623 private:
624
625 iterator_cache<key_value_object> keyval_cache;
627 vector<uint32_t> _inline_actions;
628 vector<uint32_t> _cfa_inline_actions;
629 std::string _pending_console_output;
630 flat_set<account_delta> _account_ram_deltas;
631
632 //bytes _cached_trx;
633};
634
635using apply_handler = std::function<void(apply_context&)>;
636
637} } // namespace sysio::chain
638
639//FC_REFLECT(sysio::chain::apply_context::apply_results, (applied_actions)(deferred_transaction_requests)(deferred_transactions_count))
std::string name
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
void get(int iterator, uint64_t &primary, secondary_key_proxy_type secondary)
void update(int iterator, account_name payer, secondary_key_proxy_const_type secondary)
ObjectType::secondary_key_type secondary_key_type
int upperbound_secondary(uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_type secondary, uint64_t &primary)
secondary_key_helper< secondary_key_type, secondary_key_proxy_type, secondary_key_proxy_const_type > secondary_key_helper_t
int lowerbound_primary(uint64_t code, uint64_t scope, uint64_t table, uint64_t primary)
int end_secondary(uint64_t code, uint64_t scope, uint64_t table)
int lowerbound_secondary(uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_type secondary, uint64_t &primary)
int previous_primary(int iterator, uint64_t &primary)
int find_primary(uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_type secondary, uint64_t primary)
int upperbound_primary(uint64_t code, uint64_t scope, uint64_t table, uint64_t primary)
int find_secondary(uint64_t code, uint64_t scope, uint64_t table, secondary_key_proxy_const_type secondary, uint64_t &primary)
SecondaryKeyProxyConst secondary_key_proxy_const_type
int previous_secondary(int iterator, uint64_t &primary)
int next_primary(int iterator, uint64_t &primary)
int store(uint64_t scope, uint64_t table, const account_name &payer, uint64_t id, secondary_key_proxy_const_type value)
int next_secondary(int iterator, uint64_t &primary)
void require_recipient(account_name account)
bool cancel_deferred_transaction(const uint128_t &sender_id)
uint32_t schedule_action(uint32_t ordinal_of_action_to_schedule, account_name receiver, bool context_free)
void add_ram_usage(account_name account, int64_t ram_delta)
std::vector< char > action_return_value
vector< account_name > get_active_producers() const
bool cancel_deferred_transaction(const uint128_t &sender_id, account_name sender)
int db_lowerbound_i64(name code, name scope, name table, uint64_t id)
const action & get_action() const
generic_index< index_long_double_object > idx_long_double
void exec_one()
Execution methods:
void update_db_usage(const account_name &payer, int64_t delta)
Database methods:
int db_find_i64(name code, name scope, name table, uint64_t id)
int get_context_free_data(uint32_t index, char *buffer, size_t buffer_size) const
int db_store_i64(name scope, name table, const account_name &payer, uint64_t id, const char *buffer, size_t buffer_size)
generic_index< index_double_object > idx_double
int db_get_i64(int iterator, char *buffer, size_t buffer_size)
controller & control
Fields:
int db_upperbound_i64(name code, name scope, name table, uint64_t id)
int db_next_i64(int iterator, uint64_t &primary)
void require_authorization(const account_name &account)
Authorization methods:
apply_context(controller &con, transaction_context &trx_ctx, uint32_t action_ordinal, uint32_t depth=0)
class generic_index
bool has_authorization(const account_name &account) const
void finalize_trace(action_trace &trace, const fc::time_point &start)
generic_index< index128_object > idx128
bool is_account(const account_name &account) const
exec()
transaction_context & trx_context
transaction context in which the action is running
uint64_t next_auth_sequence(account_name actor)
void db_update_i64(int iterator, account_name payer, const char *buffer, size_t buffer_size)
action_name get_sender() const
int db_previous_i64(int iterator, uint64_t &primary)
void db_remove_i64(int iterator)
void schedule_deferred_transaction(const uint128_t &sender_id, account_name payer, transaction &&trx, bool replace_existing)
chainbase::database & db
database where state is stored
uint64_t next_recv_sequence(const account_metadata_object &receiver_account)
action_name get_receiver() const
int db_end_i64(name code, name scope, name table)
bool has_recipient(account_name account) const
void console_append(std::string_view val)
Console methods:
void execute_context_free_inline(action &&a)
generic_index< index256_object, uint128_t *, const uint128_t * > idx256
generic_index< index64_object > idx64
The table_id_object class tracks the mapping of (scope, code, table) to an opaque identifier.
uint64_t id
Definition code_cache.cpp:0
#define RAM_EVENT_ID(FORMAT,...)
Definition deep_mind.hpp:27
Definition name.hpp:106
constexpr uint64_t billable_size_v
Definition config.hpp:147
sysio::chain::action_name action_name
unsigned __int128 uint128_t
Definition types.hpp:242
std::function< void(apply_context &)> apply_handler
name account_name
Definition types.hpp:120
#define value
Definition pkcs11.h:157
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
#define T(meth, val, expected)
const int N
Definition quantize.cpp:54
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
unsigned char uint8_t
Definition stdint.h:124
unsigned __int64 uint64_t
Definition stdint.h:136
Immutable except for fc::from_variant.
Definition name.hpp:43
bool set