24namespace sysio {
namespace chain {
30 return (
unsigned __int128)_id;
37 "account '${account}' does not exist",
38 (
"account",
a.permission.actor)
41 if(
a.permission.permission == config::owner_name ||
a.permission.permission == config::active_name )
44 if(
a.permission.permission == config::sysio_code_name )
48 context.control.get_authorization_manager().get_permission({
a.permission.actor,
a.permission.permission});
49 }
catch(
const permission_query_exception& ) {
51 "permission '${perm}' does not exist",
52 (
"perm",
a.permission)
57 if(
context.trx_context.enforce_whiteblacklist &&
context.control.is_producing_block() ) {
58 for(
const auto&
p : auth.
keys ) {
59 context.control.check_key_list(
p.key );
70 context.require_authorization(create.creator);
72 auto& authorization =
context.control.get_mutable_authorization_manager();
79 auto name_str =
name(create.name).to_string();
86 if( !creator.is_privileged() ) {
88 "only privileged accounts can have names that start with 'sysio.'" );
91 auto existing_account = db.find<
account_object, by_name>(create.name);
92 SYS_ASSERT(existing_account ==
nullptr, account_name_exists_exception,
93 "Cannot create account named ${name}, as that name is already taken",
94 (
"name", create.name));
98 a.creation_date =
context.control.pending_block_time();
102 a.name = create.name;
105 for(
const auto& auth : { create.owner, create.active } ){
109 const auto& owner_permission = authorization.create_permission( create.name, config::owner_name, 0,
110 std::move(create.owner) );
111 const auto& active_permission = authorization.create_permission( create.name, config::active_name, owner_permission.id,
112 std::move(create.active) );
114 context.control.get_mutable_resource_limits_manager().initialize_account(create.name);
116 int64_t ram_delta = config::overhead_per_account_ram_bytes;
118 ram_delta += owner_permission.auth.get_billable_size();
119 ram_delta += active_permission.auth.get_billable_size();
121 if (
auto dm_logger =
context.control.get_deep_mind_logger()) {
122 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${name}", (
"name", create.name)),
"account",
"add",
"newaccount");
125 context.add_ram_usage(create.name, ram_delta);
132 context.require_authorization(act.account);
134 SYS_ASSERT( act.vmtype == 0, invalid_contract_vm_type,
"code should be 0" );
135 SYS_ASSERT( act.vmversion == 0, invalid_contract_vm_version,
"version should be 0" );
141 if( code_size > 0 ) {
147 bool existing_code = (account.code_hash !=
digest_type());
149 SYS_ASSERT( code_size > 0 || existing_code, set_exact_code,
"contract is already cleared" );
152 int64_t new_size = code_size * config::setcode_ram_bytes_multiplier;
154 if( existing_code ) {
155 const code_object& old_code_entry = db.get<
code_object, by_code_hash>(boost::make_tuple(account.code_hash, account.vm_type, account.vm_version));
156 SYS_ASSERT( old_code_entry.code_hash != code_hash, set_exact_code,
157 "contract is already running this version of code" );
158 old_size = (
int64_t)old_code_entry.code.
size() * config::setcode_ram_bytes_multiplier;
159 if( old_code_entry.code_ref_count == 1 ) {
160 db.remove(old_code_entry);
161 context.control.get_wasm_interface().code_block_num_last_used(account.code_hash, account.vm_type, account.vm_version,
context.control.head_block_num() + 1);
169 if( code_size > 0 ) {
171 boost::make_tuple(code_hash, act.vmtype, act.vmversion) );
172 if( new_code_entry ) {
178 o.code_hash = code_hash;
179 o.code.assign(act.code.data(), code_size);
180 o.code_ref_count = 1;
181 o.first_block_used =
context.control.head_block_num() + 1;
182 o.vm_type = act.vmtype;
183 o.vm_version = act.vmversion;
188 db.modify( account, [&](
auto&
a ) {
189 a.code_sequence += 1;
190 a.code_hash = code_hash;
191 a.vm_type = act.vmtype;
192 a.vm_version = act.vmversion;
193 a.last_code_update =
context.control.pending_block_time();
196 if (new_size != old_size) {
197 if (
auto dm_logger =
context.control.get_deep_mind_logger()) {
198 const char* operation =
"update";
201 }
else if (new_size <= 0) {
202 operation =
"remove";
205 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${account}", (
"account", act.account)),
"code", operation,
"setcode");
208 context.add_ram_usage( act.account, new_size - old_size );
216 context.require_authorization(act.account);
218 const auto& account = db.get<
account_object,by_name>(act.account);
225 db.modify( account, [&](
auto&
a ) {
226 a.abi.assign(act.abi.data(), abi_size);
230 db.modify( account_metadata, [&](
auto&
a ) {
234 if (new_size != old_size) {
235 if (
auto dm_logger =
context.control.get_deep_mind_logger()) {
236 const char* operation =
"update";
239 }
else if (new_size <= 0) {
240 operation =
"remove";
243 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${account}", (
"account", act.account)),
"abi", operation,
"setabi");
246 context.add_ram_usage( act.account, new_size - old_size );
255 if( update.permission !=
name(
"auth.ext") && update.permission !=
name(
"auth.session") ) {
256 context.require_authorization(update.account);
259 auto& authorization =
context.control.get_mutable_authorization_manager();
264 "Permission names that start with 'sysio.' are reserved" );
268 "Invalid authority: ${auth}", (
"auth", update.auth));
269 if( update.permission == config::active_name )
271 if (update.permission == config::owner_name)
276 if( update.auth.waits.size() > 0 ) {
277 auto max_delay =
context.control.get_global_properties().configuration.max_transaction_delay;
279 "Cannot set delay longer than max_transacton_delay, which is ${max_delay} seconds",
280 (
"max_delay", max_delay) );
287 auto permission = authorization.find_permission({update.account, update.permission});
292 if( update.permission != config::owner_name ) {
293 auto& parent = authorization.get_permission({update.account, update.parent});
294 parent_id = parent.id;
299 "Changing parent authority is not currently supported");
304 authorization.modify_permission( *permission, update.auth );
308 if (
auto dm_logger =
context.control.get_deep_mind_logger()) {
309 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id", permission->id)),
"auth",
"update",
"updateauth_update");
312 context.add_ram_usage( permission->owner, new_size - old_size );
314 const auto&
p = authorization.create_permission( update.account, update.permission, parent_id, update.auth );
318 if (
auto dm_logger =
context.control.get_deep_mind_logger()) {
319 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id",
p.id)),
"auth",
"add",
"updateauth_create");
322 context.add_ram_usage( update.account, new_size );
335 auto& authorization =
context.control.get_mutable_authorization_manager();
342 auto range = index.equal_range(boost::make_tuple(
remove.account,
remove.permission));
344 "Cannot delete a linked authority. Unlink the authority first. This authority is linked to ${code}::${type}.",
345 (
"code", range.first->code)(
"type", range.first->message_type));
348 const auto& permission = authorization.get_permission({
remove.account,
remove.permission});
351 if (
auto dm_logger =
context.control.get_deep_mind_logger()) {
352 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id", permission.id)),
"auth",
"remove",
"deleteauth");
355 authorization.remove_permission( permission );
368 context.require_authorization(requirement.account);
371 const auto *account = db.find<
account_object, by_name>(requirement.account);
372 SYS_ASSERT(account !=
nullptr, account_query_exception,
373 "Failed to retrieve account: ${account}", (
"account", requirement.account));
374 const auto *code = db.find<
account_object, by_name>(requirement.code);
375 SYS_ASSERT(code !=
nullptr, account_query_exception,
376 "Failed to retrieve code for account: ${account}", (
"account", requirement.code));
377 if( requirement.requirement != config::sysio_any_name ) {
381 boost::make_tuple( requirement.account, requirement.requirement )
387 SYS_ASSERT(permission !=
nullptr, permission_query_exception,
388 "Failed to retrieve permission: ${permission}", (
"permission", requirement.requirement));
391 auto link_key = boost::make_tuple(requirement.account, requirement.code, requirement.type);
396 "Attempting to update required authority, but new requirement is same as old");
398 link.required_permission = requirement;
402 link.account = requirement.account;
403 link.code = requirement.code;
404 link.message_type = requirement.type;
405 link.required_permission = requirement.requirement;
408 if (
auto dm_logger =
context.control.get_deep_mind_logger()) {
409 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id",
l.id)),
"auth_link",
"add",
"linkauth");
427 context.require_authorization(unlink.account);
429 auto link_key = boost::make_tuple(unlink.account, unlink.code, unlink.type);
433 if (
auto dm_logger =
context.control.get_deep_mind_logger()) {
434 dm_logger->on_ram_trace(
RAM_EVENT_ID(
"${id}", (
"id", link->id)),
"auth_link",
"remove",
"unlinkauth");
447 context.require_authorization(cancel.canceling_auth.actor);
449 const auto& trx_id = cancel.trx_id;
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
static sha256 hash(const char *d, uint32_t dlen)
an implementation of 128 bit unsigned integer
The permission_link_object class assigns permission_objects to message types.
static void validate(const controller &control, const bytes &code)
#define RAM_EVENT_ID(FORMAT,...)
#define FC_CAPTURE_AND_RETHROW(...)
void apply_sysio_unlinkauth(apply_context &)
void apply_sysio_canceldelay(apply_context &)
void apply_sysio_deleteauth(apply_context &)
void apply_sysio_setcode(apply_context &)
void apply_sysio_updateauth(apply_context &)
void apply_sysio_setabi(apply_context &)
void apply_sysio_linkauth(apply_context &)
void apply_sysio_newaccount(apply_context &)
bool remove(const path &p)
constexpr uint64_t billable_size_v
chainbase::shared_multi_index_container< permission_link_object, indexed_by< ordered_unique< tag< by_id >, >, ordered_unique< tag< by_action_name >, composite_key< permission_link_object, BOOST_MULTI_INDEX_MEMBER(permission_link_object, account_name, account), BOOST_MULTI_INDEX_MEMBER(permission_link_object, account_name, code), > >, ordered_unique< tag< by_permission_name >, composite_key< permission_link_object, BOOST_MULTI_INDEX_MEMBER(permission_link_object, account_name, account), BOOST_MULTI_INDEX_MEMBER(permission_link_object, permission_name, required_permission), > > > > permission_link_index
checksum_type digest_type
@ only_link_to_existing_permission
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
unsigned __int128 uint128_t
void validate_authority_precondition(const apply_context &context, const authority &auth)
bool validate(const Authority &auth)
uint128_t transaction_id_to_sender_id(const transaction_id_type &tid)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
vector< permission_level_weight > accounts
vector< key_weight > keys
Immutable except for fc::from_variant.