Struct near_vm_logic::VMLogic

source ·
pub struct VMLogic<'a> { /* private fields */ }

Implementations§

source§

impl<'a> VMLogic<'a>

source

pub fn new_with_protocol_version( ext: &'a mut dyn External, context: VMContext, config: &'a VMConfig, fees_config: &'a RuntimeFeesConfig, promise_results: &'a [PromiseResult], memory: &'a mut dyn MemoryLike, current_protocol_version: ProtocolVersion ) -> Self

source

pub fn logs(&self) -> &[String]

Returns reference to logs that have been created so far.

source

pub fn action_receipts(&self) -> &[(AccountId, ReceiptMetadata)]

Returns receipt metadata for created receipts

source

pub fn read_register( &mut self, register_id: u64, ptr: u64 ) -> Result<(), VMLogicError>

Writes the entire content from the register register_id into the memory of the guest starting with ptr.

Arguments
  • register_id – a register id from where to read the data;
  • ptr – location on guest memory where to copy the data.
Errors
  • If the content extends outside the memory allocated to the guest. In Wasmer, it returns MemoryAccessViolation error message;
  • If register_id is pointing to unused register returns InvalidRegisterId error message.
Undefined Behavior

If the content of register extends outside the preallocated memory on the host side, or the pointer points to a wrong location this function will overwrite memory that it is not supposed to overwrite causing an undefined behavior.

Cost

base + read_register_base + read_register_byte * num_bytes + write_memory_base + write_memory_byte * num_bytes

source

pub fn register_len(&mut self, register_id: u64) -> Result<u64, VMLogicError>

Returns the size of the blob stored in the given register.

  • If register is used, then returns the size, which can potentially be zero;
  • If register is not used, returns u64::MAX
Arguments
  • register_id – a register id from where to read the data;
Cost

base

source

pub fn write_register( &mut self, register_id: u64, data_len: u64, data_ptr: u64 ) -> Result<(), VMLogicError>

Copies data from the guest memory into the register. If register is unused will initialize it. If register has larger capacity than needed for data will not re-allocate it. The register will lose the pre-existing data if any.

Arguments
  • register_id – a register id where to write the data;
  • data_len – length of the data in bytes;
  • data_ptr – pointer in the guest memory where to read the data from.
Cost

base + read_memory_base + read_memory_bytes * num_bytes + write_register_base + write_register_bytes * num_bytes

source

pub fn current_account_id( &mut self, register_id: u64 ) -> Result<(), VMLogicError>

Saves the account id of the current contract that we execute into the register.

Errors

If the registers exceed the memory limit returns MemoryAccessViolation.

Cost

base + write_register_base + write_register_byte * num_bytes

source

pub fn signer_account_id(&mut self, register_id: u64) -> Result<(), VMLogicError>

All contract calls are a result of some transaction that was signed by some account using some access key and submitted into a memory pool (either through the wallet using RPC or by a node itself). This function returns the id of that account. Saves the bytes of the signer account id into the register.

Errors
  • If the registers exceed the memory limit returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

base + write_register_base + write_register_byte * num_bytes

source

pub fn signer_account_pk(&mut self, register_id: u64) -> Result<(), VMLogicError>

Saves the public key fo the access key that was used by the signer into the register. In rare situations smart contract might want to know the exact access key that was used to send the original transaction, e.g. to increase the allowance or manipulate with the public key.

Errors
  • If the registers exceed the memory limit returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

base + write_register_base + write_register_byte * num_bytes

source

pub fn predecessor_account_id( &mut self, register_id: u64 ) -> Result<(), VMLogicError>

All contract calls are a result of a receipt, this receipt might be created by a transaction that does function invocation on the contract or another contract as a result of cross-contract call. Saves the bytes of the predecessor account id into the register.

Errors
  • If the registers exceed the memory limit returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

base + write_register_base + write_register_byte * num_bytes

source

pub fn input(&mut self, register_id: u64) -> Result<(), VMLogicError>

Reads input to the contract call into the register. Input is expected to be in JSON-format. If input is provided saves the bytes (potentially zero) of input into register. If input is not provided writes 0 bytes into the register.

Cost

base + write_register_base + write_register_byte * num_bytes

source

pub fn block_index(&mut self) -> Result<u64, VMLogicError>

Returns the current block height.

It’s only due to historical reasons, this host function is called block_index rather than block_height.

Cost

base

source

pub fn block_timestamp(&mut self) -> Result<u64, VMLogicError>

Returns the current block timestamp (number of non-leap-nanoseconds since January 1, 1970 0:00:00 UTC).

Cost

base

source

pub fn epoch_height(&mut self) -> Result<EpochHeight, VMLogicError>

Returns the current epoch height.

Cost

base

source

pub fn validator_stake( &mut self, account_id_len: u64, account_id_ptr: u64, stake_ptr: u64 ) -> Result<(), VMLogicError>

Get the stake of an account, if the account is currently a validator. Otherwise returns 0. writes the value into the u128 variable pointed by stake_ptr.

Cost

base + memory_write_base + memory_write_size * 16 + utf8_decoding_base + utf8_decoding_byte * account_id_len + validator_stake_base.

source

pub fn validator_total_stake( &mut self, stake_ptr: u64 ) -> Result<(), VMLogicError>

Get the total validator stake of the current epoch. Write the u128 value into stake_ptr. writes the value into the u128 variable pointed by stake_ptr.

Cost

base + memory_write_base + memory_write_size * 16 + validator_total_stake_base

source

pub fn storage_usage(&mut self) -> Result<StorageUsage, VMLogicError>

Returns the number of bytes used by the contract if it was saved to the trie as of the invocation. This includes:

  • The data written with storage_* functions during current and previous execution;
  • The bytes needed to store the access keys of the given account.
  • The contract code size
  • A small fixed overhead for account metadata.
Cost

base

source

pub fn account_balance(&mut self, balance_ptr: u64) -> Result<(), VMLogicError>

The current balance of the given account. This includes the attached_deposit that was attached to the transaction.

Cost

base + memory_write_base + memory_write_size * 16

source

pub fn account_locked_balance( &mut self, balance_ptr: u64 ) -> Result<(), VMLogicError>

The current amount of tokens locked due to staking.

Cost

base + memory_write_base + memory_write_size * 16

source

pub fn attached_deposit(&mut self, balance_ptr: u64) -> Result<(), VMLogicError>

The balance that was attached to the call that will be immediately deposited before the contract execution starts.

Errors

If called as view function returns `ProhibitedInView``.

Cost

base + memory_write_base + memory_write_size * 16

source

pub fn prepaid_gas(&mut self) -> Result<Gas, VMLogicError>

The amount of gas attached to the call that can be used to pay for the gas fees.

Errors

If called as view function returns ProhibitedInView.

Cost

base

source

pub fn used_gas(&mut self) -> Result<Gas, VMLogicError>

The gas that was already burnt during the contract execution (cannot exceed prepaid_gas)

Errors

If called as view function returns ProhibitedInView.

Cost

base

source

pub fn alt_bn128_g1_multiexp( &mut self, value_len: u64, value_ptr: u64, register_id: u64 ) -> Result<(), VMLogicError>

Computes multiexp on alt_bn128 curve using Pippenger’s algorithm \sum_i mul_i g_{1 i} should be equal result.

Arguments
  • value - sequence of (g1:G1, fr:Fr), where G1 is point (x:Fq, y:Fq) on alt_bn128, alt_bn128 is Y^2 = X^3 + 3 curve over Fq.

    value is encoded as packed, little-endian [((u256, u256), u256)] slice.

Errors

If value_len + value_ptr points outside the memory or the registers use more memory than the limit, the function returns MemoryAccessViolation.

If point coordinates are not on curve, point is not in the subgroup, scalar is not in the field or value.len()%96!=0, the function returns AltBn128InvalidInput.

Cost

base + write_register_base + write_register_byte * num_bytes + alt_bn128_g1_multiexp_base + alt_bn128_g1_multiexp_element * num_elements

source

pub fn alt_bn128_g1_sum( &mut self, value_len: u64, value_ptr: u64, register_id: u64 ) -> Result<(), VMLogicError>

Computes sum for signed g1 group elements on alt_bn128 curve \sum_i (-1)^{sign_i} g_{1 i} should be equal result.

Arguments
  • value - sequence of (sign:bool, g1:G1), where G1 is point (x:Fq, y:Fq) on alt_bn128, alt_bn128 is Y^2 = X^3 + 3 curve over Fq.

    value is encoded as packed, little-endian [(u8, (u256, u256))] slice. 0u8 is postive sign, 1u8 – negative.

Errors

If value_len + value_ptr points outside the memory or the registers use more memory than the limit, the function returns MemoryAccessViolation.

If point coordinates are not on curve, point is not in the subgroup, scalar is not in the field, sign is not 0 or 1, or value.len()%65!=0, the function returns AltBn128InvalidInput.

Cost

base + write_register_base + write_register_byte * num_bytes + alt_bn128_g1_sum_base + alt_bn128_g1_sum_element * num_elements

source

pub fn alt_bn128_pairing_check( &mut self, value_len: u64, value_ptr: u64 ) -> Result<u64, VMLogicError>

Computes pairing check on alt_bn128 curve. \sum_i e(g_{1 i}, g_{2 i}) should be equal one (in additive notation), e(g1, g2) is Ate pairing

Arguments
  • value - sequence of (g1:G1, g2:G2), where G2 is Fr-ordered subgroup point (x:Fq2, y:Fq2) on alt_bn128 twist, alt_bn128 twist is Y^2 = X^3 + 3/(i+9) curve over Fq2 Fq2 is complex field element (re: Fq, im: Fq) G1 is point (x:Fq, y:Fq) on alt_bn128, alt_bn128 is Y^2 = X^3 + 3 curve over Fq

    value is encoded a as packed, little-endian [((u256, u256), ((u256, u256), (u256, u256)))] slice.

Errors

If value_len + value_ptr points outside the memory or the registers use more memory than the function returns MemoryAccessViolation.

If point coordinates are not on curve, point is not in the subgroup, scalar is not in the field or data are wrong serialized, for example, value.len()%192!=0, the function returns AltBn128InvalidInput.

Cost

base + write_register_base + write_register_byte * num_bytes + alt_bn128_pairing_base + alt_bn128_pairing_element * num_elements

source

pub fn random_seed(&mut self, register_id: u64) -> Result<(), VMLogicError>

Writes random seed into the register.

Errors

If the size of the registers exceed the set limit MemoryAccessViolation.

Cost

base + write_register_base + write_register_byte * num_bytes.

source

pub fn sha256( &mut self, value_len: u64, value_ptr: u64, register_id: u64 ) -> Result<(), VMLogicError>

Hashes the given value using sha256 and returns it into register_id.

Errors

If value_len + value_ptr points outside the memory or the registers use more memory than the limit with MemoryAccessViolation.

Cost

base + write_register_base + write_register_byte * num_bytes + sha256_base + sha256_byte * num_bytes

source

pub fn keccak256( &mut self, value_len: u64, value_ptr: u64, register_id: u64 ) -> Result<(), VMLogicError>

Hashes the given value using keccak256 and returns it into register_id.

Errors

If value_len + value_ptr points outside the memory or the registers use more memory than the limit with MemoryAccessViolation.

Cost

base + write_register_base + write_register_byte * num_bytes + keccak256_base + keccak256_byte * num_bytes

source

pub fn keccak512( &mut self, value_len: u64, value_ptr: u64, register_id: u64 ) -> Result<(), VMLogicError>

Hashes the given value using keccak512 and returns it into register_id.

Errors

If value_len + value_ptr points outside the memory or the registers use more memory than the limit with MemoryAccessViolation.

Cost

base + write_register_base + write_register_byte * num_bytes + keccak512_base + keccak512_byte * num_bytes

source

pub fn ripemd160( &mut self, value_len: u64, value_ptr: u64, register_id: u64 ) -> Result<(), VMLogicError>

Hashes the given value using RIPEMD-160 and returns it into register_id.

Errors

If value_len + value_ptr points outside the memory or the registers use more memory than the limit with MemoryAccessViolation.

Cost

Where message_blocks is (value_len + 9).div_ceil(64).

base + write_register_base + write_register_byte * num_bytes + ripemd160_base + ripemd160_block * message_blocks

source

pub fn ecrecover( &mut self, hash_len: u64, hash_ptr: u64, sig_len: u64, sig_ptr: u64, v: u64, malleability_flag: u64, register_id: u64 ) -> Result<u64, VMLogicError>

Recovers an ECDSA signer address and returns it into register_id.

Takes in an additional flag to check for malleability of the signature which is generally only ideal for transactions.

Returns a bool indicating success or failure as a u64.

Malleability Flags

0 - No extra checks. 1 - Rejecting upper range.

Errors
  • If hash_ptr, r_ptr, or s_ptr point outside the memory or the registers use more memory than the limit, then returns MemoryAccessViolation.
Cost

base + write_register_base + write_register_byte * 64 + ecrecover_base

source

pub fn ed25519_verify( &mut self, signature_len: u64, signature_ptr: u64, message_len: u64, message_ptr: u64, public_key_len: u64, public_key_ptr: u64 ) -> Result<u64, VMLogicError>

Verify an ED25519 signature given a message and a public key.

Returns a bool indicating success (1) or failure (0) as a u64.

Errors
Cost

Each input can either be in memory or in a register. Set the length of the input to u64::MAX to declare that the input is a register number and not a pointer. Each input has a gas cost input_cost(num_bytes) that depends on whether it is from memory or from a register. It is either read_memory_base + num_bytes * read_memory_byte in the former case or read_register_base + num_bytes * read_register_byte in the latter. This function is labeled as input_cost below.

input_cost(num_bytes_signature) + input_cost(num_bytes_message) + input_cost(num_bytes_public_key) + ed25519_verify_base + ed25519_verify_byte * num_bytes_message

source

pub fn gas(&mut self, opcodes: u32) -> Result<(), VMLogicError>

Called by gas metering injected into Wasm. Counts both towards burnt_gas and used_gas.

Errors
  • If passed gas amount somehow overflows internal gas counters returns IntegerOverflow;
  • If we exceed usage limit imposed on burnt gas returns GasLimitExceeded;
  • If we exceed the prepaid_gas then returns GasExceeded.
source

pub fn promise_create( &mut self, account_id_len: u64, account_id_ptr: u64, method_name_len: u64, method_name_ptr: u64, arguments_len: u64, arguments_ptr: u64, amount_ptr: u64, gas: Gas ) -> Result<u64, VMLogicError>

Creates a promise that will execute a method on account with given arguments and attaches the given amount and gas. amount_ptr point to slices of bytes representing u128.

Errors
  • If account_id_len + account_id_ptr or method_name_len + method_name_ptr or arguments_len + arguments_ptr or amount_ptr + 16 points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Returns

Index of the new promise that uniquely identifies it within the current execution of the method.

Cost

Since promise_create is a convenience wrapper around promise_batch_create and promise_batch_action_function_call. This also means it charges base cost twice.

source

pub fn promise_then( &mut self, promise_idx: u64, account_id_len: u64, account_id_ptr: u64, method_name_len: u64, method_name_ptr: u64, arguments_len: u64, arguments_ptr: u64, amount_ptr: u64, gas: u64 ) -> Result<u64, VMLogicError>

Attaches the callback that is executed after promise pointed by promise_idx is complete.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex;
  • If account_id_len + account_id_ptr or method_name_len + method_name_ptr or arguments_len + arguments_ptr or amount_ptr + 16 points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Returns

Index of the new promise that uniquely identifies it within the current execution of the method.

Cost

Since promise_create is a convenience wrapper around promise_batch_then and promise_batch_action_function_call. This also means it charges base cost twice.

source

pub fn promise_and( &mut self, promise_idx_ptr: u64, promise_idx_count: u64 ) -> Result<PromiseIndex, VMLogicError>

Creates a new promise which completes when time all promises passed as arguments complete. Cannot be used with registers. promise_idx_ptr points to an array of u64 elements, with promise_idx_count denoting the number of elements. The array contains indices of promises that need to be waited on jointly.

Errors
  • If promise_ids_ptr + 8 * promise_idx_count extend outside the guest memory returns MemoryAccessViolation;
  • If any of the promises in the array do not correspond to existing promises returns InvalidPromiseIndex.
  • If called as view function returns ProhibitedInView.
  • If the total number of receipt dependencies exceeds max_number_input_data_dependencies limit returns NumInputDataDependenciesExceeded.
  • If the total number of promises exceeds max_promises_per_function_call_action limit returns NumPromisesExceeded.
Returns

Index of the new promise that uniquely identifies it within the current execution of the method.

Cost

base + promise_and_base + promise_and_per_promise * num_promises + cost of reading promise ids from memory.

source

pub fn promise_batch_create( &mut self, account_id_len: u64, account_id_ptr: u64 ) -> Result<u64, VMLogicError>

Creates a new promise towards given account_id without any actions attached to it.

Errors
  • If account_id_len + account_id_ptr points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
  • If the total number of promises exceeds max_promises_per_function_call_action limit returns NumPromisesExceeded.
Returns

Index of the new promise that uniquely identifies it within the current execution of the method.

Cost

burnt_gas := base + cost of reading and decoding the account id + dispatch cost of the receipt. used_gas := burnt_gas + exec cost of the receipt.

source

pub fn promise_batch_then( &mut self, promise_idx: u64, account_id_len: u64, account_id_ptr: u64 ) -> Result<u64, VMLogicError>

Creates a new promise towards given account_id without any actions attached, that is executed after promise pointed by promise_idx is complete.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex;
  • If account_id_len + account_id_ptr points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
  • If the total number of promises exceeds max_promises_per_function_call_action limit returns NumPromisesExceeded.
Returns

Index of the new promise that uniquely identifies it within the current execution of the method.

Cost

`base + cost of reading and decoding the account id + dispatch&execution cost of the receipt

  • dispatch&execution base cost for each data dependency`
source

pub fn promise_batch_action_create_account( &mut self, promise_idx: u64 ) -> Result<(), VMLogicError>

Appends CreateAccount action to the batch of actions for the given promise pointed by promise_idx.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If called as view function returns ProhibitedInView.
Cost

burnt_gas := base + dispatch action fee used_gas := burnt_gas + exec action fee

source

pub fn promise_batch_action_deploy_contract( &mut self, promise_idx: u64, code_len: u64, code_ptr: u64 ) -> Result<(), VMLogicError>

Appends DeployContract action to the batch of actions for the given promise pointed by promise_idx.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If code_len + code_ptr points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
  • If the contract code length exceeds max_contract_size returns ContractSizeExceeded.
Cost

burnt_gas := base + dispatch action base fee + dispatch action per byte fee * num bytes + cost of reading vector from memory used_gas := burnt_gas + exec action base fee + exec action per byte fee * num bytes

source

pub fn promise_batch_action_function_call( &mut self, promise_idx: u64, method_name_len: u64, method_name_ptr: u64, arguments_len: u64, arguments_ptr: u64, amount_ptr: u64, gas: Gas ) -> Result<(), VMLogicError>

Appends FunctionCall action to the batch of actions for the given promise pointed by promise_idx.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If method_name_len + method_name_ptr or arguments_len + arguments_ptr or amount_ptr + 16 points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

`burnt_gas := base + dispatch action base fee + dispatch action per byte fee * num bytes + cost of reading vector from memory

  • cost of reading u128, method_name and arguments from the memoryused_gas := burnt_gas + exec action base fee + exec action per byte fee * num bytes`
source

pub fn promise_batch_action_function_call_weight( &mut self, promise_idx: u64, method_name_len: u64, method_name_ptr: u64, arguments_len: u64, arguments_ptr: u64, amount_ptr: u64, gas: Gas, gas_weight: u64 ) -> Result<(), VMLogicError>

Appends FunctionCall action to the batch of actions for the given promise pointed by promise_idx. This function allows not specifying a specific gas value and allowing the runtime to assign remaining gas based on a weight.

Gas

Gas can be specified using a static amount, a weight of remaining prepaid gas, or a mixture of both. To omit a static gas amount, 0 can be passed for the gas parameter. To omit assigning remaining gas, 0 can be passed as the gas_weight parameter.

The gas weight parameter works as the following:

All unused prepaid gas from the current function call is split among all function calls which supply this gas weight. The amount attached to each respective call depends on the value of the weight.

For example, if 40 gas is leftover from the current method call and three functions specify the weights 1, 5, 2 then 5, 25, 10 gas will be added to each function call respectively, using up all remaining available gas.

If the gas_weight parameter is set as a large value, the amount of distributed gas to each action can be 0 or a very low value because the amount of gas per weight is based on the floor division of the amount of gas by the sum of weights.

Any remaining gas will be distributed to the last scheduled function call with a weight specified.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If method_name_len + method_name_ptr or arguments_len + arguments_ptr or amount_ptr + 16 points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
source

pub fn promise_batch_action_transfer( &mut self, promise_idx: u64, amount_ptr: u64 ) -> Result<(), VMLogicError>

Appends Transfer action to the batch of actions for the given promise pointed by promise_idx.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If amount_ptr + 16 points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

burnt_gas := base + dispatch action base fee + dispatch action per byte fee * num bytes + cost of reading u128 from memory used_gas := burnt_gas + exec action base fee + exec action per byte fee * num bytes

source

pub fn promise_batch_action_stake( &mut self, promise_idx: u64, amount_ptr: u64, public_key_len: u64, public_key_ptr: u64 ) -> Result<(), VMLogicError>

Appends Stake action to the batch of actions for the given promise pointed by promise_idx.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If the given public key is not a valid (e.g. wrong length) returns InvalidPublicKey.
  • If amount_ptr + 16 or public_key_len + public_key_ptr points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

burnt_gas := base + dispatch action base fee + dispatch action per byte fee * num bytes + cost of reading public key from memory used_gas := burnt_gas + exec action base fee + exec action per byte fee * num bytes

source

pub fn promise_batch_action_add_key_with_full_access( &mut self, promise_idx: u64, public_key_len: u64, public_key_ptr: u64, nonce: u64 ) -> Result<(), VMLogicError>

Appends AddKey action to the batch of actions for the given promise pointed by promise_idx. The access key will have FullAccess permission.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If the given public key is not a valid (e.g. wrong length) returns InvalidPublicKey.
  • If public_key_len + public_key_ptr points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

burnt_gas := base + dispatch action base fee + dispatch action per byte fee * num bytes + cost of reading public key from memory used_gas := burnt_gas + exec action base fee + exec action per byte fee * num bytes

source

pub fn promise_batch_action_add_key_with_function_call( &mut self, promise_idx: u64, public_key_len: u64, public_key_ptr: u64, nonce: u64, allowance_ptr: u64, receiver_id_len: u64, receiver_id_ptr: u64, method_names_len: u64, method_names_ptr: u64 ) -> Result<(), VMLogicError>

Appends AddKey action to the batch of actions for the given promise pointed by promise_idx. The access key will have FunctionCall permission.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If the given public key is not a valid (e.g. wrong length) returns InvalidPublicKey.
  • If public_key_len + public_key_ptr, allowance_ptr + 16, receiver_id_len + receiver_id_ptr or method_names_len + method_names_ptr points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

`burnt_gas := base + dispatch action base fee + dispatch action per byte fee * num bytes + cost of reading vector from memory

  • cost of reading u128, method_names and public key from the memory + cost of reading and parsing account nameused_gas := burnt_gas + exec action base fee + exec action per byte fee * num bytes`
source

pub fn promise_batch_action_delete_key( &mut self, promise_idx: u64, public_key_len: u64, public_key_ptr: u64 ) -> Result<(), VMLogicError>

Appends DeleteKey action to the batch of actions for the given promise pointed by promise_idx.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If the given public key is not a valid (e.g. wrong length) returns InvalidPublicKey.
  • If public_key_len + public_key_ptr points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

burnt_gas := base + dispatch action base fee + dispatch action per byte fee * num bytes + cost of reading public key from memory used_gas := burnt_gas + exec action base fee + exec action per byte fee * num bytes

source

pub fn promise_batch_action_delete_account( &mut self, promise_idx: u64, beneficiary_id_len: u64, beneficiary_id_ptr: u64 ) -> Result<(), VMLogicError>

Appends DeleteAccount action to the batch of actions for the given promise pointed by promise_idx.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If the promise pointed by the promise_idx is an ephemeral promise created by promise_and returns CannotAppendActionToJointPromise.
  • If beneficiary_id_len + beneficiary_id_ptr points outside the memory of the guest or host returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

burnt_gas := base + dispatch action base fee + dispatch action per byte fee * num bytes + cost of reading and parsing account id from memory used_gas := burnt_gas + exec action base fee + exec action per byte fee * num bytes + fees for transferring funds to the beneficiary

source

pub fn promise_results_count(&mut self) -> Result<u64, VMLogicError>

If the current function is invoked by a callback we can access the execution results of the promises that caused the callback. This function returns the number of complete and incomplete callbacks.

Note, we are only going to have incomplete callbacks once we have promise_or combinator.

  • If there is only one callback returns 1;
  • If there are multiple callbacks (e.g. created through promise_and) returns their number;
  • If the function was called not through the callback returns 0.
Cost

base

source

pub fn promise_result( &mut self, result_idx: u64, register_id: u64 ) -> Result<u64, VMLogicError>

If the current function is invoked by a callback we can access the execution results of the promises that caused the callback. This function returns the result in blob format and places it into the register.

  • If promise result is complete and successful copies its blob into the register;
  • If promise result is complete and failed or incomplete keeps register unused;
Returns
  • If promise result is not complete returns 0;
  • If promise result is complete and successful returns 1;
  • If promise result is complete and failed returns 2.
Errors
  • If result_id does not correspond to an existing result returns InvalidPromiseResultIndex;
  • If copying the blob exhausts the memory limit it returns MemoryAccessViolation.
  • If called as view function returns ProhibitedInView.
Cost

base + cost of writing data into a register

source

pub fn promise_return(&mut self, promise_idx: u64) -> Result<(), VMLogicError>

When promise promise_idx finishes executing its result is considered to be the result of the current function.

Errors
  • If promise_idx does not correspond to an existing promise returns InvalidPromiseIndex.
  • If called as view function returns ProhibitedInView.
Cost

base + promise_return

source

pub fn value_return( &mut self, value_len: u64, value_ptr: u64 ) -> Result<(), VMLogicError>

Sets the blob of data as the return value of the contract.

Errors
  • If value_len + value_ptr exceeds the memory container or points to an unused register it returns MemoryAccessViolation.
  • if the length of the returned data exceeds max_length_returned_data returns ReturnedValueLengthExceeded.
Cost

base + cost of reading return value from memory or register + dispatch&exec cost per byte of the data sent * num data receivers

source

pub fn panic(&mut self) -> Result<(), VMLogicError>

Terminates the execution of the program with panic GuestPanic.

Cost

base

source

pub fn panic_utf8(&mut self, len: u64, ptr: u64) -> Result<(), VMLogicError>

Guest panics with the UTF-8 encoded string. If len == u64::MAX then treats the string as null-terminated with character '\0'.

Errors
  • If string extends outside the memory of the guest with MemoryAccessViolation;
  • If string is not UTF-8 returns BadUtf8.
  • If string is longer than max_log_len returns TotalLogLengthExceeded.
Cost

base + cost of reading and decoding a utf8 string

source

pub fn log_utf8(&mut self, len: u64, ptr: u64) -> Result<(), VMLogicError>

Logs the UTF-8 encoded string. If len == u64::MAX then treats the string as null-terminated with character '\0'.

Errors
  • If string extends outside the memory of the guest with MemoryAccessViolation;
  • If string is not UTF-8 returns BadUtf8.
  • If number of bytes read + total_log_length exceeds the max_total_log_length returns TotalLogLengthExceeded.
  • If the total number of logs will exceed the max_number_logs returns NumberOfLogsExceeded.
Cost

base + log_base + log_byte + num_bytes + utf8 decoding cost

source

pub fn log_utf16(&mut self, len: u64, ptr: u64) -> Result<(), VMLogicError>

Logs the UTF-16 encoded string. If len == u64::MAX then treats the string as null-terminated with two-byte sequence of 0x00 0x00.

Errors
  • If string extends outside the memory of the guest with MemoryAccessViolation;
  • If string is not UTF-16 returns BadUtf16.
  • If number of bytes read + total_log_length exceeds the max_total_log_length returns TotalLogLengthExceeded.
  • If the total number of logs will exceed the max_number_logs returns NumberOfLogsExceeded.
Cost

base + log_base + log_byte * num_bytes + utf16 decoding cost

source

pub fn abort( &mut self, msg_ptr: u32, filename_ptr: u32, line: u32, col: u32 ) -> Result<(), VMLogicError>

Special import kept for compatibility with AssemblyScript contracts. Not called by smart contracts directly, but instead called by the code generated by AssemblyScript.

Errors
  • If string extends outside the memory of the guest with MemoryAccessViolation;
  • If string is not UTF-8 returns BadUtf8.
  • If number of bytes read + total_log_length exceeds the max_total_log_length returns TotalLogLengthExceeded.
  • If the total number of logs will exceed the max_number_logs returns NumberOfLogsExceeded.
Cost

base + log_base + log_byte * num_bytes + utf16 decoding cost

source

pub fn storage_write( &mut self, key_len: u64, key_ptr: u64, value_len: u64, value_ptr: u64, register_id: u64 ) -> Result<u64, VMLogicError>

Writes key-value into storage.

  • If key is not in use it inserts the key-value pair and does not modify the register. Returns 0;
  • If key is in use it inserts the key-value and copies the old value into the register_id. Returns 1.
Errors
  • If key_len + key_ptr or value_len + value_ptr exceeds the memory container or points to an unused register it returns MemoryAccessViolation;
  • If returning the preempted value into the registers exceed the memory container it returns MemoryAccessViolation.
  • If the length of the key exceeds max_length_storage_key returns KeyLengthExceeded.
  • If the length of the value exceeds max_length_storage_value returns ValueLengthExceeded.
  • If called as view function returns `ProhibitedInView``.
Cost

`base + storage_write_base + storage_write_key_byte * num_key_bytes + storage_write_value_byte * num_value_bytes

  • get_vec_from_memory_or_register_cost x 2`.

If a value was evicted it costs additional storage_write_value_evicted_byte * num_evicted_bytes + internal_write_register_cost.

source

pub fn storage_read( &mut self, key_len: u64, key_ptr: u64, register_id: u64 ) -> Result<u64, VMLogicError>

Reads the value stored under the given key.

  • If key is used copies the content of the value into the register_id, even if the content is zero bytes. Returns 1;
  • If key is not present then does not modify the register. Returns 0;
Errors
  • If key_len + key_ptr exceeds the memory container or points to an unused register it returns MemoryAccessViolation;
  • If returning the preempted value into the registers exceed the memory container it returns MemoryAccessViolation.
  • If the length of the key exceeds max_length_storage_key returns KeyLengthExceeded.
Cost

base + storage_read_base + storage_read_key_byte * num_key_bytes + storage_read_value_byte + num_value_bytes cost to read key from register + cost to write value into register.

source

pub fn storage_remove( &mut self, key_len: u64, key_ptr: u64, register_id: u64 ) -> Result<u64, VMLogicError>

Removes the value stored under the given key.

  • If key is used, removes the key-value from the trie and copies the content of the value into the register_id, even if the content is zero bytes. Returns 1;
  • If key is not present then does not modify the register. Returns 0.
Errors
  • If key_len + key_ptr exceeds the memory container or points to an unused register it returns MemoryAccessViolation;
  • If the registers exceed the memory limit returns MemoryAccessViolation;
  • If returning the preempted value into the registers exceed the memory container it returns MemoryAccessViolation.
  • If the length of the key exceeds max_length_storage_key returns KeyLengthExceeded.
  • If called as view function returns `ProhibitedInView``.
Cost

`base + storage_remove_base + storage_remove_key_byte * num_key_bytes + storage_remove_ret_value_byte * num_value_bytes

  • cost to read the key + cost to write the value`.
source

pub fn storage_has_key( &mut self, key_len: u64, key_ptr: u64 ) -> Result<u64, VMLogicError>

Checks if there is a key-value pair.

  • If key is used returns 1, even if the value is zero bytes;
  • Otherwise returns 0.
Errors
  • If key_len + key_ptr exceeds the memory container it returns MemoryAccessViolation.
  • If the length of the key exceeds max_length_storage_key returns KeyLengthExceeded.
Cost

base + storage_has_key_base + storage_has_key_byte * num_bytes + cost of reading key

source

pub fn storage_iter_prefix( &mut self, _prefix_len: u64, _prefix_ptr: u64 ) -> Result<u64, VMLogicError>

DEPRECATED Creates an iterator object inside the host. Returns the identifier that uniquely differentiates the given iterator from other iterators that can be simultaneously created.

  • It iterates over the keys that have the provided prefix. The order of iteration is defined by the lexicographic order of the bytes in the keys;
  • If there are no keys, it creates an empty iterator, see below on empty iterators.
Errors
  • If prefix_len + prefix_ptr exceeds the memory container it returns MemoryAccessViolation.
  • If the length of the prefix exceeds max_length_storage_key returns KeyLengthExceeded.
Cost

base + storage_iter_create_prefix_base + storage_iter_create_key_byte * num_prefix_bytes cost of reading the prefix.

source

pub fn storage_iter_range( &mut self, _start_len: u64, _start_ptr: u64, _end_len: u64, _end_ptr: u64 ) -> Result<u64, VMLogicError>

DEPRECATED Iterates over all key-values such that keys are between start and end, where start is inclusive and end is exclusive. Unless lexicographically start < end, it creates an empty iterator. Note, this definition allows for start or end keys to not actually exist on the given trie.

Errors
  • If start_len + start_ptr or end_len + end_ptr exceeds the memory container or points to an unused register it returns MemoryAccessViolation.
  • If the length of the start exceeds max_length_storage_key returns KeyLengthExceeded.
  • If the length of the end exceeds max_length_storage_key returns KeyLengthExceeded.
Cost

`base + storage_iter_create_range_base + storage_iter_create_from_byte * num_from_bytes

  • storage_iter_create_to_byte * num_to_bytes + reading from prefix + reading to prefix`.
source

pub fn storage_iter_next( &mut self, _iterator_id: u64, _key_register_id: u64, _value_register_id: u64 ) -> Result<u64, VMLogicError>

DEPRECATED Advances iterator and saves the next key and value in the register.

  • If iterator is not empty (after calling next it points to a key-value), copies the key into key_register_id and value into value_register_id and returns 1;
  • If iterator is empty returns 0; This allows us to iterate over the keys that have zero bytes stored in values.
Errors
  • If key_register_id == value_register_id returns MemoryAccessViolation;
  • If the registers exceed the memory limit returns MemoryAccessViolation;
  • If iterator_id does not correspond to an existing iterator returns InvalidIteratorId;
  • If between the creation of the iterator and calling storage_iter_next the range over which it iterates was modified returns IteratorWasInvalidated. Specifically, if storage_write or storage_remove was invoked on the key key such that:
    • in case of storage_iter_prefix. key has the given prefix and:
      • Iterator was not called next yet.
      • next was already called on the iterator and it is currently pointing at the key curr such that curr <= key.
    • in case of storage_iter_range. start<=key<end and:
      • Iterator was not called next yet.
      • next was already called on the iterator and it is currently pointing at the key curr such that curr<=key<end.
Cost

`base + storage_iter_next_base + storage_iter_next_key_byte * num_key_bytes + storage_iter_next_value_byte * num_value_bytes

  • writing key to register + writing value to register`.
source

pub fn compute_outcome_and_distribute_gas(self) -> VMOutcome

Computes the outcome of the execution.

If FunctionCallWeight protocol feature (127) is enabled, unused gas will be distributed to functions that specify a gas weight. If there are no functions with a gas weight, the outcome will contain unused gas as usual.

source

pub fn add_contract_loading_fee( &mut self, code_len: u64 ) -> Result<(), VMLogicError>

Add a cost for loading the contract code in the VM.

This cost does not consider the structure of the contract code, only the size. This is currently the only loading fee. A fee that takes the code structure into consideration could be added. But since that would have to happen after loading, we cannot pre-charge it. This is the main motivation to (only) have this simple fee.

source

pub fn gas_counter_pointer(&mut self) -> *mut FastGasCounter

Gets pointer to the fast gas counter.

source

pub fn process_gas_limit(&mut self) -> HostError

Properly handles gas limit exceeded error.

source

pub fn pay_action_base( &mut self, action: ActionCosts, sir: bool ) -> Result<(), VMLogicError>

A helper function to pay base cost gas fee for batching an action.

source

pub fn pay_action_per_byte( &mut self, action: ActionCosts, num_bytes: u64, sir: bool ) -> Result<(), VMLogicError>

A helper function to pay per byte gas fee for batching an action.

source

pub fn before_loading_executable( &mut self, method_name: &str, current_protocol_version: u32, wasm_code_bytes: usize ) -> Result<(), FunctionCallError>

VM independent setup before loading the executable.

Does VM independent checks that happen after the instantiation of VMLogic but before loading the executable. This includes pre-charging gas costs for loading the executable, which depends on the size of the WASM code.

source

pub fn after_loading_executable( &mut self, current_protocol_version: u32, wasm_code_bytes: usize ) -> Result<(), FunctionCallError>

Legacy code to preserve old gas charging behaviour in old protocol versions.

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for VMLogic<'a>

§

impl<'a> !Send for VMLogic<'a>

§

impl<'a> !Sync for VMLogic<'a>

§

impl<'a> Unpin for VMLogic<'a>

§

impl<'a> !UnwindSafe for VMLogic<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoRequest<T> for T

source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
source§

impl<T> Same<T> for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for Twhere V: MultiLane<T>,

§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more