# Deep Research Prompt — XDC 2.6.8 vs GP5 Full Parity (V2 Switch + Block Minting)

**Use with:** `claude -p --model claude-opus-4-7` (or any deep-thinking session)
**Expected runtime:** multi-hour, single deliverable
**Supersedes:** `DEEP_RESEARCH_PROMPT_V2_SWITCH_PARITY.md` (read-only / sync-side scope) — extends it to include block production
**Companion documents** (read these first to ground the agent):
- `CONSENSUS_PARITY_AUDIT_v2.md` (current authoritative parity audit, 663 lines)
- `GP5_V268_PHASE_AUDIT.md` (8-phase structured audit, 1,380 lines)
- `V2_SWITCH_PARITY_REPORT.md` (older — partially stale, retained for lineage)
- `OPUS_4.7_ANALYSIS_ISSUE_391.md` (root cause for issue #391)
- `gp5_consensus_review.md` (older — partially stale)
- `.pr-reviews/batch_summary_2026-04-25.md` (most recent PR batch findings on PRs #411-#419)
- `VALIDATION_PLAYBOOK.md` (Stages 1-4)
- `skills/consensus-parity-{audit,review,fix}/profiles/xdpos-gp5-v268.md` (project profile, paths, fixtures)

---

## Mission

Produce a complete, evidence-backed comparison of XDPoS V2 consensus behavior between two codebases — **across both sync and mining paths** — so that GP5 can be deployed as a peer that is byte-identical to XDC 2.6.8 for receiving, validating, AND producing blocks at and around the V1→V2 switch boundary and onward.

The earlier research established read-side parity (block import, snapshot reconstruction, header verification). This expanded research must establish **producer-side parity**: when GP5 mines, does it produce a block that v2.6.8 peers accept byte-for-byte? When GP5 votes / forms QCs / handles timeouts, does the BFT consensus loop converge identically to a v2.6.8 leader's loop?

The output must be actionable: every divergence classified, fix patches drafted where possible, and a validation plan that exercises both sync AND mining paths against real chain artifacts.

## Codebases

- **Reference (immutable):** `/Users/anilchinchawale/github/XDCNetwork/XDPoSChain` — XDC 2.6.8 source. Treat as the canon for both sync AND mining behavior.
- **Patient:** `/Users/anilchinchawale/github/XDCNetwork/XDC-Geth` branch `xdc-network` — GP5 (geth 1.17 + XDPoS port). Local path's folder name (`XDCNetwork/XDC-Geth`) does not match the GitHub remote (`XDCIndia/go-ethereum`); don't try to clone fresh from `XDCNetwork`.

The cross-reference rule applies to every claim about GP5: cite the equivalent `path:line` in v2.6.8.

## Definition of "100% compatible — sync and mine"

Two equivalence properties, both must hold over `[V2.SwitchBlock - Gap, V2.SwitchBlock + 3*Epoch]` at minimum, longer if the project decides:

### Sync equivalence (already partially verified)
GP5, given the canonical block stream produced by v2.6.8 nodes, produces:
- Identical block hashes
- Identical state roots
- Identical receipts roots
- Identical XDPoS snapshots (pebble keys + values)
- Identical accept/reject decisions for any input header

across bulk sync, cold-snapshot restore, and live re-org paths.

### Mining equivalence (new — what this research adds)
A GP5 node configured with the same signer key, same chain state, and same network conditions as a v2.6.8 node produces:
- Byte-identical block headers (every field including Validator signature, Penalties list ordering, Validators field encoding, Time, GasLimit, GasUsed, ParentHash, MixDigest, Nonce, Coinbase)
- Byte-identical block bodies given the same transaction pool ordering
- Byte-identical state roots for any block GP5 produces (depends on Author dispatch, fee routing, reward distribution, penalty computation)
- Byte-identical vote / QC / timeout / propose messages over peer protocol
- Identical leader-selection decisions given the same round number and active masternode set
- Identical epoch-switch detection given the same parent header

A v2.6.8 peer receiving a block GP5 just mined must accept it. A v2.6.8 peer receiving a vote GP5 just signed must aggregate it correctly. Two GP5 nodes with the same key cannot disagree with each other or with v2.6.8 peers about whether their own block is canonical.

**This is a strictly stronger property than sync equivalence.** A GP5 client can be a passable sync peer while still being a broken miner — and that's the most likely current state given the audit's NF-0 / NF-1 / NF-2 / NF-3 findings. The audit captured those findings from the perspective of "GP5 reads blocks correctly"; this research must check them again from "GP5 writes blocks correctly".

## Scope of comparison

In addition to the original 8 phases, this research must cover four new phases (9-12) that center on mining and BFT loop logic. The original 8 phases must be re-verified against current HEAD (`git log -1` to confirm SHA), since multiple PRs have landed since the prior audit.

### Original phases (re-verify)

1. **Snapshot bootstrap & masternode extraction** — re-verify against current HEAD. Recent PR #411 (C1.1 walk-back) and the rejected PRs #417/#418 touch this surface.
2. **sigHash / ecrecover / RLP encoding** — re-verify NF-0 status (Author dispatch). PR #414 attempted to land NF-0; verify it actually does.
3. **Epoch switch detection & gap-number math**
4. **Snapshot serialization & repair**
5. **Penalty / reward hooks** — NF-2 and NF-3 attempted in PR #414; C-comeback attempted in PR #416 with a known iteration-order bug. Re-verify all three against current HEAD post-merge.
6. **Gas-limit verification** — C5 fix already landed (`c45ecd863`); verify still in place.
7. **Header validation & wrapper dispatch (read-side)** — `VerifyHeader`, `VerifyHeaders`, `VerifyUncles`, `VerifySeal`. NF-0 (Author dispatch) was the read-side wrapper finding.
8. **Sync & downloader**

### New phases (mining-side)

9. **Wrapper dispatch (mining-side methods)** — `Prepare`, `FinalizeAndAssemble`, `Seal`, `CalcDifficulty`, `SealHash`, `Authorize`. Each must dispatch by `BlockConsensusVersion(header.Number)` for V2 blocks. The original audit confirmed `VerifyHeader` dispatches but flagged `Author` and `Finalize` as missing dispatch — the mining-side equivalents likely have the same problem and were never checked. Mining cannot work correctly without these.

10. **BFT consensus loop** — the V2 engine implements a HotStuff-like protocol on top of the chain. Compare round handling (`GetRoundNumber`, `getEpochSwitchInfo`, leader rotation logic), vote handling (`OnVote`, `aggregator`, signature aggregation), QC formation (`onMajority`, `propose`, `seal`), timeout messages (`OnTimeout`, `TC` formation, `onTC`), and the proposer-rotation function that picks the leader for round R given epoch's masternodes. v2.6.8's V2 engine in `consensus/XDPoS/engines/engine_v2/` is the source of truth for this loop. GP5's V2 engine should be byte-equivalent in message format and round-by-round behavior.

11. **Worker / miner integration** — `miner/worker.go` (or equivalent) must call the right consensus methods at the right time. Specifically: when this node is the proposer for round R, the worker calls `Prepare` → tx execution → `FinalizeAndAssemble` → `Seal`. The Seal call computes the sigHash, signs with the configured signer, and assembles the final block. Compare the call chain in both repos. Special attention to: when does the worker decide this node is the proposer? Does it match v2.6.8's `am_i_leader(round, masternodes)` logic? Does the timeout-when-not-leader path match?

12. **Network propagation (P2P consensus messages)** — vote, propose, timeout, sync-info messages over devp2p. v2.6.8 uses XDC-specific message types in `eth/protocols/eth/` or similar. GP5 must use byte-identical wire formats so v2.6.8 peers can parse GP5's votes and aggregate them into QCs. Differences in even one field's RLP layout break the BFT loop across mixed peer sets.

## In-scope files (file-by-file under `consensus/XDPoS/`, `eth/`, `miner/`, `core/`)

### Read-side (re-audit; mostly covered earlier)
- `consensus/XDPoS/xdpos.go` — wrapper dispatch
- `consensus/XDPoS/engines/engine_v2/engine.go` — `Author`, `VerifyHeader`, `getSnapshot`, `repairSnapshot`, `calcMasternodes`, `GetMasternodesFromEpochSwitchHeader`, `getEpochSwitchInfo`
- `consensus/XDPoS/engines/engine_v2/verifyHeader.go`
- `consensus/XDPoS/engines/engine_v2/snapshot.go`
- `consensus/XDPoS/engines/engine_v2/utils.go` — sigHash, ecrecover
- `consensus/XDPoS/engines/engine_v2/epochSwitch.go`

### Mining-side (new audit)
- `consensus/XDPoS/xdpos.go` — `Prepare`, `Finalize`, `FinalizeAndAssemble`, `Seal`, `CalcDifficulty`, `SealHash`, `Authorize` wrapper methods. Confirm each dispatches by `BlockConsensusVersion`. Audit phase 9.
- `consensus/XDPoS/engines/engine_v2/engine.go` — V2-engine implementations of `Prepare`, `FinalizeAndAssemble`, `Seal`, `Authorize`. Compare to v2.6.8's V2 engine.
- `consensus/XDPoS/engines/engine_v2/timeout.go` — timeout / TC / round-advance logic. Audit phase 10.
- `consensus/XDPoS/engines/engine_v2/vote.go` — vote handling, signature aggregation, QC formation. Audit phase 10.
- `consensus/XDPoS/engines/engine_v2/forensics.go` — forensic detection of byzantine behavior; affects vote validation.
- `consensus/XDPoS/engines/engine_v2/mining.go` (if exists) — miner-specific helpers.
- `eth/hooks/hooks.go`, `eth/hooks/engine_v2_hooks.go` — `HookReward`, `HookPenalty`, `HookValidator` (write-side: when the miner produces a block at an epoch switch, these hooks compute the Validators and Penalties fields).
- `miner/worker.go` (or equivalent in geth 1.17) — when does this node mine, what does it pass to the engine?
- `eth/handler.go`, `eth/protocols/eth/protocol.go` — peer protocol message types and codec for vote/propose/timeout messages. Audit phase 12.
- `eth/protocols/eth/handshake.go` — initial peer-version negotiation; affects whether v2.6.8 peers and GP5 peers form a connection at all.
- `core/types/block.go` — header type, RLP encoding, field semantics. Already in scope; re-verify any changes since the prior audit.
- `core/state_transition.go` — fee routing (where `Author(header)` result becomes coinbase for fees). Mining must produce fee-routing identical to what v2.6.8 peers compute when they verify the block.

## Known divergences (starting points; verify each against current HEAD)

This list is curated from the prior audits + recent PR reviews. Re-verify each against current HEAD. Some are fixed (mark as "verified fixed in commit X"), some are partially fixed, some are still open, some may have regressed.

### Fixed (verify still in place)
- **C5** — gas-limit bound 1/1024 (commit `c45ecd863`). Verify `verifyHeader.go:64-72` still uses `params.GasLimitBoundDivisor`.
- **C2** — `repairSnapshot` LRU race (commit `7277ad8c9`). Verify `currentSnap` seed at `engine.go:826-832` is still removed.
- **C1** — cold-restore walk-back retry (commit `2b1664f0d`). Verify `engine.go:355-385` walk-back is in place.
- **C1.1 (PR #411)** — walk-back guard `>` → `>=`. Confirm landed and `gofmt`'d.
- **#395 / Validators-vs-Extra at switch block** — fixed pre-audit; verify `engine.go:868-870` and `engine.go:1108-1115` still route through `decodeMasternodesFromHeaderExtra`.

### Open (most recently reviewed, status TBD)
- **NF-0 / C10 (Author dispatch)** — PR #414 attempted; verify against current HEAD.
- **NF-1 / C6 (Finalize dispatch)** — PR #414 partial (gating only). Confirm whether the "architectural full delegation" deferred work is acceptable or still a divergence.
- **NF-2 / C7 (HookPenalty boundary)** — PR #414 attempted; verify.
- **NF-3 / C8 (HookPenalty preMasternodes)** — PR #414 attempted; verify. Watch the defensive fallback at hooks.go:111-112 for silent NF-3 reintroduction.
- **C-comeback / C13 (HookPenalty comeback seeding)** — NOT in PR #414. PR #416 attempted with byte-parity bug (iteration order). State as of audit: open with a rejected attempt.
- **C14 (V1 pre-switch header guard)** — PR #416 attempted; verify the fail-loud guard at `engine.go:868-877`.
- **Genesis hash placeholder** — `params/config.go:40`. Verify whether it's been replaced with the real Apothem genesis `0xbdea512b4f12ff1135ec92c00dc047ffb93890c2ea1aa0eefe9b013d80640075`.
- **V1 HookValidator (issue #72)** — `eth/hooks/hooks.go` lacks IPC wiring for the M2 randomization contract. Reference v2.6.8 `eth/hooks/engine_v1_hooks.go:179-188` calls IPC. Critical for V1 mining; out of scope for V2-only deployments.

### New for mining (likely-divergent areas, must be checked)
- **Wrapper `Prepare` dispatch** — does it dispatch to V2 engine for V2 blocks? Or call V1 logic regardless?
- **Wrapper `FinalizeAndAssemble` dispatch** — same question. State-root computation depends on this.
- **Wrapper `Seal` dispatch** — sigHash computation depends on this.
- **Wrapper `CalcDifficulty` dispatch** — V2 difficulty is leader-index-based; V1 is signer-rotation-based. Mining must use the right one.
- **Wrapper `SealHash` dispatch** — what hash does the miner sign? If wrapper SealHash uses the wrong field set, mining produces unverifiable signatures.
- **`Authorize` wrapper** — sets the mining identity. Both V1 and V2 engines have their own Authorize. Wrapper must route the configured signer to both, or to whichever is active.
- **Worker proposer-selection** — when does the GP5 worker decide to mine? Compare to v2.6.8's `am_i_leader` / `getProposer` logic. This is in `miner/worker.go` or `consensus/XDPoS/engines/engine_v2/engine.go` mining helpers.
- **Vote/QC/timeout message wire format** — RLP fields, ordering, signature placement. Any byte-level difference breaks BFT across mixed peer sets.

## Required deliverables

For each in-scope phase, produce:

### A. Function-by-function delta table (extended)

Cover all phases 1-12. Include both read-side and write-side functions. Format:

| Function | v2.6.8 location | GP5 location | Behavior delta | Classification |

Classifications: `aligned` / `intentional-divergence` / `bug` / `missing-in-v2.6.8` / `missing-in-patient` / `regression` / `INVESTIGATE`. See `skills/consensus-parity-audit/references/classification.md`.

### B. Per-divergence dossier

For every non-aligned row: what / why / consensus impact / hash-divergence test / recommended action. Phase 9-12 dossiers should explicitly distinguish read-side impact ("does this break sync?") from write-side impact ("does this break mining?") because some bugs only surface in one mode.

### C. Mining-specific RLP and byte-layout audit

The original Stage 1 covers chain hash equivalence on replay. For mining, additionally audit:

- **Block header bytes for any block GP5 produces** — given a known parent header and a known transaction set, compute the block GP5 would produce vs the block v2.6.8 would produce. Must be byte-identical including signature bytes (which depend on sigHash, sign function, and signer key — control all three).
- **Vote / propose / timeout message bytes** — given a known QC + round number + signer key, the message GP5 sends vs the message v2.6.8 sends. Must be byte-identical at RLP level. Use a known-state fixture.
- **State-root contributors per block** — fee routing, reward distribution, penalty list serialization. State root divergence is invisible in passing tests but breaks consensus on the next block.

### D. BFT loop trace comparison

Trace a single round of BFT consensus through both clients with synthetic inputs:

1. Round R starts; both clients see the same vote-set and QC.
2. Round-R proposer is computed; assert both pick the same address.
3. The proposer (one client at a time) produces a block; assert the resulting block is byte-identical when produced by v2.6.8 vs by GP5 (this is the hard test — set up GP5 with the same key as v2.6.8, drive both with the same parent state, expect identical output).
4. Validators send votes; assert vote messages are byte-identical and aggregate identically into a QC.
5. QC is broadcast; assert both clients commit the same block at the same time.
6. Round R+1 starts; assert both advance round identically.

Document any step where the trace diverges, even if the divergence is "GP5 advances the round one tick later than v2.6.8 because of a different timer source." Timer-related divergences don't break consensus directly but can cause systematic round-leader misalignment if patient and reference miners are deployed simultaneously.

### E. Validation plan (extends original Stages 1-4 with new Stage 5+)

The original four stages cover sync. For mining parity, add:

#### Stage 5 — Mining shadow test (paired miners)

**Goal:** confirm GP5 and v2.6.8, configured with the same key and pointed at the same parent state, produce byte-identical blocks.

**Setup:**
1. Spin up a private testnet with at least 4 validators total, using the Apothem genesis.
2. Two of the validators run patient binary (GP5); two run reference (v2.6.8).
3. All four are configured to be eligible proposers for the same epoch.
4. Same RNG seed for any non-deterministic decision (timer randomization, peer selection); ideally control any randomness sources or document them.

**Procedure:**
1. Drive the network past the V1→V2 switch.
2. For each round, log the proposer, the produced block, and the vote/QC messages.
3. When a GP5 node is the proposer for round R, capture the produced block bytes. When a v2.6.8 node is the proposer for round R+1 (or some later round), capture that produced block bytes.
4. To get directly comparable outputs, deploy a special harness: take a v2.6.8 node and a GP5 node, both configured with the same key, point them at the same parent state, ask both to "mine round R now". Compare the produced blocks byte-by-byte.

**Pass criteria:**
- For any round R where both clients can be made to produce a block with the same parent + key + tx set, the block bytes are equal.
- Vote/QC/timeout messages produced by GP5 are accepted and aggregated by v2.6.8 nodes.
- The chain advances continuously with mixed proposer types; no round stalls because of GP5-produced messages being rejected.

**Diagnostic on failure:** capture the diverging block. Bisect by removing fields from the comparison: do the headers match? If yes but bodies don't, fee routing or tx ordering differs. If headers don't match, is it the signature byte (sigHash bug) or the body fields (Validators, Penalties, Coinbase, Time)?

#### Stage 6 — Mixed-peer canary

**Goal:** confirm v2.6.8 and GP5 nodes can run as peers on the same network without forking.

**Setup:**
1. Apothem mainnet observer mode (read-only initially), with two extra nodes added: one GP5, one v2.6.8.
2. Don't enable mining on either for the first phase; confirm both stay synced.
3. Phase two: enable mining on the GP5 node with a registered masternode key; observe whether v2.6.8 peers accept the produced blocks.

**Pass criteria:**
- Phase 1: zero divergence between GP5 and v2.6.8 in canonical-chain hash for ≥10,000 blocks.
- Phase 2: every block GP5 produces is accepted into the canonical chain by v2.6.8 peers; zero "validators not legit" / "invalid difficulty" / "bad seal" rejections from v2.6.8 peers' point of view.
- The masternode rotation continues correctly when GP5 is the proposer; the next v2.6.8-proposed block builds on GP5's block without any reorg.

### F. Open questions (extended)

The original prompt's Section F captured runtime-only questions for sync (e.g., "what's in the production cold-snapshot tarball's pebble keys?"). For mining, add:

- **What randomness sources does the V2 BFT loop use?** Round timers, peer selection in vote propagation, etc. If GP5 and v2.6.8 use different randomness, two miners with the same key will not produce identical messages.
- **What is the exact tx ordering policy for GP5's worker vs v2.6.8's miner?** Geth 1.17 has a different tx-pool implementation than the legacy XDC fork; ordering can differ even for the same input set.
- **Does v2.6.8 mainnet have any non-canonical signed messages floating around** (e.g., signed votes that don't match the standard sigHash) that GP5 must accept for backward compat? If yes, GP5's verify logic needs to accept these even though it shouldn't produce them.
- **Are there any consensus-impacting fields in V2 messages that change between protocol versions?** GP5 may inherit a newer geth devp2p version that handles message framing differently.

## Constraints

- Cite exact `path:line` in BOTH repos for every claim.
- Don't reuse text from prior audits verbatim. Re-verify every claim against current HEAD; if the prior claim is now wrong (commits landed since), say so explicitly.
- Don't classify a divergence as a bug without showing the consensus-impact path. Mining-side bugs are especially easy to misclassify because they don't surface in static replay.
- For mining-side findings, distinguish between "the patient produces wrong blocks (other peers reject)" and "the patient accepts wrong blocks from other peers (reference would reject)". Both are bugs but they have different urgency depending on the deployment plan.
- Trust no commit message; verify the diff. The recent PR review batch found three PRs whose commit messages overstated the actual diff (PR #417, #418, #419). Apply that lesson here.
- For mining-side claims that depend on runtime (timer behavior, randomness, tx ordering), explicitly mark them `INVESTIGATE` with the concrete runtime evidence that would resolve. Static code analysis alone cannot answer some mining questions.
- Issue #72 (V1 HookValidator IPC) is out of scope for V2-only deployments. Only flag it if the project plans to fork a fresh chain that goes through V1 → V2 transition.

## Style

Audience is the XDC core team plus future maintainers. Write the report so a reviewer can audit the conclusions in a long afternoon without rerunning the analysis. Specificity > concision; cite line numbers ruthlessly; explain the why behind each classification. If a finding's impact is conditional ("only triggers when GP5 is the proposer; only matters once GP5 is registered as a masternode on mainnet"), say so explicitly.

Prose for analysis sections (lots of conditional reasoning); tables for delta surfaces (lots of structural comparison). Code blocks for every patch; inline comments when the patch isn't self-evident.

## Final output

Single markdown file: `CONSENSUS_PARITY_AUDIT_v3.md` in the patient repo root. Lead with an executive summary that answers two questions:

1. *"If we ran GP5 on Apothem from `V2.SwitchBlock - Gap` today as a sync peer, would it agree with v2.6.8 on every block?"* (sync equivalence — should be mostly resolved by current HEAD)

2. *"If we ran GP5 on Apothem from `V2.SwitchBlock + 100*Epoch` today as a registered miner, would it produce blocks v2.6.8 peers accept?"* (mining equivalence — likely NO until NF-0/C-comeback land plus the new mining-side findings from this research)

The report should explicitly supersede `CONSENSUS_PARITY_AUDIT_v2.md` and the older parity reports, with a cross-reference table showing which prior findings are still open, which are now closed, and which were re-classified.

## Companion deliverable

Update `VALIDATION_PLAYBOOK.md` (or produce `VALIDATION_PLAYBOOK_v2.md`) with concrete commands for Stages 5 and 6. The new stages need:

- A test-network composition recipe (how many validators, which keys, what genesis).
- The deterministic-mining harness command for Stage 5 step 4 (drive both clients to mine a single round with identical inputs).
- A Stage 6 canary deployment runbook for xdc07.

Both deliverables (audit + playbook) should reference each other; the audit's findings list should map directly to the playbook's pass/fail criteria, so an operator can run the playbook to confirm or refute the audit's claims.
