Trigger warning! This blog post is going to dig into one of the most irritating issues plaguing the Solana developer ecosystem...

"Transaction was not confirmed in 30.00 seconds. It is unknown if it succeeded or failed.”

Problems related to transaction confirmation and expiration have long been a frustrating fact of life for Solana developers and users alike. I hope that after this post you will be able to understand how to fix common issues and apply best practices to avoid future headaches.

As always, feel free to jump around:

Background Info

Let’s first make sure we’re all on the same page and thinking about the same things...

What is a Transaction?

Transactions consist of two components: a message and a list of signatures. The transaction message is where the magic happens and at a high level it consists of three components: a list of instructions to invoke, a list of accounts to load, and a “recent blockhash.” In this blog post, we’re going to focusing a lot on a transaction’s recent blockhash because it plays a big role in transaction confirmation.

Transaction lifecycle refresher

Below is a high level view of the lifecycle of a transaction. This blog post will touch on everything except steps 1 and 4.

  1. Create a list of instructions along with the list of accounts that instructions need to read and write
  2. Fetch a recent blockhash and use it to prepare a transaction message
  3. Simulate the transaction to ensure it behaves as expected
  4. Prompt user to sign the prepared transaction message with their private key
  5. Send the transaction to an RPC node which attempts to forward it to the current block producer
  6. Hope that a block producer validates and commits the transaction into their produced block
  7. Confirm the transaction has either been included in a block or detect when it has expired

What is a Blockhash?

A “blockhash” refers to the last Proof of History (PoH) hash for a “slot” (description below). Since Solana uses PoH as a trusted clock, a transaction’s recent blockhash can be thought of as a timestamp!