Skip to content

Forkchoice endpoint#16862

Merged
potuz merged 3 commits into
developfrom
forkchoice_endpoint
Jun 3, 2026
Merged

Forkchoice endpoint#16862
potuz merged 3 commits into
developfrom
forkchoice_endpoint

Conversation

@potuz

@potuz potuz commented May 29, 2026

Copy link
Copy Markdown
Contributor

Track individual PTC votes on forkchoice and implement a forkchoice debug endpoint

The endpoint gives the following output

{
  "justified_checkpoint": {
    "epoch": "18",
    "root": "0xb650654c804ccd265b8154448793ffbec985f33fdeec2b1900cc49062f333cdc"
  },
  "finalized_checkpoint": {
    "epoch": "17",
    "root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72"
  },
  "fork_choice_nodes": [
  ...
      {
      "payload_status": "pending",
      "slot": "137",
      "block_root": "0xa7df2ba3728f77ac3db5e9a6e62dda229f98eb403dc19794a7002dfb8adf0da2",
      "parent_root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72",
      "weight": "51609600000000",
      "validity": "valid",
      "execution_block_hash": "0x138252140503bef2a3503d160b8181c41c5c1f3d62244fc51bdfbd2fb00f8a1c",
      "extra_data": {
        "balance": "0",
        "execution_optimistic": false,
        "timestamp": "2026-05-29 18:05:46.072764887 +0000 UTC m=+843.220895049",
        "target": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72",
        "justified_epoch": "16",
        "finalized_epoch": "15",
        "unrealized_justified_epoch": "16",
        "unrealized_finalized_epoch": "15",
        "payload_attester_count": "16",
        "payload_availability_yes_count": "16",
        "payload_data_availability_yes_count": "16"
      }
    },
    {
      "payload_status": "empty",
      "slot": "137",
      "block_root": "0xa7df2ba3728f77ac3db5e9a6e62dda229f98eb403dc19794a7002dfb8adf0da2",
      "parent_root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72",
      "weight": "0",
      "validity": "valid",
      "execution_block_hash": "0x138252140503bef2a3503d160b8181c41c5c1f3d62244fc51bdfbd2fb00f8a1c",
      "extra_data": {
        "balance": "0",
        "execution_optimistic": false,
        "timestamp": "2026-05-29 18:05:46.072764887 +0000 UTC m=+843.220895049"
      }
    },
    {
      "payload_status": "full",
      "slot": "137",
      "block_root": "0xa7df2ba3728f77ac3db5e9a6e62dda229f98eb403dc19794a7002dfb8adf0da2",
      "parent_root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72",
      "weight": "51609600000000",
      "validity": "valid",
      "execution_block_hash": "0x138252140503bef2a3503d160b8181c41c5c1f3d62244fc51bdfbd2fb00f8a1c",
      "extra_data": {
        "balance": "0",
        "execution_optimistic": false,
        "timestamp": "2026-05-29 18:05:46.118833922 +0000 UTC m=+843.266964094",
        "gas_limit": "178047538"
      }
    },
    ...
       ],
  "extra_data": {
    "unrealized_justified_checkpoint": {
      "epoch": "18",
      "root": "0xb650654c804ccd265b8154448793ffbec985f33fdeec2b1900cc49062f333cdc"
    },
    "unrealized_finalized_checkpoint": {
      "epoch": "17",
      "root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72"
    },
    "proposer_boost_root": "0x5fe7dc622f5ff854f2d3b8ca5c32861ff34502bcf5ec865cd5f9b50ed51c3f11",
    "previous_proposer_boost_root": "0x5fe7dc622f5ff854f2d3b8ca5c32861ff34502bcf5ec865cd5f9b50ed51c3f11",
    "head_root": "0x5fe7dc622f5ff854f2d3b8ca5c32861ff34502bcf5ec865cd5f9b50ed51c3f11"
  }
}

potuz and others added 3 commits May 29, 2026 13:01
Add a shared `payloadAttesters` Bitvector512 to each forkchoice Node so
we can distinguish "PTC member voted false" from "PTC member did not
vote" — the existing payloadAvailabilityVote / payloadDataAvailabilityVote
bitfields conflated those two states.

