Teach papi to read a Quantus block header, and to hash one #4
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Blocks everything else here. Until papi can read a header,
runtime$never emits,Subscribenever renders, and the console shows a splash that eventually gives up. Evidence and the full diagnosis are on #1; this issue is the decision and the work.The two problems
1. The header layout.
qp_header::Headeris notsp_runtime::generic::Header:Confirmed byte-exact against mainnet block 53845. papi's
blockHeaderin@polkadot-api/substrate-bindingsreadsnumberas a Compact, which consumes 2 bytes where 4 were written; everything after shifts and the digest vector dies on an unknown variant index.2. The block hash.
getHasherFromHeaderfinds the chain's hasher by searching for one whereh(rawHeader) === blockHash. On Quantus none exists — the block hash is Poseidon over a felt-aligned preimage the header constructs itself, not a byte-hash of the SCALE encoding.qp-poseidon-corehas the implementation;@quantus/cryptoalready ships it compiled to WASM.The design question
blockHeaderis a module-level codec insubstrate-bindings, shared by every chain in the console, and the console is deliberately multi-chain — the Substrate networks are kept precisely so a signature working on both proves the signer patch widened a check rather than broke one. So neither problem can be fixed by redefining a global.Three options, roughly in increasing order of cost and honesty:
blockHeader. Decode with the Substrate layout, re-encode, and accept only if the bytes come back identical; otherwise try the Quantus layout under the same rule. This is the rule@quantus/codecalready applies to caller-supplied extension bytes, and a full-consumption check is a strong discriminator rather than a guess. Cheapest. Does nothing for the hasher.patches/exists to avoid.Option 1 plus a Poseidon entry in the hasher list may be enough: the hasher list is already a search, so adding a Quantus hasher that the search can find is in the grain of the existing design rather than against it. Worth trying first, precisely because it does not require the console to know which chain it is on.
Worth checking before starting
getHasherFromHeader's signature (header, blockHash) is sufficient, but a hasher that must be told the layout is not a drop-in for that search.@quantus/crypto's Poseidon surface covers this. It exposesext_poseidon_hashfor account derivation; the header preimage is a different construction over the same primitive, and the crate may need a second export.archive.jsdecodes headers too (map(blockHeader[1])).Acceptance
The console connects to Quantus mainnet, lists blocks in the explorer, and the block hashes it computes match the ones the node reports. Then quantus/extension#7 tier 3's two remaining boxes — listing extension accounts, and signing a transfer that lands in a block — become reachable.