Skip to main content

Life of a Transaction

At a high level, the following diagram outlines the life cycle of a transaction on the Sui blockchain.

Transaction life cycle

The following steps align with those in the diagram:

  1. A user with a private key creates and signs a user transaction to either mutate objects they own, shared objects, or create new objects.

  2. Sui sends the transaction to each validator, often through a full node. Validators perform a series of validity and safety checks, sign it, and return the signed transaction to the client.

  3. The client collects the responses from a set of validators that account for at least 2/3 of the validator committee to form a transaction certificate. As a result, Sui validators do not need to propagate signatures on a best-effort basis (gossip signatures) or aggregate certificates. This effort is now the responsibility of the client or gateway.

  4. After assembling the certificate, the client sends it back to all validators, who check its validity and acknowledge its receipt to the client.

    1. If the transaction involves owned objects or immutable objects exclusively, Sui can process the transaction certificate immediately and execute it without waiting for the consensus engine.
  5. All certificates are forwarded to the Sui DAG-based consensus protocol, which also operated by the validators. Consensus outputs a complete order of certificates; the validators check and execute those that contain [shared objects].

  6. Clients can collect a supermajority of validator responses, assemble them into an effects certificate, and use it as proof of the transaction settlement.

  7. Subsequently, Sui forms checkpoints for every consensus commit, which it uses to drive the reconfiguration protocol.

The Sui Lutris paper provides additional details on how the safety and liveness protocols operate, as well as proof of security for the standard distributed systems model with Byzantine participants in partial synchrony.

Transaction submission

All transactions on Sui begin when they are submitted to the network. For example, imagine you want to transfer an NFT that you own in your wallet to your friend. First, you would create a transaction using a wallet or some other app. The transaction includes your gas object and a command to transfer the NFT object to your friend's address. Before the wallet or app submits the transaction to the network, it must also sign it.

After the transaction is signed, the wallet or app submits the transaction to a Sui full node on behalf of the user.

Certification

Certification happens after a transaction gets submitted to a full node. The full node cannot certify the transaction on its own because it does not have a complete view of transactions across the network. Consequently, the full node sends the transaction to validators. Each validator performs a validity check on the transaction and signs it if it passes. To be considered valid, the transaction must pass the following checks:

  • The transaction has a valid user signature.

  • The initiator of the transaction must have access to all the owned input objects the transaction uses. In the previous NFT example, the validity check makes sure you own the NFT you're trying to send to a friend.

  • All the shared input objects used by the transaction exist.

  • The gas coin is a Coin<SUI> object, and it contains at least as much gas as specified in the transaction's gas budget.

If all the validity checks pass, the validator then attempts to lock all the owned input objects to the given transaction digest. This ensures each owned input object can only be used by one transaction at a time and is the way that Sui prevents double-spending. In other words, this makes sure that you send your NFT to only one friend instead of trying to send the same NFT to all your friends.

If the locking succeeds, the validator signs the transaction using its BLS private key and returns the signature to the full node. A single validator signature is not enough, though. The full node must collect signatures from enough validators to form a supermajority (2/3).

info

Full nodes collect signatures from validators in parallel to minimize latency.

After the full node collects a supermajority of validator signatures, the transaction is considered certified as the full node has formed a transaction certificate.

It is impossible to concurrently form certificates for two different transactions that attempt to use the same owned object. This is true even if there are some dishonest validators that illegally sign both transactions, because of a principle in distributed computing called quorum intersection.

If fewer than 1/3 of the validators are dishonest, then the set of signers for any two certificates must have an overlap that includes at least one honest validator. Crucially, because that validator is honest, it never signs two transactions that attempt to access the same input object at the same version. After the transaction completes, the input object version changes and can be accessed again by subsequent transactions.

Execution

Full nodes send transactions that have a certificate to validators for execution. Each validator verifies the signatures on the certificate. If the certificate signatures are valid, then the validator can be sure that the transaction passed all validity checks and is not attempting to double-spend any objects.

The validator submits the transaction to Sui's consensus layer, which orders the transaction with respect to other transactions using the same shared objects and then executes it. Transactions that don't overlap on inputs at all can be verified and executed completely in parallel.

Transaction effects and finality

After the transaction executes, the validator signs the effects of the transaction and returns them to the full node. The transaction effects are a list of all the actions that the transaction took, which include:

  • All the objects that were mutated, created, wrapped, unwrapped, or deleted.

  • The gas that was spent.

  • The execution status (success or an error code) of the transaction.

Eventually, the full node collects effects signatures from a supermajority of validators. This collection of signatures, plus the effects themselves, is called an effects certificate.

tip

An effects certificate guarantees transaction finality. After you or a full node observes an effects certificate, you are guaranteed that the transaction is going to be included in a checkpoint, which means that the transaction cannot be reverted.

You could present the effects certificate to your friend to prove that you sent them the NFT. The presence of the validator signatures means that an effects certificate cannot be forged.

Including the transaction in a checkpoint

Inclusion in a checkpoint is the final stage in the life of a transaction. As validators execute transactions, they submit them to consensus.

While transactions that use shared input objects must be sent to consensus before they are executed, owned-input-only transactions are also sent to consensus. The difference is that owned-input-only transactions are executed first.

The consensus layer produces a universally agreed-upon ordering of transactions. This ordering is the starting point for the creation of checkpoints.

The validators take chunks of ordered transactions from the consensus layer and use them to form a checkpoint. Each chunk of transactions is first made causally complete and causally ordered. This means that the validators add any missing dependencies to the list of transactions and order them so that dependencies always appear before dependents in checkpoints.

