Starknet v0.13.1 pre-release notes

Sepolia Testnet – March 5
Goerli Testnet – March 7
Mainnet – March 12

Conceptual Changes

Starknet v0.13.1 deals mostly with stability and performance improvements. The following items cover the changes feature-wise:

  1. Starknet will use EIP4844 and send state diffs as blobs rather than calldata. This means that we need to add the notion of data_gas to Starknet blocks.

  2. Pricing

    1. The gas prices of various Starknet operations will be reduced due to the adoption of EIP4844 alongside other improvements.

    2. The pricing for calldata and class declaration will change.

  3. Bytecode segmentation – changing the definition of a compiled class hash so that only the used functions of a contract will be loaded into memory during the proof.

  4. Changes in behavior of time-related syscalls when called from validate:

    1. The get_block_timestamp syscall will return the hour, rounded down

    2. The get_blocknum syscall will return the block number rounded down to the nearest multiple of 100

API Changes

FGW request/response

  1. Adding the l1_da_mode field to the block header (including the pending block), a string enum that takes the values “CALLDATA” or “BLOB” and indicates the DA solution that is used for this particular block

  2. Adding the l1_data_gas_price field to the block header (including the pending block).

    1. Contains price_in_wei and price_in_fri (10-18 denominations, similar to v0.6.0).
  3. Similarly to the above, the existing fields eth_l1_gas_price and strk_l1_gas_price will be under a new field l1_gas_price.

  4. get_compiled_class_by_class_hash will return the updated compiled class structure, i.e. including segments data.

    1. Concretely, the field bytecode_segments_lengths is added, which is a nested list of integers.
  5. Transactions + events commitments are added to get_block endpoint.

  6. Transaction receipt refactor:

    1. Receipts, as they appear in a get_block request, now include the data_availability property, which isolates DA resources from computation resources. This property includes l1_gas and l1_data_gas that were incurred by state updates (one of them will always be zero)

    2. Receipts now include syscall-related resources. Each syscall has an associated step-cost, which can be found here. So far, these costs were included in the fee but not reported inside receipts. This is now changing, so a spike in the receipt resources is to be expected, these are not new costs, rather these are costs that are already incurred but were not reported in the receipt so far.

The source of truth for the feeder gateway response is FGW response objects.

JSON RPC

It is completely fine to continue using rpc v0.6.0 to interact with SN 0.13.1. Responses from 0.13.1 can be mapped naturally into v0.6.0 objects (see the next section).

A new version of the RPC, 0.7.0, will be released to accommodate the changes induced by using EIP4844:

  1. Addition of EIP4844 l1_data_gas_price field in block header.

    1. Contains price_in_wei and price_in_fri (10-18 denominations, similar to v0.6.0).
  2. Addition of the l1_da_mode field to the block header. This is an enum that indicates whether this block will use calldata or blobdata and can take the following values:

    1. CALLDATA

    2. BLOB

  3. FEE_ESTIMATE

    1. Will include two new fields:

      1. data_gas_consumed

      2. data_gas_price

    2. overall_fee will now be gas_consumed × gas_price + data_gas_consumed × data_gas_price

    3. Fee estimates will change depending on the DA solution used by current Starknet blocks, i.e. if I estimate fee against the pending block, and it’s currently using CALLDATA, then nodes are expected to return data_gas_consumed=0 and compute the fee similarly to today (i.e. get higher estimates)

  4. We are adding data availability resources to the receipts and traces

    1. The field data_availability is added to execution_resources of receipts

    2. A new execution_resources entry is added to the main receipt object, and this entry will include DA resources. Note that the resources of internal calls will remain the same

    3. For more details, see the PR to the specs

  5. EXECUTION_RESOURCES

    1. Similarly to the FGW changes, we’re separating computation resources from DA resources. This is done by introducing a new data_availability property which includes l1_gas and l1_data_gas that were consumed due to DA requirements. One of these will always be zero, depending on whether or not the block uses calldata or blobs (as specified by the l1_da_mode field in the block header)

    2. Syscall costs are now included in the execution resources of traces and receipts. These are costs that are already being paid for but were not reported so far.

Conventions to embed new RPC version in old

Nodes serving RPC 0.6.0 are expected to:

  • Ignore the new blob-related fields in the various getBlock requests

  • Keep starknet_estimateFee/starknet_simulateTransactions unchanged. Fee estimations will continue to assume only calldata is used to send state diffs to L1, hence can be significantly larger than the fee charged in practice.

FGW response object → RPC response object

  1. Map l1_data_gas_price FGW response to l1_data_gas_price RPC response.

  2. Map l1_gas_price FGW response to l1_gas_price RPC response.

(SDKs/Wallets) How to use the new fee estimates?

When we communicate with a node serving rpc 0.7.0, the estimateFee response is richer, and gas_consumed does not account for the resources associated with storage updates (this is encapsulated in data_gas_consumed).

