paritytech / paritytech/subxt

Expose parent hash on the Config::Header trait (parent_hash())

Open
#2,242 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
489
Forks
293
Avg merge
18h 35m
Merged PRs (30d)
3

Description

Summary

The Config::Header trait only exposes number(). There's no way to read a
header's parent hash generically over T::Header — it's only available as a
public field on the concrete SubstrateHeader. I'd like to propose adding a
parent_hash() accessor (plus an associated hash type) to the trait.

What I was building / why I hit this

I'm building a Rust, code-first Substrate indexer framework on top of subxt
(kunal171/subdex). To stay reorg-safe,
the indexer validates chain continuity by comparing each incoming block's
parent_hash against the hash it stored for the previous height; on a mismatch it
rolls back and re-syncs the corrected chain.

I wanted the ingestion layer to be generic over subxt::Config (so it works for
any chain): client.blocks()block.header()T::Header. But:

fn parent_of<T: subxt::Config>(h: &T::Header) -> ??? {
    // not possible — Header only exposes number()
}

The only workaround is to abandon the generic abstraction and hard-code a concrete
config (e.g. PolkadotConfig) so I can touch SubstrateHeader's parent_hash
field directly — which defeats the purpose of Config being generic and is awkward
for any tool that wants to support arbitrary chains.

Current state
pub trait Header: Sized + Encode + Decode + Debug + Sync + Send + DeserializeOwned + Clone {
    fn number(&self) -> u64;
}

number() is exposed, but parent_hash (which every Substrate header carries,
right next to the number) is not.

Proposed change

Add an associated hash type + accessor:

pub trait Header: ... {
    type Hash: Hash;
    fn number(&self) -> u64;
    fn parent_hash(&self) -> Self::Hash;
}

implemented for SubstrateHeader<H> as type Hash = H, returning the existing
field (Hash already requires Copy, so it's a by-value return).

This is a breaking trait change (external Header impls would need to add the
associated type + method), but it's small and SubstrateHeader is the only in-repo
implementor. I'm also open to alternatives — e.g. tying the hash type to
Config::Hasher instead of a new associated type — whichever you prefer.

Status

I have a working implementation that passes cargo check --workspace --exclude test-runtime and cargo test -p subxt --lib (30 passed). The only failing doctest
(runtime_path field in subxt/src/lib.rs) fails identically on current master,
so it's pre-existing and unrelated.

Happy to open a PR shortly once there's agreement on the API shape. Would a
contribution along these lines be welcome?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the Config::Header trait and its SubstrateHeader implementation, then review the proposed associated Hash type and parent_hash() API. Run cargo check --workspace --exclude test-runtime and cargo test -p subxt --lib; done means the API decision is accepted, the in-repo implementation works, and the existing runtime_path doctest remains understood as unrelated.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api, backend-api-design
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.