SetPTCVote now writes both value bits unconditionally and always marks
the attester bit, so a later vote from the same ptcIdx overwrites the
earlier one. The previously-removed payloadAttestationCount uint64 field
is replaced by payloadAttesters.Count().

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The v1 dump emits one entry per beacon block root and ignores the
empty/full PayloadNode distinction, so the spec's three forkchoice
node states (PENDING/EMPTY/FULL) and the PTC vote tallies are
invisible to clients.

v2 emits one entry per (root, payload_status) tuple, mirroring the
spec's ForkChoiceNode model: PENDING comes from the consensus Node and
carries PTC attester/availability/data-availability counts; EMPTY and
FULL come from the respective PayloadNode in emptyNodeByRoot /
fullNodeByRoot, carrying their own weight, balance, optimistic flag,
and (for FULL) gas limit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@terencechain terencechain left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. My only concern is that we’re adding 4KB to the store in the happy case, and much more in the non-finality case, for a debug endpoint

wemeetagain pushed a commit to ChainSafe/lodestar that referenced this pull request Jun 2, 2026
**Motivation**

- add missing forkchoice data to debug endpoint
- see OffchainLabs/prysm#16862

**Description**

- sample EMPTY node

```json
{
  "payload_status": "empty",
  "slot": "9",
  "block_root": "0x37d931610a0f4ff0ec7a4057f9905799e459a75fe49c76f258d5e11d47d1d79c",
  "parent_root": "0x2301a10ddc86d8cea5bbb05d0aa0dca8823123d3bfa6c2f8a7a6ff4450636d6e",
  "weight": "0",
  "validity": "valid",
  "execution_block_hash": "0xbbc1f010c338817286e384fcc129b96885d63619e206ce2729969f135252b81d",
  "extra_data": {
    "execution_optimistic": false,
    "timestamp": "1780386554",
    "target": "0x2301a10ddc86d8cea5bbb05d0aa0dca8823123d3bfa6c2f8a7a6ff4450636d6e",
    "justified_epoch": "0",
    "finalized_epoch": "0",
    "unrealized_justified_epoch": "0",
    "unrealized_finalized_epoch": "0",
    "payload_attester_count": null,
    "payload_availability_yes_count": null,
    "payload_data_availability_yes_count": null,
    "gas_limit": null
  }
}
```

- sample FULL node
```json
{
  "payload_status": "full",
  "slot": "9",
  "block_root": "0x37d931610a0f4ff0ec7a4057f9905799e459a75fe49c76f258d5e11d47d1d79c",
  "parent_root": "0x2301a10ddc86d8cea5bbb05d0aa0dca8823123d3bfa6c2f8a7a6ff4450636d6e",
  "weight": "44",
  "validity": "valid",
  "execution_block_hash": "0xec7766e17b1df22a82a447d97c457301c4b6be3b66928d13c87224dc3bc0ab76",
  "extra_data": {
    "execution_optimistic": false,
    "timestamp": "1780386554",
    "target": "0x2301a10ddc86d8cea5bbb05d0aa0dca8823123d3bfa6c2f8a7a6ff4450636d6e",
    "justified_epoch": "0",
    "finalized_epoch": "0",
    "unrealized_justified_epoch": "0",
    "unrealized_finalized_epoch": "0",
    "payload_attester_count": "16",
    "payload_availability_yes_count": "16",
    "payload_data_availability_yes_count": "16",
    "gas_limit": "30000000"
  }
}
```

**Testing**
- `node ./bin/lodestar.js dev --genesisValidators 8 --startValidators
0..7 --params.GLOAS_FORK_EPOCH 1 --enr.ip 127.0.0.1 --dataDir
.lodestar/gloas-node --reset --rest --rest.namespace '*' --metrics`
- `curl http://localhost:9596/eth/v2/debug/fork_choice`


**AI Assistance Disclosure**

- Created with the help ofClaude

---------