Then the validator constructs a checkpoint, which (among other data) contains a list of transaction digests as well as the digests of the transaction effects of each transaction. Because checkpoints must be complete, the network sometimes has to wait for the availability of all transactions to form the checkpoints, which might take a couple of commits to process. This process typically completes in the order of a few seconds.

At this point, the transaction has reached the end of its life cycle and is included in the permanent record of transaction activity on the Sui network.

Transaction finality timing

The network round trip of sending a transaction and receiving a validator signature takes less than half a second to complete. At this point the sender knows the transaction is irrevocable and is going to be processed within the epoch, no matter what. The transaction has reached finality; honest validators deem any subsequent transactions using the same owned input objects during the same epoch invalid.

Settlement finality timing

After the supermajority of validators have executed the transaction and an effects certificate exists, the effects of the transaction (transfers, newly minted objects, and so on) have been implemented. At this point, the network can process transactions that depend on those effects.

For transactions that involve owned objects only, this happens before consensus in under 1/2 a second. If a transaction includes shared objects, it happens shortly after consensus, which can take a few seconds. At this point, the transaction reached settlement finality because now you can process more transactions on the same input objects. See Object Ownership for more information.

Epoch change

Periodically (~24 hours), the Sui Testnet and Mainnet networks enter the process of epoch change. During epoch change, the network calculates and distributes staking rewards, validator metadata takes effect, and other network processes are performed. All user transactions are delayed until the new epoch begins.

If your transaction is submitted at epoch boundary, in rare perfect timing it is possible that a quorum of validators already decided to not accept any new transaction certificates in the current epoch. This means your transaction is not checkpointed either. For any transactions that are certified but not finalized, they are reverted if executed or its owned objects are unlocked and not yet executed.

In this case, the transaction certificate does not guarantee finality. In the new epoch, this transaction certificate becomes void because validator signatures are signed over epoch ID. To continue this transaction, a new transaction certificate is necessary with the new epoch ID. The standard full node implementation handles this automatically.

Verifying finality

If an app stores the signed transaction locally before sending it to the full node, which is best practice, when the app restarts it tries to verify if the transaction has been finalized first. If it has, then no other steps are necessary. If it has not, then the app needs to resubmit the transaction.

The wallet app can query the full node with the getTransactionBlock method. Assuming the full node is honest:

  • If the response contains transaction details, the transaction must have been finalized. It is either executed with WaitForLocalExecution or executed as a checkpointed transaction.

  • If the response is None, it could mean the transaction was dropped in some step or is already finalized but this full node does not know yet. In this scenario, the safer option is to resubmit the transaction.

Before a transaction is locally executed, its effects are not reflected on the full node. This full node must wait for the transaction to be checkpointed and state synced, which normally takes a few seconds. After the full node receives this transaction in a checkpoint, it is executed and has effects updated locally.

Example: Coffee shop payment

As a real-world example, suppose you want to pay the local coffee shop 10 SUI for your morning coffee. The following steps demonstrate how the coffee shop can be sure that the payment is complete.

Transaction creation and signing

You open the wallet app on your phone and scan the coffee shop's QR code that contains the recipient on-chain address. The wallet app constructs a transaction that transfers 10 SUI from your Sui address to the coffee shop's address. You review the transaction details and approve it. The wallet app then signs the transaction with your private key and submits it to a full node. The full node broadcasts the transaction to all validators in the network.

Certification and execution

Validators receive the transaction from the full node and examine its validity. After confirming the transaction passes all validity checks, each validator locks the referenced owned objects and returns its signature to the full node.

After the full node collects a quorum of signatures (2/3 of validators), it forms a transaction certificate and broadcasts it to all validators. Validators verify the certificate, execute the transaction, and unlock the previously locked owned objects. They sign the transaction effects and return them to the full node.

The full node verifies that effects returned from validators are identical. After it collects a supermajority of signatures, it forms an effects certificate. At this point, your wallet app receives the effects certificate, which you can share with the coffee shop. The coffee shop can then be sure that the transaction is executed and irreversible.

Checkpoint inclusion

If the original full node goes offline before collecting all signatures, your wallet app can retry with a different full node. Alternatively, a different full node learns about your transaction through checkpoints.

A checkpoint contains a list of transactions. If a transaction appears in a certified checkpoint (signed by a supermajority of validators), it is considered finalized. The full node that the coffee shop's terminal connects to knows about your transaction through state sync. As long as one validator receives the transaction certificate from your original full node, the transaction likely finalizes even without an effects certificate. The coffee shop is assured of payment and can give you your coffee.

Local execution on full node

Before the full node sends back an effects certificate to your wallet app, it might try to execute the transaction locally if the request asks it to.

The purpose of this extra step is to keep the full node up to date as much as possible, especially when the wallet app frequently hits the same full node. For high-frequency applications, such as gaming, this could be important.

When a dApp constructs a transaction, it typically requests that the full node choose a gas object for it. Gas objects are owned objects, meaning that if the full node is stale and not aware of the right version of the object, it could lead to invalid transactions, or worse, client equivocation if the client software does not handle it properly. Executing on full node before returning the effects certificate is one way to avoid this situation. A request can ask for such behavior by using the WaitForLocalExecution parameter. See Sponsored Transactions for more on client equivocation.

Using WaitForLocalExecution is not always the best choice, however. For this coffee payment, it adds latency without significant benefits. In this case, using the WaitForEffects parameter instead provides slightly shorter user-perceived latency.