Proof of History (PoH)
A verifiable clock and its role in ordering. This guide targets Agave 4.1.1 validators, Solana CLI 3.0.10, Anchor 0.32.1, and @solana/kit 7.0.0 clients.
Recipe
Quick-reference recipe card.
solana config set --url devnet
solana balanceimport { createSolanaRpc } from "@solana/kit";
const rpc = createSolanaRpc("https://api.devnet.solana.com");When to reach for this:
- Implementing or debugging proof of history (poh) in production paths
- Teaching the concept to engineers new to Solana
- Auditing whether your stack matches Agave 4.1 era behavior
Working Example
import { createSolanaRpc, address } from "@solana/kit";
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const slot = await rpc.getSlot().send();
const sig = "PASTE_SIGNATURE_AFTER_YOUR_TX";
const tx = await rpc
.getTransaction(sig, { encoding: "json", maxSupportedTransactionVersion: 0 })
.send();
console.log({ slot, err: tx?.meta?.err, cu: tx?.meta?.computeUnitsConsumed });use anchor_lang::prelude::*;
#[program]
pub mod demo {
use super::*;
pub fn log_slot(_ctx: Context<LogSlot>) -> Result<()> {
let clock = Clock::get()?;
msg!("slot: {}", clock.slot);
Ok(())
}
}
#[derive(Accounts)]
pub struct LogSlot {}What this demonstrates:
- RPC access patterns with @solana/kit 7.0.0
- Reading execution metadata (errors, CU) from confirmed transactions
- On-chain sysvar access in Anchor 0.32.1 programs
Deep Dive
How It Works
- A verifiable clock and its role in ordering.
- Solana's account model requires explicit account lists per instruction
- Sealevel executes non-conflicting transactions in parallel
Agave 4.1.1 Notes
- Confirmation semantics follow TowerBFT voting with PoH ordering
- Alpenglow (Votor + Rotor) is rolling out for faster finality - see Consensus section
- Local development: Surfpool 0.12.0 and LiteSVM 0.6.x
Rust Notes
// Use checked math and explicit constraints in programs
require!(amount > 0, MyError::InvalidAmount);Gotchas
- Legacy web3.js v1 snippets - API differs from Kit. Fix: use @solana/kit 7.0.0.
- Wrong cluster - devnet vs mainnet mismatch. Fix: align CLI, RPC, wallet, explorer.
- Float SOL amounts - precision loss. Fix: bigint lamports end-to-end.
- Expired blockhash - dropped txs. Fix: re-fetch blockhash and re-sign.
- Insufficient CU - OOM or budget exceeded. Fix: optimize program + set Compute Budget.
- Missing owner checks - writable account exploits. Fix: Anchor constraints on every mut account.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| @solana/kit 7.0.0 | New TypeScript clients | Maintaining legacy code temporarily |
| Solana CLI 3.0.10 | Ops and quick probes | Production transaction signing at scale |
| Surfpool 0.12.0 | Anchor integration tests | Production deployment |
| LiteSVM 0.6.x | Fast unit tests | Full network behavior validation |
FAQs
How does this apply on Agave 4.1.1?
Agave 4.1.1 leaders embed PoH hashes in blocks so validators agree on transaction order before TowerBFT votes.
What Solana CLI version should I use?
Use Solana CLI 3.0.10, which pairs with Agave 4.1.1. Install with agave-install init 4.1.1 (or your team's pin file), then verify with solana --version and agave-install --version.
Should I use @solana/kit or web3.js?
Use @solana/kit 7.0.0 for new TypeScript—typed RPC methods, smaller API surface, and examples on this page already use Kit. Keep web3.js only for legacy codebases; migrate RPC calls and transaction building incrementally.
What commitment level is recommended?
Use confirmed for dashboards and finalized before withdrawals or cross-system callbacks.
How do I debug related failures?
PoH issues appear as slot drift or skipped leaders—not typical program errors. Compare getBlockTime across slots when diagnosing cluster-wide ordering delays.
Does this work on devnet?
Yes—point CLI and RPC to https://api.devnet.solana.com. Behavior matches mainnet; only account data and economics differ.
How do compute units affect this?
PoH does not consume your transaction CU; it is a validator-side clock. Client impact is blockhash lifetime and slot timing.
What is the Anchor 0.32.1 pattern?
Anchor 0.32.1 uses #[program], Context<T>, and #[derive(Accounts)] with explicit mut/signer constraints—run anchor build and anchor test on 0.32.1 via avm use 0.32.1.
How do I test with Surfpool 0.12.0?
Start Surfpool 0.12.0, point RPC to its port, and run anchor test or client integration scripts against forked accounts.
Can LiteSVM 0.6.x cover this?
LiteSVM does not run PoH ticks; it executes instructions against a static ledger snapshot.
What changed in the Agave era?
The validator client rebranded to Agave (4.1.1), CLI 3.0.10 aligns with it, and Alpenglow work is changing finality—pin versions and read release notes each upgrade.
Where do I find related RPC methods?
getRecentBlockhash / getLatestBlockhash, getSlot, and getBlockTime relate client signing cadence to PoH-driven slots.
Related
- Browse other pages in the
core-architecture-componentssection for complementary topics - Solana Basics - account and transaction orientation
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.