Co-authored-by: twoeths <twoeths@users.noreply.github.com>
@potuz potuz added this pull request to the merge queue Jun 2, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 2, 2026
@potuz potuz added this pull request to the merge queue Jun 2, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 2, 2026
@potuz potuz added this pull request to the merge queue Jun 3, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 3, 2026
@potuz potuz added this pull request to the merge queue Jun 3, 2026
Merged via the queue into develop with commit 68ef7a2 Jun 3, 2026
23 checks passed
@potuz potuz deleted the forkchoice_endpoint branch June 3, 2026 10:39
james-prysm pushed a commit that referenced this pull request Jun 8, 2026
Track individual PTC votes on forkchoice and implement a forkchoice
debug endpoint

The endpoint gives the following output

```
{
  "justified_checkpoint": {
    "epoch": "18",
    "root": "0xb650654c804ccd265b8154448793ffbec985f33fdeec2b1900cc49062f333cdc"
  },
  "finalized_checkpoint": {
    "epoch": "17",
    "root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72"
  },
  "fork_choice_nodes": [
  ...
      {
      "payload_status": "pending",
      "slot": "137",
      "block_root": "0xa7df2ba3728f77ac3db5e9a6e62dda229f98eb403dc19794a7002dfb8adf0da2",
      "parent_root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72",
      "weight": "51609600000000",
      "validity": "valid",
      "execution_block_hash": "0x138252140503bef2a3503d160b8181c41c5c1f3d62244fc51bdfbd2fb00f8a1c",
      "extra_data": {
        "balance": "0",
        "execution_optimistic": false,
        "timestamp": "2026-05-29 18:05:46.072764887 +0000 UTC m=+843.220895049",
        "target": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72",
        "justified_epoch": "16",
        "finalized_epoch": "15",
        "unrealized_justified_epoch": "16",
        "unrealized_finalized_epoch": "15",
        "payload_attester_count": "16",
        "payload_availability_yes_count": "16",
        "payload_data_availability_yes_count": "16"
      }
    },
    {
      "payload_status": "empty",
      "slot": "137",
      "block_root": "0xa7df2ba3728f77ac3db5e9a6e62dda229f98eb403dc19794a7002dfb8adf0da2",
      "parent_root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72",
      "weight": "0",
      "validity": "valid",
      "execution_block_hash": "0x138252140503bef2a3503d160b8181c41c5c1f3d62244fc51bdfbd2fb00f8a1c",
      "extra_data": {
        "balance": "0",
        "execution_optimistic": false,
        "timestamp": "2026-05-29 18:05:46.072764887 +0000 UTC m=+843.220895049"
      }
    },
    {
      "payload_status": "full",
      "slot": "137",
      "block_root": "0xa7df2ba3728f77ac3db5e9a6e62dda229f98eb403dc19794a7002dfb8adf0da2",
      "parent_root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72",
      "weight": "51609600000000",
      "validity": "valid",
      "execution_block_hash": "0x138252140503bef2a3503d160b8181c41c5c1f3d62244fc51bdfbd2fb00f8a1c",
      "extra_data": {
        "balance": "0",
        "execution_optimistic": false,
        "timestamp": "2026-05-29 18:05:46.118833922 +0000 UTC m=+843.266964094",
        "gas_limit": "178047538"
      }
    },
    ...
       ],
  "extra_data": {
    "unrealized_justified_checkpoint": {
      "epoch": "18",
      "root": "0xb650654c804ccd265b8154448793ffbec985f33fdeec2b1900cc49062f333cdc"
    },
    "unrealized_finalized_checkpoint": {
      "epoch": "17",
      "root": "0x1a07e34776709617b7251ff3966f6a1283a45b8af13fa13de995bd53b4d29a72"
    },
    "proposer_boost_root": "0x5fe7dc622f5ff854f2d3b8ca5c32861ff34502bcf5ec865cd5f9b50ed51c3f11",
    "previous_proposer_boost_root": "0x5fe7dc622f5ff854f2d3b8ca5c32861ff34502bcf5ec865cd5f9b50ed51c3f11",
    "head_root": "0x5fe7dc622f5ff854f2d3b8ca5c32861ff34502bcf5ec865cd5f9b50ed51c3f11"
  }
}

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants