Applying chunk

Inputs and outputs

Runtime.apply takes following inputs:

  • trie and current state root
  • validator_accounts_update
  • incoming_receipts
  • transactions

and produces following outputs:

  • new state root
  • validator_proposals
  • outgoing_receipts
  • (executed receipt) outcomes
  • proof

Processing order

  • If this is first block of an epoch, dispense epoch rewards to validators (in order of validator_accounts_update.stake_info)
  • Slash locked balance for malicious behavior (in order of validator_accounts_update.slashing_info)
  • If treasury account was not one of validators and this is first block of an epoch, dispense treasury account reward
  • If this is first block of new version or first block with chunk of new version, apply corresponding migrations
  • If this block do not have chunk for this shard, end process early
  • Process transactions (in order of transactions)
  • Process local receipts (in order of transactions that generated them)
  • Process delayed receipts (ordered first by block where they were generated, then first local receipts based on order of generating transactions, then incoming receipts, ordered by incoming_receipts order)
  • Process incoming receipts (ordered by incoming_receipts)

When processing receipts we track gas used (including gas used on migrations). If we use up gas limit, we immediately stop to process delayed receipts, and for local and incoming receipts we add them to delayed receipts)

  • If any of the delayed receipts were processed or any new receipts were delayed, update indices of first and last unprocessed receipts in state
  • Remove duplicate validator proposals (for each account we only keep last one in receipts processing order)

Please note that local receipts are receipts generated by transaction where receiver is the same as signer of the transaction

Delayed receipts

In each block we have maximal amount of Gas we can use to process receipts and migrations, currently 500 TGas. If any incoming or local receipts are not processed due to lack of remaining Gas, they are stored in state with key

TrieKey::DelayedReceipt { id }
where id is unique index for each shard, assigned consecutively. Currently sender does not need to stake any tokens to store delayed receipts. State also contains special key
TrieKey::DelayedReceiptIndices
where first and last ids of delayed receipts not yet processed are stored.