BlockDeep Labs

At BlockDeep Labs, we’re dedicated to empowering businesses to harness the full potential of decentralized technologies. We specialize in premium services spanning blockchain solution development, architecture design, and advisory.

Follow publication

Inside The Polkadot PoV: A Deep Dive

BlockDeep Team
BlockDeep Labs
Published in
4 min readMar 12, 2025

In Polkadot, scalability and security are achieved by connecting specialized parachains to a relay chain. One of the key components that enables this security model is the Proof-of-Validity (PoV). In this blog post, we’ll explore what PoV is, why it’s needed, and how it is generated.

What is PoV?

Proof-of-Validity (PoV) is a package of data produced by a parachain collator that contains everything necessary for relay chain validators to verify the correctness of a parachain’s state transition. A PoV includes:

  • Block Header: The block header metadata (state root, extrinsics root, etc.) is essential for verification.
  • Extrinsics: The list of transactions or operations executed in the parachain block.
  • Storage Proof (Compact Proof): A minimal set of trie nodes (both those that were directly accessed and the necessary siblings) that prove the state changes. This proof allows anyone to reconstruct the relevant part of the Merkle trie and verify that the new state root is correct.

Why is PoV Needed?

Polkadot’s relay chain does not store or process the entire state of each parachain. Instead, it relies on parachains to provide proof that the state transition (triggered by executing the block’s transactions) is valid. Here’s why PoV is essential:

  • Security Without Storing Full State:
    Validators on the relay chain only hold a commitment (the state root) to the parachain’s state. The PoV lets them verify that the parachain block correctly transitions from this known previous state without having to store or process the entire state.
  • Efficient Verification:
    The PoV bundles a compact storage proof, ensuring validators have enough information to reconstruct the relevant parts of the Merkle trie and recompute the new state root. This efficient mechanism minimizes bandwidth and computation, which is crucial for scalability.

PoV Computation: A Step-by-Step Process

Let’s take a detailed look at how the PoV is generated at the parachain side:

1. Block Execution with Instrumented Storage

When a collator produces a new parachain block, the block’s execution environment is “instrumented” to record all storage accesses. Here’s what happens:

  • Instrumented Trie Backend: Before execution begins, the node wraps its underlying trie backend with a recorder.
let proving_backend = TrieBackendBuilder::wrap(trie_backend)
.with_recorder(Default::default())
.build();
  • This recorder intercepts every storage read and write. In simple terms, whenever the runtime requests a storage node, the recorder “catches” the call, logs the node and then passes it back.
  • Recording Storage Accesses: As the parachain runtime executes each extrinsic (transaction), the instrumented storage layer intercepts the calls. The recorder logs:
    Directly Accessed Nodes: Nodes along the path from the root to the leaf that are read or modified.
    Sibling Nodes: Additional nodes required to reconstruct the Merkle branch from a leaf to the root.

2. Extracting the Raw Storage Proof

After block execution completes, the recorder holds a log of all the nodes needed to prove the state transition. The next step is to extract these nodes into a raw StorageProof.

  • Extraction Process: The proving backend calls a function as shown below:
let proof = proving_backend.extract_proof()
.expect("Recorder was set, so proof can be extracted");
  • This function gathers the recorded nodes (both accessed and sibling nodes) and packages them into a StorageProof object.
  • Proof Contents: The raw proof is not a dump of the entire state but only the subset of nodes required to rebuild the affected portions of the Merkle trie.

3. Composing the Parachain Candidate and PoV

With the raw storage proof in hand, the collator continues its block production.

  • Attaching the Proof: The block (which includes the header and extrinsics) and the raw storage proof are combined into a ParachainCandidate.
Ok(Some(ParachainCandidate { block, proof: proposal.proof }))
  • Compacting the Proof: Before the candidate is forwarded, the raw proof is compacted:
let compact_proof = 
candidate.proof.into_compact_proof::<HashingFor<Block>>(*parent_header.state_root())?;
  • This compact proof is then embedded in a ParachainBlockData structure alongside the header and extrinsics.
let block_data = 
ParachainBlockData::<Block>::new(header, extrinsics, compact_proof);
  • Creating the Final PoV: Finally, the ParachainBlockData is encoded and further compressed into the final PoV block. This PoV block is what gets submitted (as part of a collation) to the relay chain validators.
let pov = polkadot_node_primitives::maybe_compress_pov(PoV {
block_data: BlockData(block_data.encode()),
});

PoV Validation On Relay Chain

The relay chain does not store the entire parachain state; instead, it only stores a commitment in the form of the state root. When a new parachain block is sent to the relay chain, it comes with a PoV containing the block header, extrinsics, and a compact storage proof (as described above). Relay Chain validators use the compact proof to reconstruct only the affected portions of the parachain’s Merkle trie. Using the reconstructed trie, validators re-execute the parachain block against the PoV. Finally, they compare this computed state root with the one declared in the block header. If these state roots match, the parachain block is validated; if not, it is rejected. This mechanism allows validators to efficiently verify state transitions without needing to store the full parachain state.

Conclusion

PoV (Proof-of-Validity) is a cornerstone of Polkadot’s shared security model. It enables parachains to prove that their state transitions are valid without burdening the relay chain with full state storage. By recording only the accessed trie nodes during block execution, extracting a compact proof, and then using that proof to reconstruct and verify the new state, the system achieves efficient and scalable validation. This intricate process — spanning from the recording of storage accesses to the final verification by relay chain validators — ensures that every parachain block meets the rigorous standards required for secure interoperability within the Polkadot ecosystem.

Connect with us

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in BlockDeep Labs

At BlockDeep Labs, we’re dedicated to empowering businesses to harness the full potential of decentralized technologies. We specialize in premium services spanning blockchain solution development, architecture design, and advisory.

Written by BlockDeep Team

At BlockDeep Labs, we're dedicated to empowering businesses to harness the full potential of decentralized technologies.

No responses yet

Write a response