Skip to main content

Transaction Costing

What are transaction costs?

At the very high-level, transaction costs can be broken down into the following categories:


Item
Unit of MeasurementDescription
ExecutionExecution Cost Unit

This is to account for the CPU usage during the execution of a transaction.


In this context, execution refers to the process of determining the state changes and other side effects by interpreting the instructions one-by-one upon some existing world state.

FinalisationFinalisation Cost UnitThis is to account for the CPU usage during the finalisation of a transaction.

In this context, finalisation refers to the process of committing state changes derived from a transaction and other auxiliary indices.
StorageBytes

This is to account for the additional data being added to a Node database.

There are currently two type of storage costs:

  1. State Storage - The substates
  2. Archive Storage - Transaction payload, events and logs
RoyaltiesXRD and USDThe amount of XRD paid to blueprint developers and component owners for the use of the code or component instances.
TipPercentageThe extra amount of XRD paid to validators for the processing of a transaction.

This is designed to help prioritise transaction when there is a traffic jam.

How does costing work?

Untitled.drawio.png

Transaction costing is done through the costing module within the System.

This module is responsible for tracking the fee balance, counting execution and finalisation cost units and applying the costs listed above, with the help of a fee reserve.

At the beginning of a transaction, the fee reserve is provided with a loan of XRD to bootstrap transaction execution. 

  • The amount is defined as:
execution_cost_unit_price  * ( 1 + tip_percentage / 100) * execution_cost_unit_loan
  • This loan must be repaid before execution_cost_unit_loan number of execution cost units are consumed ("repay condition"), otherwise the transaction is rejected.

After that, transaction execution starts, during which two processes happen

  • Kernel and system sends **execution cost events **(such as CPU usage, royalties) to the costing module:
    • To deduct the fee balance
    • To increase the cost unit counter
    • To repay system loan and apply deferred costs, if repay condition is met
  • System sends vault lock fee events to the costing module:
    • To credit fee balance

Once execution is done, costing module is instructed to apply finalisation cost and storage cost.

Costing Parameters

The following parameters are used by the costing module.

Protocol defined parameters

NameValueDescription
execution_cost_unit_price0.00000005The price of execution cost unit in XRD.
execution_cost_unit_limit100,000,000The maximum number of execution cost units that a transaction can consume.
execution_cost_unit_loan4,000,000The number of execution cost units loaned from the system, to bootstrap transaction execution.
finalization_cost_unit_price0.00000005The price of finalisation cost unit in XRD.
finalization_cost_unit_limit50,000,000The maximum number of finalisation cost units that a transaction can consume.
usd_price16.666666666666666666The price of USD in XRD.  1 XRD = 0.06 USD
state_storage_price0.00009536743The price of state storage. 1 MiB = 6 USD
archive_storage_price0.00009536743The price of archive storage.  1MiB = 6 USD

Transaction defined parameters

NameDescription
tip_percentageThe tip percentage specified by the transaction.
free_credit_in_xrdThe free credit amount specified by a preview request.

Fee Table

The table below further defines the cost of each costing entry.

CategoryEntryDescriptionCost

Execution
(execution cost unit)

VerifyTxSignatures

Verify transaction signature.Variable: num_of_signature * 7000

ValidateTxPayload

Verify transaction payload.Variable: size(payload) * 40

RunNativeCode

Run native code.Native code execution is billed in native execution unit per function based on table here.
34 native execution units = 1 execution cost unit

RunWasmCode

Run WASM code.WASM code execution is billed in WASM execution units per instruction based on weights here.
3000 WASM execution units = 1 execution cost unit

PrepareWasmCode

Prepare WASM code.Variable: size(wasm) * 2

BeforeInvoke

Before function invocation.Variable: size(input) * 2

AfterInvoke

After function invocation.Variable: size(output) * 2

AllocateNodeId

Allocate a new node id. Node is the lower level representation of an object or key value store.Fixed: 97

CreateNode

Create a new node.Variable: size(substate) + 456

DropNode

Drop a node.Variable: size(substate) +1143

PinNode

Pin a node to a device (heap or track).Variable: 12 + IO access

MoveModule

Move module from one node to another.Variable: 140 + IO access

OpenSubstate

Open a substate of a node.Variable: 303 + IO access

ReadSubstate

Read the value of a substate.

Variable:

  • If from heap: 65 + size(substate) * 2 + IO access
  • If from track: 113 + size(substate) * 2 + IO access

WriteSubstate

Update the value of a substate.Variable: 218 + size(substate) * 2 + IO access

CloseSubstate

Cloes a substate.Fixed: 129

MarkSubstateAsTransient

Marks a substate a transient. Transient substates are not committed after transaction.Fixed: 55

SetSubstate

Set the value of a substateVariable: 133 + size(substate) * 2 + IO access

RemoveSubstate

Remove a substateVariable: 717 + IO access

ScanKeys

Scan substate keys in a collectionVariable: 498 + IO access

ScanSortedSubstates

Scan substates in a collectionVariable: 187 + IO access

DrainSubstates

Drain substates in a collectionVariable: 273 * num_of_substates + 272 + IO access

LockFee

Lock feeFixed: 500

QueryFeeReserve

Query state of fee reserveFixed: 500

QueryActor

Query actor of this call frameFixed: 500

QueryTransactionHash

Query the transaction hashFixed: 500

GenerateRuid

Generate a RUIDFixed: 500

EmitEvent

Emit an eventVariable: 500 + size(event) * 2

EmitLog

Emit a logVariable: 500 + size(log) * 2

Panic

Panic and abort executionVariable: 500 + size(message) * 2
Finalisation
(finalisation cost unit)

CommitStateUpdates

Commit state updates

Variable, per substate:

  • Insert or update: 100,000 + size(substate) / 4
  • Delete: 100,000

CommitEvents

Commit eventsVariable, per event: 5,000 + size(event) / 4

CommitLogs

Commit logsVariable, per log: 1,000 + size (log) / 4
Storage
(XRD)

IncreaseStateStorageSize

Increase the size of the state storageVariable, per byte: 0.00009536743

IncreaseArchiveStorageSize

Increase the size of the archive storageVariable, per byte: 0.00009536743

IO access cost:

  • Read from database and found: 40,000 + size / 10
  • Read from database and not found: 160,000

Costing Runtime APIs

The system exposes a list of API to query the current state of the fee reserve.

See WASM API and Scrypto rustdoc.

Fee Distribution

CostTo ProposerTo Validator SetTo BurnTo Royalty Owners
Execution25%25%50%0
Finalisation25%25%50%0
Storage25%25%50%0
Royalty000100%
Tip100%000