In Starknet v0.13.1,v3 transactions don’t send data_gas related fields (max price or max amount). This may change in the future, but it means that we need to define how to map (gas_consumed, gas_price, data_gas_consumed, data_gas_price, overall_fee) into max_amount and max_price_per_unit in the L1_GAS resource (in the future, we might add fields in the resource mapping of v3 transactions, in which case we’ll have a natural mapping between the fee estimate and the signed transaction fields, but this is not yet the case).

The suggested behavior for SDKs, wallets, or any party sending v3 transactions, is to sign over the following fields:

  • L1_GAS:

    • max_amount: (overall_fee / gas_price) × gas_safety_margin

    • max_price_per_unit: gas_price × fee_safety_margin

Where gas_safety_margin and fee_safety_margin are overheads placed by the sdk/wallet to ensure the transaction won’t be rejected due to price fluctuations (the former safety margin isn’t really related to the price, but rather to the potential state changes by the time the tx is processed, leading to a slightly different execution resulting in a minor gas difference). Currently, starknet.js sets those numbers to 1.1 and 1.5 correspondingly.

Note that the data_gas_consumed field is only used indirectly from the overall_fee field. This trick allows us to fold the two cost dimensions (data_gas and gas) into the single L1_GAS resource, which is currently in the v3 transaction resource_bounds field.

:warning:Note: unlike in the old fee estimates, max_amount now depends on the ratio data_gas_price/gas_price at the time of estimation, and not only on the state of Starknet. Hence, price fluctuations will affect max_amount and not only gas_price. Therefore we need a larger safety margin (larger than today’s 10%).

For transactions of version ≤2, this is a non-issue since we’re signing max_fee, which can still be overall_fee × fee_safety_margin.

Cairo

We will have Cairo v2.6.0 / Sierra v1.5.0 with the following changes:

  • The CasmContractClass struct changes and includes bytecode_segments_length

  • New libfuncs are added that require the new compiler

    • gas related (redeposit_gas, coupons)

    • match expressions related (enum_from_felt252_bounded)

    • consts related (const_as_box)

    • nullable_forward_snapshot, box_forward_snapshot

  • Hash computation of compiled contract classes changes

    • Backwards compatible for old classes (when compiling Sierra <= 1.4.0, the new compiler will not add segments data, so the structure/hash remains the same)

    • For a non-trivial segmentation, the bytecode hash will be the Poseidon hash of all segments: The hash of a function is the Poseidon hash of its bytecode, and the hash of a compiled class is the chain-hash of its functions’ hashes.

The source of truth on the computation of compiled class hashes is in compiled_class_hash.py

Execution Changes

Blockifier

  • Added data_gas_price to block context (see PR).

  • Added use_kzg_da bit to the block context (see PR) - this field will allow getting estimates both old and new fee estimates (note that RPC v0.6.0 should always pass false here, otherwise gas_consumed will be too low).

  • A configuration with parameters that can affect execution will be added to the BlockContext struct and be used in execute: (see PR)

    • Pricing information (relative weights of steps/builtins and syscall prices)

    • Tx limits (validate max steps limits, execute max steps limit, etc.)

    • The blockifier repo will contain config files associated with recent SN versions (0.13.0 and 0.13.1)

  • Added a preprocess_block function that takes a state at the end of block X-1 and returns the block context + state for the beginning of block X (namely, adding the block hash of block X-10 to the state)

Pricing changes

Computation

The Cairo step price is reduced by a factor of 2x, and will now cost 0.0025 gas/step. This also means that the costs of all builtins are halved accordingly.

Calldata and signatures

Each felt in the calldata and signature arrays of all transaction types is now priced at 0.128gas/felt

Class declaration

Each felt of sierra_program in the contract class and of bytecode in the compiled contract class is now priced at 28 gas/felt (note that for v1 declares, we only have bytecode).

Additionally, each character in the ABI costs 0.875 gas

Events

An additional felt to the data array of an event now costs 0.128 gas/felt (similarly to calldata). An additional felt to the keys array now costs 0.256 gas/felt.

Action items

Full nodes

  • Release a new version that can sync with SN 0.13.1 before the Testnet upgrade

  • Upgrade the compiler and blockifier dependencies (cairo 2.6.0 / blockifier 0.5.0)

  • Serve RPC 0.7.0

API providers

  • Upgrade to the new node version before the Testnet upgrade

  • Nice to have: offer 0.7.0 endpoints

SDKs

  • Release a version that supports RPC 0.7.0 and properly sign v3 txs in accordance with the above suggestion

Wallets

  • Use the new SDK versions to get more accurate fee estimates, and sign v3 txs in accordance with the above suggestion.

DApps

  • RPC version 0.4.0 will no longer be supported by nodes, dapps are expected to update their SDK and work with rpc version >= 0.5.0 (preferably, the more update 0.6.0 which is already supported by all SDKs)