14#include <boost/container/flat_set.hpp>
16using boost::container::flat_set;
18namespace sysio {
namespace chain {
20static inline void print_debug(
account_name receiver,
const action_trace& ar) {
21 if (!ar.console.empty()) {
23 "\n[(${a},${n})->${r}]",
28 dlog(prefix +
": CONSOLE OUTPUT BEGIN =====================\n"
30 + prefix +
": CONSOLE OUTPUT END =====================" );
39,first_receiver_action_ordinal(action_ordinal)
40,action_ordinal(action_ordinal)
45,idx_long_double(*this)
47 action_trace& trace = trx_ctx.get_action_trace(action_ordinal);
61 auto handle_exception = [&](
const auto& e)
74 privileged = receiver_account->is_privileged();
84 if( ( receiver_account->code_hash !=
digest_type() ) &&
85 ( !( act->
account == config::system_account_name
86 && act->
name ==
"setcode"_n
87 && receiver == config::system_account_name )
101 const size_t checktime_interval = 10;
103 bool not_in_notify_context = (receiver == act->
account);
104 const auto end = _account_ram_deltas.end();
105 for(
auto itr = _account_ram_deltas.begin(); itr != end; ++itr, ++counter ) {
106 if( counter == checktime_interval ) {
110 if( itr->delta > 0 && itr->account != receiver ) {
111 SYS_ASSERT( not_in_notify_context, unauthorized_ram_usage_increase,
112 "unprivileged contract cannot increase RAM usage of another account within a notify context: ${account}",
113 (
"account", itr->account)
116 "unprivileged contract cannot increase RAM usage of another account that has not authorized the action: ${account}",
117 (
"account", itr->account)
122 }
FC_RETHROW_EXCEPTIONS( warn,
"pending console output: ${console}", (
"console", _pending_console_output) )
135 }
catch (
const std::bad_alloc& ) {
137 }
catch (
const boost::interprocess::bad_alloc& ) {
141 }
catch (
const std::exception& e ) {
143 handle_exception(wrapper);
156 r.receiver = receiver;
157 r.act_digest = act_digest;
162 if( act->
account == receiver ) {
163 first_receiver_account = receiver_account;
168 r.code_sequence = first_receiver_account->code_sequence;
169 r.abi_sequence = first_receiver_account->abi_sequence;
180 print_debug(receiver, trace);
185 dm_logger->on_end_action();
192 _account_ram_deltas.clear();
194 trace.
console = std::move( _pending_console_output );
195 _pending_console_output.clear();
202 _notified.emplace_back( receiver, action_ordinal );
204 for(
uint32_t i = 1; i < _notified.size(); ++i ) {
205 std::tie( receiver, action_ordinal ) = _notified[i];
209 if( _cfa_inline_actions.size() > 0 || _inline_actions.size() > 0 ) {
214 for(
uint32_t ordinal : _cfa_inline_actions ) {
215 trx_context.execute_action( ordinal, recurse_depth + 1 );
218 for(
uint32_t ordinal : _inline_actions ) {
219 trx_context.execute_action( ordinal, recurse_depth + 1 );
234 code_sequence = obj->code_sequence;
241 code_sequence = obj->code_sequence;
242 code_hash = obj->code_hash;
244 vm_version = obj->vm_version;
254 SYS_ASSERT(
false, missing_auth_exception,
"missing authority of ${account}", (
"account",account));
259 if( auth.actor == account )
272 SYS_ASSERT(
false, missing_auth_exception,
"missing authority of ${account}/${permission}",
273 (
"account",account)(
"permission",permission) );
277 for(
const auto&
p : _notified )
278 if(
p.first == code )
285 _notified.emplace_back(
291 dm_logger->on_require_recipient();
315 "inline action's code account ${account} does not exist", (
"account",
a.account) );
318 flat_set<account_name> actors;
321 bool send_to_self = (
a.account == receiver);
324 flat_set<permission_level> inherited_authorizations;
325 if( inherit_parent_authorizations ) {
326 inherited_authorizations.reserve(
a.authorization.size() );
329 for(
const auto& auth :
a.authorization ) {
332 "inline action's authorizing actor ${account} does not exist", (
"account", auth.actor) );
334 "inline action's authorizations include a non-existent permission: ${permission}",
335 (
"permission", auth) );
336 if( enforce_actor_whitelist_blacklist )
337 actors.insert( auth.actor );
340 inherited_authorizations.insert( auth );
344 if( enforce_actor_whitelist_blacklist ) {
351 inline_action_too_big_nonprivileged,
352 "inline action too big for nonprivileged account ${account}", (
"account",
a.account));
360 {{receiver, config::sysio_code_name}},
365 inherited_authorizations
372 if( disallow_send_to_self_bypass || !send_to_self ) {
375 subjective_block_production_exception new_exception(
FC_LOG_MESSAGE( error,
"Authorization failure with inline action sent to self"));
376 for (
const auto& log: e.
get_log()) {
377 new_exception.append_log(log);
382 if( disallow_send_to_self_bypass || !send_to_self ) {
385 SYS_THROW(subjective_block_production_exception,
"Unexpected exception occurred validating inline action sent to self");
390 auto inline_receiver =
a.account;
391 _inline_actions.emplace_back(
396 dm_logger->on_send_inline();
403 "inline action's code account ${account} does not exist", (
"account",
a.account) );
406 "context-free actions cannot have authorizations" );
411 inline_action_too_big_nonprivileged,
412 "inline action too big for nonprivileged account ${account}", (
"account",
a.account));
415 auto inline_receiver =
a.account;
416 _cfa_inline_actions.emplace_back(
421 dm_logger->on_send_context_free_inline();
427 SYS_ASSERT( trx.context_free_actions.size() == 0, cfa_inside_generated_tx,
"context free actions are not currently allowed in generated transactions" );
434 auto exts = trx.validate_and_extract_extensions();
435 if( exts.size() > 0 ) {
438 SYS_ASSERT( exts.size() == 1 && itr != exts.end(), invalid_transaction_extension,
439 "only the deferred_transaction_generation_context extension is currently supported for deferred transactions"
442 const auto&
context = std::get<deferred_transaction_generation_context>(itr->second);
444 SYS_ASSERT(
context.sender == receiver, ill_formed_deferred_transaction_generation_context,
445 "deferred transaction generaction context contains mismatching sender",
446 (
"expected", receiver)(
"actual",
context.sender)
448 SYS_ASSERT(
context.sender_id == sender_id, ill_formed_deferred_transaction_generation_context,
449 "deferred transaction generaction context contains mismatching sender_id",
450 (
"expected", sender_id)(
"actual",
context.sender_id)
453 "deferred transaction generaction context contains mismatching sender_trx_id",
458 trx.transaction_extensions,
464 trx.ref_block_num = 0;
465 trx.ref_block_prefix = 0;
475 +
static_cast<uint64_t>(config::transaction_id_net_usage) );
482 if( payer != receiver ) {
483 if( ram_restrictions_activated ) {
485 "cannot bill RAM usage of deferred transactions to another account within notify context"
488 "cannot bill RAM usage of deferred transaction to another account that has not authorized the action: ${payer}",
509 bool send_to_self =
true;
510 for(
const auto& act : trx.actions ) {
512 send_to_self =
false;
523 {{receiver, config::sysio_code_name}},
529 if( disallow_send_to_self_bypass || !is_sending_only_to_self(receiver) ) {
532 subjective_block_production_exception new_exception(
FC_LOG_MESSAGE( error,
"Authorization failure with sent deferred transaction consisting only of actions to self"));
533 for (
const auto& log: e.
get_log()) {
534 new_exception.append_log(log);
539 if( disallow_send_to_self_bypass || !is_sending_only_to_self(receiver) ) {
542 SYS_THROW(subjective_block_production_exception,
"Unexpected exception occurred validating sent deferred transaction consisting only of actions to self");
549 SYS_ASSERT( replace_existing, deferred_tx_duplicate,
"deferred transaction with the same sender_id and payer already exists" );
553 SYS_ASSERT( replace_deferred_activated || !control.is_producing_block()
554 || control.all_subjective_mitigations_disabled(),
555 subjective_block_production_exception,
556 "Replacing a deferred transaction is temporarily disabled." );
558 if (
auto dm_logger = control.get_deep_mind_logger()) {
559 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id", ptr->id)),
"deferred_trx",
"cancel",
"deferred_trx_cancel");
563 if( replace_deferred_activated ) {
564 add_ram_usage( ptr->payer, -
static_cast<int64_t>( orig_trx_ram_bytes ) );
566 control.add_to_ram_correction( ptr->payer, orig_trx_ram_bytes );
570 if( replace_deferred_activated ) {
571 trx_id_for_new_obj = trx.id();
573 trx_id_for_new_obj = ptr->trx_id;
576 if (
auto dm_logger = control.get_deep_mind_logger()) {
582 db.create<generated_transaction_object>( [&](
auto& gtx ) {
583 gtx.trx_id = trx_id_for_new_obj;
584 gtx.sender = receiver;
585 gtx.sender_id = sender_id;
587 gtx.published = control.pending_block_time();
588 gtx.delay_until = gtx.published +
delay;
589 gtx.expiration = gtx.delay_until +
fc::seconds(control.get_global_properties().configuration.deferred_trx_expiration_window);
591 trx_size = gtx.set( trx );
593 if (
auto dm_logger = control.get_deep_mind_logger()) {
595 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id", gtx.id)),
"deferred_trx",
"update",
"deferred_trx_add");
599 db.create<generated_transaction_object>( [&](
auto& gtx ) {
600 gtx.trx_id = trx.id();
601 gtx.sender = receiver;
602 gtx.sender_id = sender_id;
604 gtx.published = control.pending_block_time();
605 gtx.delay_until = gtx.published +
delay;
606 gtx.expiration = gtx.delay_until +
fc::seconds(control.get_global_properties().configuration.deferred_trx_expiration_window);
608 trx_size = gtx.set( trx );
610 if (
auto dm_logger = control.get_deep_mind_logger()) {
612 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id", gtx.id)),
"deferred_trx",
"add",
"deferred_trx_add");
618 || control.is_ram_billing_in_notify_allowed()
619 || (receiver == act->account) || (receiver == payer) || privileged,
620 subjective_block_production_exception,
621 "Cannot charge RAM to other accounts during notify."
632 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id", gto->id)),
"deferred_trx",
"cancel",
"deferred_trx_cancel");
636 generated_transaction_idx.remove(*gto);
643 uint32_t scheduled_action_ordinal =
trx_context.schedule_action( ordinal_of_action_to_schedule,
644 receiver, context_free,
645 action_ordinal, first_receiver_action_ordinal );
648 return scheduled_action_ordinal;
653 uint32_t scheduled_action_ordinal =
trx_context.schedule_action( std::move(act_to_schedule),
654 receiver, context_free,
655 action_ordinal, first_receiver_action_ordinal );
658 return scheduled_action_ordinal;
666 const auto* existing_tid =
db.
find<
table_id_object, by_code_scope_table>(boost::make_tuple(code, scope, table));
667 if (existing_tid !=
nullptr) {
668 return *existing_tid;
672 std::string event_id =
RAM_EVENT_ID(
"${code}:${scope}:${table}",
677 dm_logger->on_ram_trace(std::move(event_id),
"table",
"add",
"create_table");
682 return db.
create<table_id_object>([&](table_id_object &t_id){
689 dm_logger->on_create_table(t_id);
694void apply_context::remove_table(
const table_id_object& tid ) {
696 std::string event_id =
RAM_EVENT_ID(
"${code}:${scope}:${table}",
701 dm_logger->on_ram_trace(std::move(event_id),
"table",
"remove",
"remove_table");
707 dm_logger->on_remove_table(tid);
717 for(
const auto& producer : ap.producers )
718 accounts.push_back(producer.producer_name);
729 subjective_block_production_exception,
"Cannot charge RAM to other accounts during notify." );
740 const action* act_ptr =
nullptr;
743 if( index >= trx.context_free_actions.size() )
745 act_ptr = &trx.context_free_actions[index];
747 else if( type == 1 ) {
748 if( index >= trx.actions.size() )
750 act_ptr = &trx.actions[index];
753 SYS_ASSERT(act_ptr, action_not_found_exception,
"action is not found" );
756 if( ps <= buffer_size ) {
767 if( index >= trx.context_free_data.size() )
return -1;
770 if( buffer_size == 0 )
return s;
772 auto copy_size = std::min( buffer_size,
s );
773 memcpy( buffer, trx.context_free_data[index].data(), copy_size );
779 return db_store_i64( receiver, scope, table, payer,
id, buffer, buffer_size);
784 const auto& tab = find_or_create_table( code, scope, table, payer );
785 auto tableid = tab.id;
787 SYS_ASSERT( payer !=
account_name(), invalid_table_payer,
"must specify a valid account to pay for new record" );
792 o.value.assign( buffer, buffer_size );
803 std::string event_id =
RAM_EVENT_ID(
"${table_code}:${scope}:${table_name}:${primkey}",
804 (
"table_code", tab.code)
806 (
"table_name", tab.table)
807 (
"primkey",
name(obj.primary_key))
809 dm_logger->on_ram_trace(std::move(event_id),
"table_row",
"add",
"primary_index_add");
815 dm_logger->on_db_store_i64(tab, obj);
818 keyval_cache.cache_table( tab );
819 return keyval_cache.add( obj );
825 const auto& table_obj = keyval_cache.get_table( obj.
t_id );
826 SYS_ASSERT( table_obj.code == receiver, table_access_violation,
"db access violation" );
836 std::string event_id;
838 event_id =
RAM_EVENT_ID(
"${table_code}:${scope}:${table_name}:${primkey}",
839 (
"table_code", table_obj.code)
840 (
"scope", table_obj.scope)
841 (
"table_name", table_obj.table)
850 dm_logger->on_ram_trace(std::string(event_id),
"table_row",
"remove",
"primary_index_update_remove_old_payer");
856 dm_logger->on_ram_trace(std::move(event_id),
"table_row",
"add",
"primary_index_update_add_new_payer");
859 }
else if(old_size != new_size) {
863 dm_logger->on_ram_trace(std::move(event_id) ,
"table_row",
"update",
"primary_index_update");
869 dm_logger->on_db_update_i64(table_obj, obj, payer, buffer, buffer_size);
873 o.value.assign( buffer, buffer_size );
881 const auto& table_obj = keyval_cache.get_table( obj.
t_id );
882 SYS_ASSERT( table_obj.code == receiver, table_access_violation,
"db access violation" );
887 std::string event_id =
RAM_EVENT_ID(
"${table_code}:${scope}:${table_name}:${primkey}",
888 (
"table_code", table_obj.code)
889 (
"scope", table_obj.scope)
890 (
"table_name", table_obj.table)
893 dm_logger->on_ram_trace(std::move(event_id),
"table_row",
"remove",
"primary_index_remove");
899 dm_logger->on_db_remove_i64(table_obj, obj);
902 db.
modify( table_obj, [&](
auto& t ) {
907 if (table_obj.count == 0) {
908 remove_table(table_obj);
911 keyval_cache.remove( iterator );
918 if( buffer_size == 0 )
return s;
920 auto copy_size = std::min( buffer_size,
s );
927 if( iterator < -1 )
return -1;
929 const auto& obj = keyval_cache.get( iterator );
932 auto itr = idx.iterator_to( obj );
935 if( itr == idx.end() || itr->t_id != obj.t_id )
return keyval_cache.get_end_iterator_by_table_id(obj.t_id);
937 primary = itr->primary_key;
938 return keyval_cache.add( *itr );
946 auto tab = keyval_cache.find_table_by_end_iterator(iterator);
947 SYS_ASSERT( tab, invalid_table_iterator,
"not a valid end iterator" );
949 auto itr = idx.upper_bound(tab->id);
950 if( idx.begin() == idx.end() || itr == idx.begin() )
return -1;
954 if( itr->t_id != tab->id )
return -1;
956 primary = itr->primary_key;
957 return keyval_cache.add(*itr);
960 const auto& obj = keyval_cache.get(iterator);
962 auto itr = idx.iterator_to(obj);
963 if( itr == idx.begin() )
return -1;
967 if( itr->t_id != obj.t_id )
return -1;
969 primary = itr->primary_key;
970 return keyval_cache.add(*itr);
976 const auto* tab = find_table( code, scope, table );
977 if( !tab )
return -1;
979 auto table_end_itr = keyval_cache.cache_table( *tab );
982 if( !obj )
return table_end_itr;
984 return keyval_cache.add( *obj );
990 const auto* tab = find_table( code, scope, table );
991 if( !tab )
return -1;
993 auto table_end_itr = keyval_cache.cache_table( *tab );
996 auto itr = idx.lower_bound( boost::make_tuple( tab->id,
id ) );
997 if( itr == idx.end() )
return table_end_itr;
998 if( itr->t_id != tab->id )
return table_end_itr;
1000 return keyval_cache.add( *itr );
1006 const auto* tab = find_table( code, scope, table );
1007 if( !tab )
return -1;
1009 auto table_end_itr = keyval_cache.cache_table( *tab );
1012 auto itr = idx.upper_bound( boost::make_tuple( tab->id,
id ) );
1013 if( itr == idx.end() )
return table_end_itr;
1014 if( itr->t_id != tab->id )
return table_end_itr;
1016 return keyval_cache.add( *itr );
1022 const auto* tab = find_table( code, scope, table );
1023 if( !tab )
return -1;
1025 return keyval_cache.cache_table( *tab );
1031 ++dgp.global_action_sequence;
1033 return p.global_action_sequence;
1037 db.
modify( receiver_account, [&](
auto& ra ) {
1040 return receiver_account.recv_sequence;
1047 return amo.auth_sequence;
1053 auto p = _account_ram_deltas.emplace( account, ram_delta );
1055 p.first->delta += ram_delta;
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
const generic_index< MultiIndexType > & get_index() const
void modify(const ObjectType &obj, Modifier &&m)
const ObjectType * find(CompatibleKey &&key) const
void remove(const ObjectType &obj)
const ObjectType & create(Constructor &&con)
generic_index< MultiIndexType > & get_mutable_index()
const ObjectType & get(CompatibleKey &&key) const
const char * data() const
Used to generate a useful error report when an exception is thrown.
const log_messages & get_log() const
An order-preserving dictionary of variants.
static sha256 hash(const char *d, uint32_t dlen)
static std_exception_wrapper from_current_exception(const std::exception &e)
void require_recipient(account_name account)
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
uint64_t next_global_sequence()
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)
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)
void execute_inline(action &&a)
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)
int db_end_i64(name code, name scope, name table)
bool has_recipient(account_name account) const
void get_code_hash(account_name account, uint64_t &code_sequence, fc::sha256 &code_hash, uint8_t &vm_type, uint8_t &vm_version) const
void execute_context_free_inline(action &&a)
void check_authorization(const vector< action > &actions, const flat_set< public_key_type > &provided_keys, const flat_set< permission_level > &provided_permissions=flat_set< permission_level >(), fc::microseconds provided_delay=fc::microseconds(0), const std::function< void()> &checktime=std::function< void()>(), bool allow_unused_keys=false, bool check_but_dont_fail=false, const flat_set< permission_level > &satisfied_authorizations=flat_set< permission_level >()) const
Check authorizations of a vector of actions with provided keys, permission levels,...
const permission_object * find_permission(const permission_level &level) const
void check_action_list(account_name code, action_name action) const
const global_property_object & get_global_properties() const
const chainbase::database & db() const
bool is_producing_block() const
const dynamic_global_property_object & get_dynamic_global_properties() const
block_id_type head_block_id() const
bool skip_auth_check() const
const apply_handler * find_apply_handler(account_name contract, scope_name scope, action_name act) const
bool is_ram_billing_in_notify_allowed() const
deep_mind_handler * get_deep_mind_logger() const
uint32_t get_max_nonprivileged_inline_action_size() const
wasm_interface & get_wasm_interface()
const authorization_manager & get_authorization_manager() const
void check_actor_list(const flat_set< account_name > &actors) const
bool is_builtin_activated(builtin_protocol_feature_t f) const
bool sender_avoids_whitelist_blacklist_enforcement(account_name sender) const
time_point pending_block_time() const
const producer_authority_schedule & active_producers() const
static std::optional< uint64_t > convert_exception_to_error_code(const fc::exception &e)
bool contracts_console() const
void check_contract_list(account_name code) const
chain_config configuration
The table_id_object class tracks the mapping of (scope, code, table) to an opaque identifier.
const packed_transaction & packed_trx
void add_net_usage(uint64_t u)
bool enforce_whiteblacklist
void validate_referenced_accounts(const transaction &trx, bool enforce_actor_whitelist_blacklist) const
record_transaction
vector< digest_type > executed_action_receipt_digests
DigestType hash_with_checktime(const char *data, uint32_t datalen) const
void apply(const digest_type &code_hash, const uint8_t &vm_type, const uint8_t &vm_version, apply_context &context)
#define RAM_EVENT_ID(FORMAT,...)
#define FC_RETHROW_EXCEPTIONS(LOG_LEVEL, FORMAT,...)
Catchs all exception's, std::exceptions, and ... and rethrows them after appending the provided log m...
void delay(websocketpp::connection_hdl, long duration)
#define FC_LOG_MESSAGE(LOG_LEVEL, FORMAT,...)
A helper method for generating log messages.
void pack(Stream &s, const std::deque< T > &value)
size_t pack_size(const T &v)
constexpr microseconds seconds(int64_t s)
fc::string format_string(const fc::string &, const variant_object &, bool minimize=false)
constexpr uint64_t billable_size_v
@ no_duplicate_deferred_id
@ restrict_action_to_self
auto emplace_extension(extensions_type &exts, uint16_t eid, vector< char > &&data)
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
auto generate_action_digest(Hasher &&hash, const action &act, const vector< char > &action_output)
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 Error decompressing transaction Transaction should have at least one required authority Expired Transaction Invalid Reference Block Duplicate deferred transaction The transaction can not be found Transaction is too big Invalid transaction extension Transaction includes disallowed Transaction exceeded transient resource limit action_validate_exception
sysio::chain::action_name action_name
unsigned __int128 uint128_t
chainbase::shared_multi_index_container< generated_transaction_object, indexed_by< ordered_unique< tag< by_id >, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, generated_transaction_object::id_type, id)>, ordered_unique< tag< by_trx_id >, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, transaction_id_type, trx_id)>, ordered_unique< tag< by_expiration >, composite_key< generated_transaction_object, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, time_point, expiration), > >, ordered_unique< tag< by_delay >, composite_key< generated_transaction_object, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, time_point, delay_until), > >, ordered_unique< tag< by_sender_id >, composite_key< generated_transaction_object, BOOST_MULTI_INDEX_MEMBER(generated_transaction_object, account_name, sender), > > > > generated_transaction_multi_index
checksum_type transaction_id_type
chainbase::shared_multi_index_container< key_value_object, indexed_by< ordered_unique< tag< by_id >, member< key_value_object, key_value_object::id_type, &key_value_object::id > >, ordered_unique< tag< by_scope_primary >, composite_key< key_value_object, member< key_value_object, table_id, &key_value_object::t_id >, member< key_value_object, uint64_t, &key_value_object::primary_key > >, composite_key_compare< std::less< table_id >, std::less< uint64_t > > > > > key_value_index
@ self
the connection is to itself
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
unsigned __int64 uint64_t
vector< permission_level > authorization
fc::unsigned_int creator_action_ordinal
std::optional< fc::exception > except
flat_set< account_delta > account_ram_deltas
std::vector< char > return_value
std::optional< action_receipt > receipt
std::optional< uint64_t > error_code
uint16_t max_inline_action_depth
recursion depth limit on sending inline actions
uint32_t max_inline_action_size
maximum allowed size (in bytes) of an inline action
v1 Producer-voted blockchain configuration parameters
static constexpr uint16_t extension_id()
Immutable except for fc::from_variant.
const signed_transaction & get_signed_transaction() const
const transaction_id_type & id() const
const transaction & get_transaction() const
vector< bytes > context_free_data
for each context-free action, there is an entry here
memcpy((char *) pInfo->slotDescription, s, l)