diff --git a/CHANGELOG.md b/CHANGELOG.md
index 350a871ef228..7d48ebdb7fca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-# Changelog 
+# Changelog
 
 All notable changes to this project will be documented in this file.
 
@@ -10,13 +10,15 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
 
 - Aggregate and proof committee validation for Electra.
 - More tests for electra field generation.
-- Light client support: implement `ComputeFieldRootsForBlockBody`.
+- Light client support: Implement `ComputeFieldRootsForBlockBody`.
 - Light client support: Add light client database changes.
+- Light client support: Implement capella and deneb changes.
 
 ### Changed
 
 - `getLocalPayload` has been refactored to enable work in ePBS branch.
-- `TestNodeServer_GetPeer` and `TestNodeServer_ListPeers` test flakes resolved by iterating the whole peer list to find a match rather than taking the first peer in the map.
+- `TestNodeServer_GetPeer` and `TestNodeServer_ListPeers` test flakes resolved by iterating the whole peer list to find
+  a match rather than taking the first peer in the map.
 - Passing spectests v1.5.0-alpha.4 and v1.5.0-alpha.5.
 - Beacon chain now asserts that the external builder block uses the expected gas limit.
 - Electra: Add electra objects to beacon API.
@@ -27,6 +29,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
 - `grpc-gateway-port` is renamed to http-port. The old name can still be used as an alias.
 - `grpc-gateway-corsdomain` is renamed to http-cors-domain. The old name can still be used as an alias.
 - `api-timeout` is changed from int flag to duration flag, default value updated.
+- Light client support: abstracted out the light client headers with different versions.
 
 ### Deprecated
 - `--disable-grpc-gateway` flag is deprecated due to grpc gateway removal.
@@ -46,14 +49,18 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
 
 ### Security
 
-
 ## [v5.1.0](https://github.com/prysmaticlabs/prysm/compare/v5.0.4...v5.1.0) - 2024-08-20
 
-This release contains 171 new changes and many of these are related to Electra! Along side the Electra changes, there are nearly 100 changes related to bug fixes, feature additions, and other improvements to Prysm. Updating to this release is recommended at your convenience.
+This release contains 171 new changes and many of these are related to Electra! Along side the Electra changes, there
+are nearly 100 changes related to bug fixes, feature additions, and other improvements to Prysm. Updating to this
+release is recommended at your convenience.
 
 ⚠️ Deprecation Notice: Removal of gRPC Gateway and Gateway Flag Renaming ⚠️
 
-In an upcoming release, we will be deprecating the gRPC gateway and renaming several associated flags. This change will result in the removal of access to several internal APIs via REST, though the gRPC endpoints will remain unaffected. We strongly encourage systems to transition to using the beacon API endpoints moving forward. Please refer to PR for more details.
+In an upcoming release, we will be deprecating the gRPC gateway and renaming several associated flags. This change will
+result in the removal of access to several internal APIs via REST, though the gRPC endpoints will remain unaffected. We
+strongly encourage systems to transition to using the beacon API endpoints moving forward. Please refer to PR for more
+details.
 
 ### Added
 
@@ -64,7 +71,8 @@ In an upcoming release, we will be deprecating the gRPC gateway and renaming sev
 - Add middleware for Content-Type and Accept headers
 - Add debug logs for proposer settings
 - Add tracing to beacon api package
-- Add support for persistent validator keys when using remote signer. --validators-external-signer-public-keys and --validators-external-signer-key-file See the docs page for more info.
+- Add support for persistent validator keys when using remote signer. --validators-external-signer-public-keys and
+  --validators-external-signer-key-file See the docs page for more info.
 - Add AggregateKeyFromIndices to beacon state to reduce memory usage when processing attestations
 - Add GetIndividualVotes endpoint
 - Implement is_better_update for light client
@@ -118,8 +126,7 @@ In an upcoming release, we will be deprecating the gRPC gateway and renaming sev
 - Fix Event stream with carriage return support
 - Fix panic on empty block result in REST API
 - engine_getPayloadBodiesByRangeV1 - fix, adding hexutil encoding on request parameters
-- Use sync committee period instead of epoch in `createLightClientUpdate` 
-
+- Use sync committee period instead of epoch in `createLightClientUpdate`
 
 ### Security
 
@@ -127,7 +134,9 @@ In an upcoming release, we will be deprecating the gRPC gateway and renaming sev
 
 ## [v5.0.4](https://github.com/prysmaticlabs/prysm/compare/v5.0.3...v5.0.4) - 2024-07-21
 
-This release has many wonderful bug fixes and improvements. Some highlights include p2p peer fix for windows users, beacon API fix for retrieving blobs older than the minimum blob retention period, and improvements to initial sync by avoiding redundant blob downloads.
+This release has many wonderful bug fixes and improvements. Some highlights include p2p peer fix for windows users,
+beacon API fix for retrieving blobs older than the minimum blob retention period, and improvements to initial sync by
+avoiding redundant blob downloads.
 
 Updating to this release is recommended at your earliest convenience, especially for windows users.
 
@@ -189,7 +198,9 @@ Updating to this release is recommended at your earliest convenience, especially
 
 ## [v5.0.3](https://github.com/prysmaticlabs/prysm/compare/v5.0.2...v5.0.3) - 2024-04-04
 
-Prysm v5.0.3 is a small patch release with some nice additions and bug fixes. Updating to this release is recommended for users on v5.0.0 or v5.0.1. There aren't many changes since last week's v5.0.2 so upgrading is not strictly required, but there are still improvements in this release so update if you can!
+Prysm v5.0.3 is a small patch release with some nice additions and bug fixes. Updating to this release is recommended
+for users on v5.0.0 or v5.0.1. There aren't many changes since last week's v5.0.2 so upgrading is not strictly required,
+but there are still improvements in this release so update if you can!
 
 ### Added
 
@@ -221,16 +232,19 @@ No security updates in this release.
 
 ## [v5.0.2](https://github.com/prysmaticlabs/prysm/compare/v5.0.1...v5.0.2) - 2024-03-27
 
-This release has many optimizations, UX improvements, and bug fixes. Due to the number of important bug fixes and optimizations, we encourage all operators to update to v5.0.2 at their earliest convenience.
-
-In this release, there is a notable change to the default value of --local-block-value-boost from 0 to 10. This means that the default behavior of using the builder API / mev-boost requires the builder bid to be 10% better than your local block profit. If you want to preserve the existing behavior, set --local-block-value-boost=0.
+This release has many optimizations, UX improvements, and bug fixes. Due to the number of important bug fixes and
+optimizations, we encourage all operators to update to v5.0.2 at their earliest convenience.
 
+In this release, there is a notable change to the default value of --local-block-value-boost from 0 to 10. This means
+that the default behavior of using the builder API / mev-boost requires the builder bid to be 10% better than your local
+block profit. If you want to preserve the existing behavior, set --local-block-value-boost=0.
 
 ### Added
 
 - API: Add support for sync committee selections
 - blobs: call fsync between part file write and rename (feature flag --blob-save-fsync)
-- Implement EIP-3076 minimal slashing protection, using a filesystem database (feature flag --enable-minimal-slashing-protection)
+- Implement EIP-3076 minimal slashing protection, using a filesystem database (feature flag
+  --enable-minimal-slashing-protection)
 - Save invalid block to temp --save-invalid-block-temp
 - Compute unrealized checkpoints with pcli
 - Add gossip blob sidecar verification ms metric
@@ -309,7 +323,8 @@ In this release, there is a notable change to the default value of --local-block
 - Fix Data Race in Epoch Boundary
 - exit blob fetching for cp block if outside retention
 - Do not check parent weight on early FCU
-- Fix VC DB conversion when no proposer settings is defined and add Experimental flag in the --enable-minimal-slashing-protection help.
+- Fix VC DB conversion when no proposer settings is defined and add Experimental flag in the
+  --enable-minimal-slashing-protection help.
 - keymanager api: lowercase statuses
 - Fix unrealized justification
 - fix race condition when pinging peers
@@ -342,9 +357,11 @@ In this release, there is a notable change to the default value of --local-block
 
 ## [v5.0.1](https://github.com/prysmaticlabs/prysm/compare/v5.0.0...v5.0.1) - 2024-03-08
 
-This minor patch release has some nice improvements over the recent v5.0.0 for Deneb. We have minimized this patch release to include only low risk and valuable fixes or features ahead of the upcoming network upgrade on March 13th.
+This minor patch release has some nice improvements over the recent v5.0.0 for Deneb. We have minimized this patch
+release to include only low risk and valuable fixes or features ahead of the upcoming network upgrade on March 13th.
 
-Deneb is scheduled for mainnet epoch 269568 on March 13, 2024 at 01:55:35pm UTC. All operators MUST update their Prysm software to v5.0.0 or later before the upgrade in order to continue following the blockchain.
+Deneb is scheduled for mainnet epoch 269568 on March 13, 2024 at 01:55:35pm UTC. All operators MUST update their Prysm
+software to v5.0.0 or later before the upgrade in order to continue following the blockchain.
 
 ### Added
 
@@ -372,14 +389,19 @@ Prysm version v5.0.0 or later is required to maintain participation in the netwo
 
 Behold the Prysm v5 release with official support for Deneb on Ethereum mainnet!
 
-Deneb is scheduled for mainnet epoch 269568 on March 13, 2024 at 01:55:35pm UTC. All operators MUST update their Prysm software to v5.0.0 or later before the upgrade in order to continue following the blockchain.
+Deneb is scheduled for mainnet epoch 269568 on March 13, 2024 at 01:55:35pm UTC. All operators MUST update their Prysm
+software to v5.0.0 or later before the upgrade in order to continue following the blockchain.
 
-This release brings improvements to the backfill functionality of the beacon node to support backfilling blobs. If running a beacon node with checkpoint sync, we encourage you to test the backfilling functionality and share your feedback. Run with backfill enabled using the flag --enable-experimental-backfill.
+This release brings improvements to the backfill functionality of the beacon node to support backfilling blobs. If
+running a beacon node with checkpoint sync, we encourage you to test the backfilling functionality and share your
+feedback. Run with backfill enabled using the flag --enable-experimental-backfill.
 
 Known Issues
 
 - --backfill-batch-size with a value of 1 or less breaks backfill.
-- Validator client on v4.2.0 or older uses some API methods that are incompatible with beacon node v5. Ensure that you have updated the beacon node and validator client to v4.2.1 and then upgrade to v5 or update both processes at the same time to minimize downtime.
+- Validator client on v4.2.0 or older uses some API methods that are incompatible with beacon node v5. Ensure that you
+  have updated the beacon node and validator client to v4.2.1 and then upgrade to v5 or update both processes at the
+  same time to minimize downtime.
 
 ### Added
 
@@ -419,7 +441,6 @@ The following flags have been removed entirely:
 - --safe-slots-to-import-optimistically
 - --show-deposit-data
 
-
 ### Removed
 
 - Prysm gRPC slasher endpoints are removed
@@ -449,49 +470,50 @@ The following flags have been removed entirely:
 - Check non-zero blob data is written to disk
 - Avoid blob partial filepath collisions with mem addr entropy
 
-
 ### Security
 
 v5.0.0 of Prysm is required to maintain participation in the network after the Deneb upgrade.
 
 ## [v4.2.1](https://github.com/prysmaticlabs/prysm/compare/v4.2.0...v4.2.1) - 2024-01-29
 
-Welcome to Prysm Release v4.2.1! This release is highly recommended for stakers and node operators, possibly being the final update before V5.
+Welcome to Prysm Release v4.2.1! This release is highly recommended for stakers and node operators, possibly being the
+final update before V5.
 
-⚠️ This release will cause failures on Goerli, Sepolia and Holeski testnets, when running on certain older CPUs without AVX support (eg Celeron) after the Deneb fork. This is not an issue for mainnet.
+⚠️ This release will cause failures on Goerli, Sepolia and Holeski testnets, when running on certain older CPUs without
+AVX support (eg Celeron) after the Deneb fork. This is not an issue for mainnet.
 
 ### Added
 
 - Linter: Wastedassign linter enabled to improve code quality.
 - API Enhancements:
-  - Added payload return in Wei for /eth/v3/validator/blocks.
-  - Added Holesky Deneb Epoch for better epoch management.
+    - Added payload return in Wei for /eth/v3/validator/blocks.
+    - Added Holesky Deneb Epoch for better epoch management.
 - Testing Enhancements:
-  - Clear cache in tests of core helpers to ensure test reliability.
-  - Added Debug State Transition Method for improved debugging.
-  - Backfilling test: Enabled backfill in E2E tests for more comprehensive coverage.
+    - Clear cache in tests of core helpers to ensure test reliability.
+    - Added Debug State Transition Method for improved debugging.
+    - Backfilling test: Enabled backfill in E2E tests for more comprehensive coverage.
 - API Updates: Re-enabled jwt on keymanager API for enhanced security.
 - Logging Improvements: Enhanced block by root log for better traceability.
 - Validator Client Improvements:
-  - Added Spans to Core Validator Methods for enhanced monitoring.
-  - Improved readability in validator client code for better maintenance (various commits).
+    - Added Spans to Core Validator Methods for enhanced monitoring.
+    - Improved readability in validator client code for better maintenance (various commits).
 
 ### Changed
 
 - Optimizations and Refinements:
-  - Lowered resource usage in certain processes for efficiency.
-  - Moved blob rpc validation closer to peer read for optimized processing.
-  - Cleaned up validate beacon block code for clarity and efficiency.
-  - Updated Sepolia Deneb fork epoch for alignment with network changes.
-  - Changed blob latency metrics to milliseconds for more precise measurement.
-  - Altered getLegacyDatabaseLocation message for better clarity.
-  - Improved wait for activation method for enhanced performance.
-  - Capitalized Aggregated Unaggregated Attestations Log for consistency.
-  - Modified HistoricalRoots usage for accuracy.
-  - Adjusted checking of attribute emptiness for efficiency.
+    - Lowered resource usage in certain processes for efficiency.
+    - Moved blob rpc validation closer to peer read for optimized processing.
+    - Cleaned up validate beacon block code for clarity and efficiency.
+    - Updated Sepolia Deneb fork epoch for alignment with network changes.
+    - Changed blob latency metrics to milliseconds for more precise measurement.
+    - Altered getLegacyDatabaseLocation message for better clarity.
+    - Improved wait for activation method for enhanced performance.
+    - Capitalized Aggregated Unaggregated Attestations Log for consistency.
+    - Modified HistoricalRoots usage for accuracy.
+    - Adjusted checking of attribute emptiness for efficiency.
 - Database Management:
-  - Moved --db-backup-output-dir as a deprecated flag for database management simplification.
-  - Added the Ability to Defragment the Beacon State for improved database performance.
+    - Moved --db-backup-output-dir as a deprecated flag for database management simplification.
+    - Added the Ability to Defragment the Beacon State for improved database performance.
 - Dependency Update: Bumped quic-go version from 0.39.3 to 0.39.4 for up-to-date dependencies.
 
 ### Removed
@@ -502,12 +524,12 @@ Welcome to Prysm Release v4.2.1! This release is highly recommended for stakers
 ### Fixed
 
 - Bug Fixes:
-  - Fixed off by one error for improved accuracy.
-  - Resolved small typo in error messages for clarity.
-  - Addressed minor issue in blsToExecChange validator for better validation.
-  - Corrected blobsidecar json tag for commitment inclusion proof.
-  - Fixed ssz post-requests content type check.
-  - Resolved issue with port logging in bootnode.
+    - Fixed off by one error for improved accuracy.
+    - Resolved small typo in error messages for clarity.
+    - Addressed minor issue in blsToExecChange validator for better validation.
+    - Corrected blobsidecar json tag for commitment inclusion proof.
+    - Fixed ssz post-requests content type check.
+    - Resolved issue with port logging in bootnode.
 - Test Fixes: Re-enabled Slasher E2E Test for more comprehensive testing.
 
 ### Security
@@ -516,32 +538,42 @@ No security issues in this release.
 
 ## [v4.2.0](https://github.com/prysmaticlabs/prysm/compare/v4.1.1...v4.2.0) - 2024-01-11
 
-Happy new year! We have an incredibly exciting release to kick off the new year. This release is **strongly recommended** for all operators to update as it has many bug fixes, security patches, and features that will improve the Prysm experience on mainnet. This release has so many wonderful changes that we've deviated from our normal release notes format to aptly categorize the changes.
+Happy new year! We have an incredibly exciting release to kick off the new year. This release is **strongly recommended
+** for all operators to update as it has many bug fixes, security patches, and features that will improve the Prysm
+experience on mainnet. This release has so many wonderful changes that we've deviated from our normal release notes
+format to aptly categorize the changes.
 
 ### Highlights
 
 #### Upgrading / Downgrading Validators
 
-There are some API changes bundled in this release that require you to upgrade or downgrade in particular order. If the validator is updated before the beacon node, it will see repeated 404 errors at start up until the beacon node is updated as it uses a new API endpoint introduced in v4.2.0.
+There are some API changes bundled in this release that require you to upgrade or downgrade in particular order. If the
+validator is updated before the beacon node, it will see repeated 404 errors at start up until the beacon node is
+updated as it uses a new API endpoint introduced in v4.2.0.
 
 :arrow_up_small:  **Upgrading**: Upgrade the beacon node, then the validator.
 :arrow_down_small: **Downgrading**: Downgrade the validator to v4.1.1 then downgrade the beacon node.
 
 #### Deneb Goerli Support
+
 This release adds in full support for the upcoming deneb hard fork on goerli next week on January 17th.
 
 #### Networking Parameter Changes
+
 This release increases the default peer count to 70 from 45. The reason this is done is so that node's running
 with default peer counts can perform their validator duties as expected. Users who want to use the old peer count
 can add in `--p2p-max-peers=45` as a flag.
 
 #### Profile Guided Optimization
-This release has binaries built using PGO, for more information on how it works feel free to look here: https://tip.golang.org/doc/pgo . 
-This allows the go compiler to build more optimized Prysm binaries using production profiles and workloads.  
+
+This release has binaries built using PGO, for more information on how it works feel free to look
+here: https://tip.golang.org/doc/pgo .
+This allows the go compiler to build more optimized Prysm binaries using production profiles and workloads.
 
 #### ARM Supported Docker Images
 
-Our docker images now support amd64 and arm64 architecture! This long awaited feature is finally here for Apple Silicon and Raspberry Pi users. 
+Our docker images now support amd64 and arm64 architecture! This long awaited feature is finally here for Apple Silicon
+and Raspberry Pi users.
 
 ### Deneb
 
@@ -593,18 +625,18 @@ Our docker images now support amd64 and arm64 architecture! This long awaited fe
 - Prune dangling blob
 - Use Afero Walk for Pruning Blob
 - Initialize blob storage without pruning
-- Fix batch pruning errors 
+- Fix batch pruning errors
 - Blob filesystem add pruning during blob write
 - Blob filesystem add pruning at startup
 - Ensure partial blob is deleted if there's an error
 - Split blob pruning into two funcs
 - Use functional options for `--blob-retention-epochs`
-- Blob filesystem: delete blobs 
+- Blob filesystem: delete blobs
 - Fix Blob Storage Path
 - Add blob getters
 - Blob filesystem: Save Blobs
 - Blob filesystem: prune blobs
-- blobstorage: Improve mkdirall error 
+- blobstorage: Improve mkdirall error
 
 #### Beacon-API
 
@@ -622,7 +654,7 @@ Our docker images now support amd64 and arm64 architecture! This long awaited fe
 #### Validator Client
 
 - Validator client: remove blob signing
-- Deneb - web3signer 
+- Deneb - web3signer
 
 #### Testing
 
@@ -640,7 +672,7 @@ Our docker images now support amd64 and arm64 architecture! This long awaited fe
 - Check builder header kzg commitment
 - Add more color to sending blob by range req log
 - Move pruning log to after retention check
-- Enhance Pruning Logs 
+- Enhance Pruning Logs
 - Rename Blob retention epoch flag
 - Check that blobs count is correct when unblinding
 - Log blob's kzg commmitment at sync
@@ -680,7 +712,7 @@ Our docker images now support amd64 and arm64 architecture! This long awaited fe
 - Verify lmd without ancestor
 - Track target in forkchoice
 - Return early from ReceiveBlock if already sycned
- 
+
 #### Builder
 
 - Adding builder boost factor to get block v3
@@ -729,7 +761,7 @@ _Most of the PRs here involve shifting our http endpoints to using vanilla http
 - http endpoint cleanup
 - Revert "REST VC: Subscribe to Beacon API events "
 - proposer and attester slashing sse
-- REST VC: Subscribe to Beacon API events 
+- REST VC: Subscribe to Beacon API events
 - Simplify error handling for JsonRestHandler
 - Update block publishing to 2.4.2 spec
 - Use `SkipMevBoost` properly during block production
@@ -869,12 +901,12 @@ _Most of the PRs here involve shifting our http endpoints to using vanilla http
 - Fix missing testnet versions. Issue
 - Update README.md
 - Only run metrics for canonical blocks
-- Relax file permissions check on existing directories 
+- Relax file permissions check on existing directories
 - forkchoice.Getter wrapper with locking wrappers
 - Initialize cancellable root context in main.go
 - Fix forkchoice pkg's comments grammar
 - lock RecentBlockSlot
-- Comment typo 
+- Comment typo
 - Optimize `ReplayBlocks` for Zero Diff
 - Remove default value of circuit breaker flags
 - Fix Withdrawals
@@ -899,7 +931,8 @@ _Most of the PRs here involve shifting our http endpoints to using vanilla http
 
 ## [v4.1.1](https://github.com/prysmaticlabs/prysm/compare/v4.1.0...v4.1.1) - 2023-10-24
 
-This patch release includes two cherry-picked changes from the develop branch to resolve critical issues that affect a small set of users.
+This patch release includes two cherry-picked changes from the develop branch to resolve critical issues that affect a
+small set of users.
 
 ### Fixed
 
@@ -912,11 +945,17 @@ No security issues in thsi release.
 
 ## [v4.1.0](https://github.com/prysmaticlabs/prysm/compare/v4.0.8...v4.1.0) - 2023-08-22
 
-- **Fundamental Deneb Support**: This release lays the foundation for Deneb support, although features like backwards syncing and filesystem-based blob storage are planned for Q4 2024.
-- **Multi-Value Slices for Beacon State**: Implemented multi-value slices to reduce the memory footprint and optimize certain processing paths. This data structure allows for storing values shared between state instances more efficiently. This feature is controller by the `--enable-experimental-state` flag.
-- **EIP-4881 Deposit Tree**: Integrated the EIP-4881 Deposit Tree into Prysm to optimize runtime block processing and production. This feature is controlled by a flag: `--enable-eip-4881`
-- **BLST version 0.3.11**: Introduced a significant improvement to the portable build's performance. The portable build now features runtime detection, automatically enabling optimized code paths if your CPU supports it.
-- **Multiarch Containers Preview Available**: multiarch (:wave: arm64 support :wave:) containers will be offered for preview at the following locations:
+- **Fundamental Deneb Support**: This release lays the foundation for Deneb support, although features like backwards
+  syncing and filesystem-based blob storage are planned for Q4 2024.
+- **Multi-Value Slices for Beacon State**: Implemented multi-value slices to reduce the memory footprint and optimize
+  certain processing paths. This data structure allows for storing values shared between state instances more
+  efficiently. This feature is controller by the `--enable-experimental-state` flag.
+- **EIP-4881 Deposit Tree**: Integrated the EIP-4881 Deposit Tree into Prysm to optimize runtime block processing and
+  production. This feature is controlled by a flag: `--enable-eip-4881`
+- **BLST version 0.3.11**: Introduced a significant improvement to the portable build's performance. The portable build
+  now features runtime detection, automatically enabling optimized code paths if your CPU supports it.
+- **Multiarch Containers Preview Available**: multiarch (:wave: arm64 support :wave:) containers will be offered for
+  preview at the following locations:
     - Beacon Chain: [gcr.io/prylabs-dev/prysm/beacon-chain:v4.1.0](gcr.io/prylabs-dev/prysm/beacon-chain:v4.1.0)
     - Validator: [gcr.io/prylabs-dev/prysm/validator:v4.1.0](gcr.io/prylabs-dev/prysm/validator:v4.1.0)
     - Please note that in the next cycle, we will exclusively use these containers at the canonical URLs.
@@ -924,13 +963,16 @@ No security issues in thsi release.
 ### Added
 
 #### EIP-4844:
+
 ##### Core:
+
 - **Deneb State & Block Types**: New state and block types added specifically for Deneb.
 - **Deneb Protobufs**: Protocol Buffers designed exclusively for Deneb.
 - **Deneb Engine API**: Specialized API endpoints for Deneb.
 - **Deneb Config/Params**: Deneb-specific configurations and parameters from the deneb-integration branch.
 
 ##### Blob Management:
+
 - **Blob Retention Epoch Period**: Configurable retention periods for blobs.
 - **Blob Arrival Gossip Metric**: Metrics for blob arrivals via gossip protocol.
 - **Blob Merge Function**: Functionality to merge and validate saved/new blobs.
@@ -938,37 +980,45 @@ No security issues in thsi release.
 - **Save Blobs to DB**: Feature to save blobs to the database for subscribers.
 
 ##### Logging and Validation:
+
 - **Logging for Blob Sidecar**: Improved logging functionalities for Blob Sidecar.
 - **Blob Commitment Count Logging**: Introduced logging for blob commitment counts.
 - **Blob Validation**: A feature to validate blobs.
 
 ##### Additional Features and Tests:
+
 - **Deneb Changes & Blobs to Builder**: Deneb-specific changes and blob functionality added to the builder.
 - **Deneb Blob Sidecar Events**: Blob sidecar events added as part of the Deneb release.
 - **KZG Commitments**: Functionality to copy KZG commitments when using the builder block.
 - **Deneb Validator Beacon APIs**: New REST APIs specifically for the Deneb release.
 - **Deneb Tests**: Test cases specific to the Deneb version.
 - **PublishBlockV2 for Deneb**: The `publishblockv2` endpoint implemented specifically for Deneb.
-- **Builder Override & Builder Flow for Deneb**: An override for the builder and a new RPC to handle the builder flow in Deneb.
+- **Builder Override & Builder Flow for Deneb**: An override for the builder and a new RPC to handle the builder flow in
+  Deneb.
 - **SSZ Detection for Deneb**: SSZ detection capabilities added for Deneb.
 - **Validator Signing for Deneb**: Validators can now sign Deneb blocks.
 - **Deneb Upgrade Function**: A function to handle the upgrade to Deneb.
 
 #### Rest of EIPs
+
 - **EIP-4788**: Added support for Beacon block root in the EVM.
-- **EIP-7044** and **EIP-7045**: Implemented support for Perpetually Valid Signed Voluntary Exits and increased the max attestation inclusion slot.
+- **EIP-7044** and **EIP-7045**: Implemented support for Perpetually Valid Signed Voluntary Exits and increased the max
+  attestation inclusion slot.
 
 #### Beacon API:
 
 *Note: All Beacon API work is related with moving endpoints into pure HTTP handlers. This is NOT new functionality.*
 
 ##### Endpoints moved to HTTP:
+
 - `/eth/v1/beacon/blocks` and `/eth/v1/beacon/blinded_blocks`.
 - `/eth/v1/beacon/states/{state_id}/committees`.
 - `/eth/v1/config/deposit_contract`.
 - `/eth/v1/beacon/pool/sync_committees`.
-- `/eth/v1/beacon/states/{state_id}/validators`, `/eth/v1/beacon/states/{state_id}/validators/{validator_id}` and `/eth/v1/beacon/states/{state_id}/validator_balances`.
-- `/eth/v1/validator/duties/attester/{epoch}`, `/eth/v1/validator/duties/proposer/{epoch}` and `/eth/v1/validator/duties/sync/{epoch}`.
+- `/eth/v1/beacon/states/{state_id}/validators`, `/eth/v1/beacon/states/{state_id}/validators/{validator_id}`
+  and `/eth/v1/beacon/states/{state_id}/validator_balances`.
+- `/eth/v1/validator/duties/attester/{epoch}`, `/eth/v1/validator/duties/proposer/{epoch}`
+  and `/eth/v1/validator/duties/sync/{epoch}`.
 - `/eth/v1/validator/register_validator`.
 - `/eth/v1/validator/prepare_beacon_proposer`.
 - `/eth/v1/beacon/headers`.
@@ -981,13 +1031,16 @@ No security issues in thsi release.
 - `/eth/v1/beacon/headers/{block_id}` and `/eth/v1/validator/liveness/{epoch}`.
 
 ##### Miscellaneous:
+
 - **Comma-Separated Query Params**: Support for comma-separated query parameters added to Beacon API.
 - **Middleware for Query Params**: Middleware introduced for handling comma-separated query parameters.
 - **Content-Type Header**: Compliance improved by adding Content-Type header to VC POST requests.
 - **Node Version**: REST-based node version endpoint implemented.
 
 #### Other additions
+
 ##### Protocol:
+
 - **Multi-Value Slice for Beacon State**: Enhanced the beacon state by utilizing a multi-value slice.
 - **EIP-4881 Deposit Tree**: EIP-4881 Deposit Tree integrated into Prysm, controlled by a feature flag.
 - **New Engine Methods**: New engine methods set as the default.
@@ -995,36 +1048,45 @@ No security issues in thsi release.
 - **Block Commitment Checks**: Functionality to reject blocks with excessive commitments added.
 
 ##### State Management:
+
 - **Alloc More Items**: Modified beacon-node/state to allocate an additional item during appends.
-- **GetParentBlockHash Helper**: Refactoring of `getLocalPayloadAndBlobs` with a new helper function for fetching parent block hashes.
+- **GetParentBlockHash Helper**: Refactoring of `getLocalPayloadAndBlobs` with a new helper function for fetching parent
+  block hashes.
 - **RW Lock for Duties**: Read-Write lock mechanism introduced for managing validator duties.
 
 ##### Build and CI/CD Improvements:
+
 - **Manual Build Tag**: A "manual" build tag introduced to expedite CI build times.
 - **Multiarch Docker Containers**: Support for multiple architectures in Docker containers added.
 
 ##### Testing:
+
 - **Init-Sync DA Tests**: Tests for initial sync Data Availability (DA) included.
 - **Fuzz List Timeout**: Github workflow for fuzz testing now includes a timeout setting.
 - **Go Fuzzing Workflow**: New Github workflow for Go fuzzing on a cron schedule.
 
 ##### Logging and Monitoring:
+
 - **FFG-LMD Consistency Logging**: Enhanced logging for Finality Gadget LMD (FFG-LMD) consistency.
 - **Validator Count Endpoint**: New endpoint to count the number of validators.
 
 ##### User Interface and Web:
+
 - **Web UI Release**: Prysm Web UI v2.0.4 released with unspecified updates and improvements.
 
 ##### Testnet support:
+
 - **Holesky Support**: Support for Holesky decompositions integrated into the codebase.
 
 ##### Error Handling and Responses:
+
 - **Validation Error in ForkchoiceUpdatedResponse**: Included validation errors in fork choice update responses.
 - **Wrapped Invalid Block Error**: Improved error handling for cases where an invalid block error is wrapped..
 
 ### Changed
 
 #### General:
+
 - **Skip MEV-Boost Flag**: Updated `GetBlock` RPC to utilize `skip mev-boost` flag.
 - **Portable Version of BLST**: Transitioned to portable BLST version as default.
 - **Teku Mainnet Bootnodes**: Refreshed Teku mainnet bootnodes ENRs.
@@ -1032,6 +1094,7 @@ No security issues in thsi release.
 - **Parallel Block Building**: Deprecated sequential block building path
 
 #### Deneb-Specific Changes:
+
 - **Deneb Spectests Release**: Upgraded to Deneb spectests v1.4.0-beta.2-hotfix.
 - **Deneb API and Builder Cleanup**: Conducted clean-up activities for Deneb-specific API and builder.
 - **Deneb Block Versioning**: Introduced changes related to Deneb produce block version 3.
@@ -1040,23 +1103,28 @@ No security issues in thsi release.
 - **Blob Sidecar Syncing**: Altered behavior when value is 0.
 
 #### Code Cleanup and Refactor:
+
 - **API Types Cleanup**: Reorganized API types for improved readability.
 - **Geth Client Headers**: Simplified code for setting geth client headers.
 - **Bug Report Template**: Revised requirements for more clarity.
 
 #### Flags and Configuration:
+
 - **Safe Slots to Import Flag**: Deprecated this flag for standard alignment.
 - **Holesky Config**: Revised the Holesky configuration for new genesis.
 
 #### Logging:
+
 - **Genesis State Warning**: Will log a warning if the genesis state size is under 1KB.
 - **Debug Log Removal**: Excised debug logs for cleaner output.
 
 #### Miscellaneous:
+
 - **First Aggregation Timing**: Default setting for first aggregation is 7 seconds post-genesis.
 - **Pointer Usage**: Modified execution chain to use pointers, reducing copy operations.
 
 #### Dependency Updates:
+
 - **Go Version Update**: Updated to Go version 1.20.7.
 - **Go Version Update**: Updated to Go version 1.20.9 for better security.
 - **Various Dependencies**: Updated multiple dependencies including Geth, Bazel, rules_go, Gazelle, BLST, and go-libp2p.
@@ -1069,13 +1137,16 @@ No security issues in thsi release.
 - **Go-Playground/Validator**: Removed go-playground/validator from Beacon API.
 - **Reverted Cache Proposer ID**: Reversed the change that cached proposer ID on GetProposerDuties.
 - **Cache Proposer ID**: Reversed the functionality that cached proposer ID on GetProposerDuties.
-- **Quadratic Loops in Exiting**: Eliminated quadratic loops that occurred during voluntary exits, improving performance.
-- **Deprecated Go Embed Rules**: Removed deprecated `go_embed` rules from rules_go, to stay up-to-date with best practices.
+- **Quadratic Loops in Exiting**: Eliminated quadratic loops that occurred during voluntary exits, improving
+  performance.
+- **Deprecated Go Embed Rules**: Removed deprecated `go_embed` rules from rules_go, to stay up-to-date with best
+  practices.
 - **Alpine Images**: Removed Alpine images from the Prysm project.
 
 ### Fixed
 
 #### Deneb-Specific Bug Fixes:
+
 - **Deneb Builder Bid HTR**: Fixed an issue related to HashTreeRoot (HTR) in Deneb builder bid.
 - **PBV2 Condition**: Corrected conditions related to PBV2.
 - **Route Handler and Cleanup**: Updated the route handler and performed minor cleanups.
@@ -1088,11 +1159,13 @@ No security issues in thsi release.
 - **Sync/RPC Blob Usage**: Rectified blob usage when requesting a block by root in Sync/RPC.
 
 #### Cache Fixes:
+
 - **Don't Prune Proposer ID Cache**: Fixed a loop erroneously pruning the proposer ID cache.
 - **LastRoot Adjustment**: Altered `LastRoot` to return the head root.
 - **Last Canonical Root**: Modified forkchoice to return the last canonical root of the epoch.
 
 #### Block Processing fixes:
+
 - **Block Validation**: Fixed an issue where blocks were incorrectly marked as bad during validation.
 - **Churn Limit Helpers**: Improved churn limit calculations through refactoring.
 - **Churn with 0 Exits**: Rectified a bug that calculated churn even when there were 0 exits.
@@ -1100,19 +1173,22 @@ No security issues in thsi release.
 - **Duplicate Block Processing**: Eliminated redundant block processing.
 
 #### Error Handling and Logging:
+
 - **RpcError from Core Service**: Ensured that `RpcError` is returned from core services.
 - **Unhandled Error**: Enhanced error management by handling previously unhandled errors.
 - **Error Handling**: Wrapped `ctx.Err` for improved error handling.
 - **Attestation Error**: Optimized error management in attestation processing.
 
 #### Test and Build Fixes:
+
 - **Racy Tests in Blockchain**: Resolved race conditions in blockchain tests.
 - **TestService_ReceiveBlock**: Modified `TestService_ReceiveBlock` to work as expected.
 - **Build Issue with @com_github_ethereum_c_kzg_4844**: Resolved build issues related to this specific library.
-- **Fuzz Testing**: Addressed fuzz testing issues in the `origin/deneb-integration` 
+- **Fuzz Testing**: Addressed fuzz testing issues in the `origin/deneb-integration`
 - **Long-Running E2E Tests**: Fixed issues that were causing the end-to-end tests to run for an extended period.
 
 #### Additional Fixes:
+
 - **Public Key Copies During Aggregation**: Optimized to avoid unnecessary public key copies during aggregation.
 - **Epoch Participations**: Fixed the setting of current and previous epoch participations.
 - **Verify Attestations**: Resolved an attestation verification issue in proposer logic.
@@ -1122,7 +1198,6 @@ No security issues in thsi release.
 - **Hex Handling**: Upgraded the hex handling in various modules.
 - **Initial Sync PreProcessing**: Resolved an issue affecting the initial sync preprocessing.
 
-
 ### Security
 
 No security updates in this release.
@@ -1133,7 +1208,8 @@ Welcome to Prysm Release v4.0.8! This release is recommended. Highlights:
 
 - Parallel hashing of validator entries in the beacon state. This results in a faster hash tree root. ~3x reduction
 - Parallel validations of consensus and execution checks. This results in a faster block verification
-- Aggregate parallel is now the default. This results in faster attestation aggregation time if a node is subscribed to multiple beacon attestation subnets. ~3x reduction
+- Aggregate parallel is now the default. This results in faster attestation aggregation time if a node is subscribed to
+  multiple beacon attestation subnets. ~3x reduction
 - Better process block epoch boundary cache usages and bug fixes
 - Beacon-API endpoints optimizations and bug fixes
 
@@ -1215,12 +1291,20 @@ Welcome to the v4.0.7 release of Prysm! This recommended release contains many e
 Highlights:
 
 - The validator proposal time for slot 0 has been reduced by 800ms. Writeup and PR
-- The attestation aggregation time has been reduced by 400ms—roughly 75% with all subnets subscribed. Flag --aggregate-parallel. PR. This is only useful if running more than a dozen validator keys. The more subnets your node subscribe to, the more useful.
-- The usage of fork choice lock has been reduced and optimized, significantly reducing block processing time. This results in a higher proposal and attest rate. PR
-- The block proposal path has been optimized with more efficient copies and a better pruning algorithm for pending deposits. PR and PR
-- Validator Registration cache is enabled by default, this affects users who have used webui along with mevboost. Please review PR for details.
-
-Note: We remind our users that there are two versions of the cryptographic library BLST, one is "portable" and less performant, and another is "non-portable" or "modern" and more performant. Most users would want to use the second one. You can set the environment variable USE_PRYSM_MODERN=true when using prysm.sh. The released docker images are using the non-portable version by default.
+- The attestation aggregation time has been reduced by 400ms—roughly 75% with all subnets subscribed. Flag
+  --aggregate-parallel. PR. This is only useful if running more than a dozen validator keys. The more subnets your node
+  subscribe to, the more useful.
+- The usage of fork choice lock has been reduced and optimized, significantly reducing block processing time. This
+  results in a higher proposal and attest rate. PR
+- The block proposal path has been optimized with more efficient copies and a better pruning algorithm for pending
+  deposits. PR and PR
+- Validator Registration cache is enabled by default, this affects users who have used webui along with mevboost. Please
+  review PR for details.
+
+Note: We remind our users that there are two versions of the cryptographic library BLST, one is "portable" and less
+performant, and another is "non-portable" or "modern" and more performant. Most users would want to use the second one.
+You can set the environment variable USE_PRYSM_MODERN=true when using prysm.sh. The released docker images are using the
+non-portable version by default.
 
 ### Added
 
@@ -1290,21 +1374,29 @@ No security updates in this release.
 
 ## [v4.0.6](https://github.com/prysmaticlabs/prysm/compare/v4.0.5...v4.0.6) - 2023-07-15
 
-Welcome to v4.0.6 release of Prysm! This recommended release contains many essential optimizations since v4.0.5. Notable highlights:
+Welcome to v4.0.6 release of Prysm! This recommended release contains many essential optimizations since v4.0.5. Notable
+highlights:
 
 Better handling of state field trie under late block scenario. This improves the next slot proposer's proposed time
 Better utilization of next slot cache under various conditions
 
 **Important read:**
 
-1.) We use this opportunity to remind you that two different implementations of the underlying cryptographic library BLST exist.
+1.) We use this opportunity to remind you that two different implementations of the underlying cryptographic library
+BLST exist.
 
 - portable: supports every CPU made in the modern era
 - non-portable: more performant but requires your CPU to support special instructions
 
-Most users will want to use the "non-portable" version since most CPUs support these instructions. Our docker builds are now non-portable by default. Most users will benefit from the performance improvements. You can run with the "portable" versions if your CPU is old or unsupported. For binary distributions and to maintain backward compatibility with older versions of prysm.sh or prysm.bat, users that want to benefit from the non-portable performance improvements need to add an environment variable, like so: USE_PRYSM_MODERN=true prysm.sh beacon-chain prefix, or download the "non-portable" version of the binaries from the github repo.
+Most users will want to use the "non-portable" version since most CPUs support these instructions. Our docker builds are
+now non-portable by default. Most users will benefit from the performance improvements. You can run with the "portable"
+versions if your CPU is old or unsupported. For binary distributions and to maintain backward compatibility with older
+versions of prysm.sh or prysm.bat, users that want to benefit from the non-portable performance improvements need to add
+an environment variable, like so: USE_PRYSM_MODERN=true prysm.sh beacon-chain prefix, or download the "non-portable"
+version of the binaries from the github repo.
 
-2.) A peering bug that led to nodes losing peers gradually and eventually needing a restart has been patched. Nodes previously affected by it can remove the --disable-resource-manager flag from v4.0.6 onwards.
+2.) A peering bug that led to nodes losing peers gradually and eventually needing a restart has been patched. Nodes
+previously affected by it can remove the --disable-resource-manager flag from v4.0.6 onwards.
 
 ### Added
 
@@ -1358,22 +1450,31 @@ No security updates in this release.
 
 ## [v4.0.5](https://github.com/prysmaticlabs/prysm/compare/v4.0.4...v4.0.5) - 2023-05-22
 
-Welcome to v4.0.5 release of Prysm! This release contains many important improvements and bug fixes since v4.0.4, including significant improvements to attestation aggregation. See @potuz's notes [here](https://hackmd.io/TtyFurRJRKuklG3n8lMO9Q). This release is **strongly** recommended for all users.
+Welcome to v4.0.5 release of Prysm! This release contains many important improvements and bug fixes since v4.0.4,
+including significant improvements to attestation aggregation. See @potuz's
+notes [here](https://hackmd.io/TtyFurRJRKuklG3n8lMO9Q). This release is **strongly** recommended for all users.
 
-Note: The released docker images are using the portable version of the blst cryptography library. The Prysm team will release docker images with the non-portable blst library as the default image. In the meantime, you can compile docker images with blst non-portable locally with the `--define=blst_modern=true` bazel flag, use the "-modern-" assets attached to releases, or set environment varaible USE_PRYSM_MODERN=true when using prysm.sh.
+Note: The released docker images are using the portable version of the blst cryptography library. The Prysm team will
+release docker images with the non-portable blst library as the default image. In the meantime, you can compile docker
+images with blst non-portable locally with the `--define=blst_modern=true` bazel flag, use the "-modern-" assets
+attached to releases, or set environment varaible USE_PRYSM_MODERN=true when using prysm.sh.
 
 ### Added
 
 - Added epoch and root to "not a checkpt in forkchoice" log message
 - Added cappella support for eth1voting tool
 - Persist validator proposer settings in the validator db.
-- Add flag to disable p2p resource management. This flag is for debugging purposes and should not be used in production for extended periods of time. Use this flag if you are experiencing significant peering issues. --disable-resource-manager
+- Add flag to disable p2p resource management. This flag is for debugging purposes and should not be used in production
+  for extended periods of time. Use this flag if you are experiencing significant peering issues.
+  --disable-resource-manager
 
 ### Changed
 
 - Improved slot ticker for attestation aggregation
-- Parallel block production enabled by default. Opt out with --disable-build-block-parallel if issues are suspected with this feature.
-- Improve attestation aggregation by not using max cover on unaggregated attestations and not checking subgroup of previously validated signatures.
+- Parallel block production enabled by default. Opt out with --disable-build-block-parallel if issues are suspected with
+  this feature.
+- Improve attestation aggregation by not using max cover on unaggregated attestations and not checking subgroup of
+  previously validated signatures.
 - Improve sync message processing by using forkchoice
 
 ### Fixed
@@ -1388,14 +1489,17 @@ No security updates in this release.
 
 ## [v4.0.4](https://github.com/prysmaticlabs/prysm/compare/v4.0.3...v4.0.4) - 2023-05-15
 
-Welcome to v4.0.4 release of Prysm! This is the first full release following the recent mainnet issues and it is very important that all stakers update to this release as soon as possible.
+Welcome to v4.0.4 release of Prysm! This is the first full release following the recent mainnet issues and it is very
+important that all stakers update to this release as soon as possible.
 
 Aside from the critical fixes for mainnet, this release contains a number of new features and other fixes since v4.0.3.
 
 ### Added
 
-- Feature to build consensus and execution blocks in parallel. This feature has shown a noticeable reduction (~200ms) in block proposal times. Enable with --build-block-parallel
-- An in memory cache for validator registration can be enabled with --enable-registration-cache. See PR description before enabling.
+- Feature to build consensus and execution blocks in parallel. This feature has shown a noticeable reduction (~200ms) in
+  block proposal times. Enable with --build-block-parallel
+- An in memory cache for validator registration can be enabled with --enable-registration-cache. See PR description
+  before enabling.
 - Added new linters
 - Improved tracing data for builder pipeline
 - Improved withdrawal phrasing in validator withdrawal tooling
@@ -1444,7 +1548,8 @@ Aside from the critical fixes for mainnet, this release contains a number of new
 
 ### Security
 
-This release contains some important fixes that improve the resiliency of Ethereum Consensus Layer. See https://github.com/prysmaticlabs/prysm/pull/12387 and https://github.com/prysmaticlabs/prysm/pull/12398.
+This release contains some important fixes that improve the resiliency of Ethereum Consensus Layer.
+See https://github.com/prysmaticlabs/prysm/pull/12387 and https://github.com/prysmaticlabs/prysm/pull/12398.
 
 ## [v4.0.3](https://github.com/prysmaticlabs/prysm/compare/v4.0.2...v4.0.3) - 2023-04-20
 
@@ -1478,21 +1583,27 @@ No security updates in this release.
 
 ## [v4.0.2](https://github.com/prysmaticlabs/prysm/compare/v4.0.1...v4.0.2) - 2023-04-12
 
-This release fixes a critical bug on Prysm interacting with mev-boost / relayer. You MUST upgrade to this release if you run Prysm with mev boost and relayer, or you will be missing block proposals during the first days after the Shapella fork while the block has bls-to-exec changes.
+This release fixes a critical bug on Prysm interacting with mev-boost / relayer. You MUST upgrade to this release if you
+run Prysm with mev boost and relayer, or you will be missing block proposals during the first days after the Shapella
+fork while the block has bls-to-exec changes.
 Post-mortem that describes this incident will be provided by the end of the week.
 
-One of this release's main optimizations is revamping the next slot cache. It has been upgraded to be more performant across edge case re-org scenarios. This can help with the bad head attestation vote.
+One of this release's main optimizations is revamping the next slot cache. It has been upgraded to be more performant
+across edge case re-org scenarios. This can help with the bad head attestation vote.
 
-Minor fixes in this release address a bug that affected certain large operators querying RPC endpoints. This bug caused unexpected behavior and may have impacted the performance of affected operators. To resolve this issue, we have included a patch that ensures proper functionality when querying RPC endpoints.
+Minor fixes in this release address a bug that affected certain large operators querying RPC endpoints. This bug caused
+unexpected behavior and may have impacted the performance of affected operators. To resolve this issue, we have included
+a patch that ensures proper functionality when querying RPC endpoints.
 
 ### Added
 
-- CLI: New beacon node flag local-block-value-boost that allows the local block value to be multiplied by the boost value
+- CLI: New beacon node flag local-block-value-boost that allows the local block value to be multiplied by the boost
+  value
 - Smart caching for square root computation
 - Beacon-API: Implemented Block rewards endpoint
 - Beacon-API client: Implemented GetSyncStatus endpoint
 - Beacon-API client: Implemented GetGenesis endpoint
-- Beacon-API client: Implemented ListValidators  endpoint
+- Beacon-API client: Implemented ListValidators endpoint
 
 ### Changed
 
@@ -1570,7 +1681,6 @@ This is a reissue of v4.0.0. See https://github.com/prysmaticlabs/prysm/issues/1
 - Test: disable e2e slasher test
 - CLI: derecate the following flags
 
-
 ### Deprecated
 
 The following flags have been deprecated.
@@ -1628,10 +1738,12 @@ This release is required to participate in the Capella upgrade.
 
 Gm! ☀️ We are excited to announce our release for upgrading Goerli testnet to Shanghai / Capella! 🚀
 
-This release is MANDATORY for Goerli testnet. You must upgrade your Prysm beacon node and validator client to this release before Shapella hard fork time epoch=162304 or UTC=14/03/2023, 10:25:36 pm.
+This release is MANDATORY for Goerli testnet. You must upgrade your Prysm beacon node and validator client to this
+release before Shapella hard fork time epoch=162304 or UTC=14/03/2023, 10:25:36 pm.
 
 This release is a low-priority for the mainnet.
-This release is the same commit as v3.2.2-rc.3. If you are already running v3.2.2-rc.3, then you do not need to update your client.
+This release is the same commit as v3.2.2-rc.3. If you are already running v3.2.2-rc.3, then you do not need to update
+your client.
 
 ### Added
 
@@ -1672,14 +1784,17 @@ This release is required for Goerli to upgrade to Capella.
 
 We are excited to announce the release of Prysm v3.2.1 🎉
 
-This is the first release to support Capella / Shanghai. The Sepolia testnet Capella upgrade time is currently set to 2/28/2023, 4:04:48 AM UTC. The Goerli testnet and Mainnet upgrade times are still yet to be determined. In Summary:
+This is the first release to support Capella / Shanghai. The Sepolia testnet Capella upgrade time is currently set to
+2/28/2023, 4:04:48 AM UTC. The Goerli testnet and Mainnet upgrade times are still yet to be determined. In Summary:
 
 - This is a mandatory upgrade for Sepolia nodes and validators
 - This is a recommended upgrade for Goerli and Mainnet nodes and validators
 
 There are some known issues with this release.
 
-- mev-boost, relayer, and builder support for Capella upgrade are built in but still need to be tested. Given the lack of testing infrastructure, none of the clients could test this for withdrawals testnet. There may be hiccups when using mev-boost on the Capella upgraded testnets.
+- mev-boost, relayer, and builder support for Capella upgrade are built in but still need to be tested. Given the lack
+  of testing infrastructure, none of the clients could test this for withdrawals testnet. There may be hiccups when
+  using mev-boost on the Capella upgraded testnets.
 
 ### Added
 
@@ -1736,7 +1851,10 @@ There are no security updates in this release.
 
 ## [v3.2.0](https://github.com/prysmaticlabs/prysm/compare/v3.1.2...v3.2.0) - 2022-12-16
 
-This release contains a number of great features and improvements as well as progress towards the upcoming Capella upgrade. This release also includes some API changes which are reflected in the minor version bump. If you are using mev-boost, you will need to update your prysm client to v3.2.0 before updating your mev-boost instance in the future. See [flashbots/mev-boost#404](https://github.com/flashbots/mev-boost/issues/404) for more details.
+This release contains a number of great features and improvements as well as progress towards the upcoming Capella
+upgrade. This release also includes some API changes which are reflected in the minor version bump. If you are using
+mev-boost, you will need to update your prysm client to v3.2.0 before updating your mev-boost instance in the future.
+See [flashbots/mev-boost#404](https://github.com/flashbots/mev-boost/issues/404) for more details.
 
 ### Added
 
@@ -1864,7 +1982,9 @@ This release contains a number of great features and improvements as well as pro
 
 ## [v3.1.1](https://github.com/prysmaticlabs/prysm/compare/v3.1.0...v3.1.1) - 2022-09-09
 
-This is another highly recommended release. It contains a forkchoice pruning fix and a gossipsub optimization. It is recommended to upgrade to this release before the Merge next week, which is currently tracking for Wed Sept 14 (https://bordel.wtf/). Happy staking! See you on the other side!
+This is another highly recommended release. It contains a forkchoice pruning fix and a gossipsub optimization. It is
+recommended to upgrade to this release before the Merge next week, which is currently tracking for Wed Sept
+14 (https://bordel.wtf/). Happy staking! See you on the other side!
 
 ### Fixed
 
@@ -1877,14 +1997,14 @@ No security updates in this release.
 
 ## [v3.1.0](https://github.com/prysmaticlabs/prysm/compare/v3.1.0...v3.0.0) - 2022-09-05
 
-Updating to this release is highly recommended as it contains several important fixes and features for the merge. You must be using Prysm v3 or later before Bellatrix activates on September 6th. 
+Updating to this release is highly recommended as it contains several important fixes and features for the merge. You
+must be using Prysm v3 or later before Bellatrix activates on September 6th.
 
 **Important docs links**
 
 - [How to prepare for the merge](https://docs.prylabs.network/docs/prepare-for-merge)
 - [How to check merge readiness status](https://docs.prylabs.network/docs/monitoring/checking-status)
 
-
 ### Added
 
 - Add time until next duty in epoch logs for validator
@@ -1937,16 +2057,21 @@ There are no security updates in this release.
 - Keymanager: Add support for setting the gas limit via API.
 - Merge: Mainnet merge epoch and TTD defined!
 - Validator: Added expected wait time for pending validator activation in log message.
-- Go: Prysm now uses proper versioning suffix v3 for this release. GoDocs and downstream users can now import prysm as expected for go projects.
+- Go: Prysm now uses proper versioning suffix v3 for this release. GoDocs and downstream users can now import prysm as
+  expected for go projects.
 - Builder API: Register validator via HTTP REST Beacon API endpoint /eth/v1/validator/register_validator
 - Cross compilation support for Mac ARM64 chips (Mac M1, M2)
 
 ### Changed
 
-- **Require an execution client** `--execution-endpoint=...`. The default value has changed to `localhost:8551` and you must use the jwt flag `--jwt-secret=...`. Review [the docs](https://docs.prylabs.network/docs/prepare-for-merge) for more information 
-- `--http-web3provider` has been renamed to `--execution-endpoint`. Please update your configuration as `--http-web3provider` will be removed in a future release.
+- **Require an execution client** `--execution-endpoint=...`. The default value has changed to `localhost:8551` and you
+  must use the jwt flag `--jwt-secret=...`. Review [the docs](https://docs.prylabs.network/docs/prepare-for-merge) for
+  more information
+- `--http-web3provider` has been renamed to `--execution-endpoint`. Please update your configuration
+  as `--http-web3provider` will be removed in a future release.
 - Insert attestations into forkchoice sooner
-- Builder API: `gas_limit` changed from int to string to support JSON / YAML configs. `--suggested-gas-limit` changed from int to string.
+- Builder API: `gas_limit` changed from int to string to support JSON / YAML configs. `--suggested-gas-limit` changed
+  from int to string.
 - Fork choice: Improved handling of double locks / deadlocks
 - Lower libp2p log level
 - Improved re-org logs with additional metadata
@@ -1955,25 +2080,31 @@ There are no security updates in this release.
 - Protobuf message renaming (non-breaking changes)
 - Enabled feature to use gohashtree by default. Disable with `--disable-vectorized-htr`
 - Enabled fork choice doubly linked tree feature by default. Disable with `--disable-forkchoice-doubly-linked-tree`
-- Remote signer: Renamed some field names to better represent block types (non-breaking changes for gRPC users, possibly breaking change for JSON API users)
+- Remote signer: Renamed some field names to better represent block types (non-breaking changes for gRPC users, possibly
+  breaking change for JSON API users)
 - Builder API: require header and payload root match.
 - Improved responses for json-rpc requests batching when using blinded beacon blocks.
 - Builder API: Improved error messages
-- Builder API: Issue warning when validator expects builder ready beacon node, but beacon node is not configured with a relay.
+- Builder API: Issue warning when validator expects builder ready beacon node, but beacon node is not configured with a
+  relay.
 - Execution API: Improved payload ID to handle reorg scenarios
 
 ### Deprecated
 
-- Several features have been promoted to stable or removed. The following flags are now deprecated and will be removed in a future release. `--enable-db-backup-webhook`, `--bolt-mmap-initial-size`, `--disable-discv5`, `--disable-attesting-history-db-cache`, `--enable-vectorized-htr`, `--enable-peer-scorer`, `--enable-forkchoice-doubly-linked-tree`, `--enable-duty-count-down`, `--head-sync`, `--enable-gossip-batch-aggregateion`, `--enable-larger-gossip-history`, `--fallback-web3provider`, `--use-check-point-cache`.
+- Several features have been promoted to stable or removed. The following flags are now deprecated and will be removed
+  in a future
+  release. `--enable-db-backup-webhook`, `--bolt-mmap-initial-size`, `--disable-discv5`, `--disable-attesting-history-db-cache`, `--enable-vectorized-htr`, `--enable-peer-scorer`, `--enable-forkchoice-doubly-linked-tree`, `--enable-duty-count-down`, `--head-sync`, `--enable-gossip-batch-aggregateion`, `--enable-larger-gossip-history`, `--fallback-web3provider`, `--use-check-point-cache`.
 - Several beacon API endpoints marked as deprecated
 
 ### Removed
 
 - Logging: Removed phase0 fields from validator performance log messages
 - Deprecated slasher protos have been removed
-- Deprecated beacon API endpoints removed: `GetBeaconState`, `ProduceBlock`, `ListForkChoiceHeads`, `ListBlocks`, `SubmitValidatorRegistration`, `GetBlock`, `ProposeBlock`
+- Deprecated beacon API endpoints
+  removed: `GetBeaconState`, `ProduceBlock`, `ListForkChoiceHeads`, `ListBlocks`, `SubmitValidatorRegistration`, `GetBlock`, `ProposeBlock`
 - API: Forkchoice method `GetForkChoice` has been removed.
-- All previously deprecated feature flags have been removed. `--enable-active-balance-cache`, `--correctly-prune-canonical-atts`, `--correctly-insert-orphaned-atts`, `--enable-next-slot-state-cache`, `--enable-batch-gossip-verification`, `--enable-get-block-optimizations`, `--enable-balance-trie-computation`, `--disable-next-slot-state-cache`, `--attestation-aggregation-strategy`, `--attestation-aggregation-force-opt-maxcover`, `--pyrmont`, `--disable-get-block-optimizations`, `--disable-proposer-atts-selection-using-max-cover`, `--disable-optimized-balance-update`, `--disable-active-balance-cache`, `--disable-balance-trie-computation`, `--disable-batch-gossip-verification`, `--disable-correctly-prune-canonical-atts`, `--disable-correctly-insert-orphaned-atts`, `--enable-native-state`, `--enable-peer-scorer`, `--enable-gossip-batch-aggregation`, `--experimental-disable-boundry-checks`
+- All previously deprecated feature flags have been
+  removed. `--enable-active-balance-cache`, `--correctly-prune-canonical-atts`, `--correctly-insert-orphaned-atts`, `--enable-next-slot-state-cache`, `--enable-batch-gossip-verification`, `--enable-get-block-optimizations`, `--enable-balance-trie-computation`, `--disable-next-slot-state-cache`, `--attestation-aggregation-strategy`, `--attestation-aggregation-force-opt-maxcover`, `--pyrmont`, `--disable-get-block-optimizations`, `--disable-proposer-atts-selection-using-max-cover`, `--disable-optimized-balance-update`, `--disable-active-balance-cache`, `--disable-balance-trie-computation`, `--disable-batch-gossip-verification`, `--disable-correctly-prune-canonical-atts`, `--disable-correctly-insert-orphaned-atts`, `--enable-native-state`, `--enable-peer-scorer`, `--enable-gossip-batch-aggregation`, `--experimental-disable-boundry-checks`
 - Validator Web API: Removed unused ImportAccounts and DeleteAccounts rpc options
 
 ### Fixed
@@ -1990,44 +2121,50 @@ There are no security updates in this release.
 
 ## [v2.1.4](https://github.com/prysmaticlabs/prysm/compare/v2.1.4...v2.1.3) - 2022-08-10
 
-As we prepare our `v3` mainnet release for [The Merge](https://ethereum.org/en/upgrades/merge/), `v2.1.4` marks the end of the `v2` era. Node operators and validators are **highly encouraged** to upgrade to release `v2.1.4` - many bug fixes and improvements have been included in preparation for The Merge. `v3` will contain breaking changes, and will be released within the next few weeks. Using `v2.1.4` in the meantime will give you access to a more streamlined user experience. See our [v2.1.4 doc](https://docs.prylabs.network/docs/vnext/214-rc) to learn how to use v2.1.4 to run a Merge-ready configuration on the Goerli-Prater network pair.
+As we prepare our `v3` mainnet release for [The Merge](https://ethereum.org/en/upgrades/merge/), `v2.1.4` marks the end
+of the `v2` era. Node operators and validators are **highly encouraged** to upgrade to release `v2.1.4` - many bug fixes
+and improvements have been included in preparation for The Merge. `v3` will contain breaking changes, and will be
+released within the next few weeks. Using `v2.1.4` in the meantime will give you access to a more streamlined user
+experience. See our [v2.1.4 doc](https://docs.prylabs.network/docs/vnext/214-rc) to learn how to use v2.1.4 to run a
+Merge-ready configuration on the Goerli-Prater network pair.
 
 ### Added
 
 - Sepolia testnet configs `--sepolia`
-- Goerli as an alias to Prater and testnet configs `--prater` or `--goerli` 
+- Goerli as an alias to Prater and testnet configs `--prater` or `--goerli`
 - Fee recipient API for key manager
 - YML config flag support for web3 signer
-- Validator registration API for web3 signer 
+- Validator registration API for web3 signer
 - JSON tcontent type with optional metadata
-- Flashbots MEV boost support 
-- Store blind block (i.e block with payload header) instead of full block (i.e. block with payload) for storage efficiency (currently only available when the `enable-only-blinded-beacon-blocks` feature flag is enabled) 
-- Pcli utility support to print blinded block 
+- Flashbots MEV boost support
+- Store blind block (i.e block with payload header) instead of full block (i.e. block with payload) for storage
+  efficiency (currently only available when the `enable-only-blinded-beacon-blocks` feature flag is enabled)
+- Pcli utility support to print blinded block
 - New Web v2.0 release into Prysm
 
 ### Changed
 
-- Native state improvement is enabled by default 
-- Use native blocks instead of protobuf blocks 
+- Native state improvement is enabled by default
+- Use native blocks instead of protobuf blocks
 - Peer scorer is enabled by default
-- Enable fastssz to use vectorized HTR hash algorithm improvement 
+- Enable fastssz to use vectorized HTR hash algorithm improvement
 - Forkchoice store refactor and cleanups
-- Update libp2p library dependency 
-- RPC proposer duty is now allowed next epoch query 
+- Update libp2p library dependency
+- RPC proposer duty is now allowed next epoch query
 - Do not print traces with `log.withError(err)`
 - Testnets are running with pre-defined feature flags
 
 ### Removed
 
-- Deprecate Step Parameter from our Block By Range Requests 
+- Deprecate Step Parameter from our Block By Range Requests
 
 ### Fixed
 
-- Ignore nil forkchoice node when saving orphaned atts 
-- Sync: better handling of missing state summary in DB 
-- Validator: creates invalid terminal block using the same timestamp as payload 
-- P2P: uses incorrect goodbye codes 
-- P2p: defaults Incorrectly to using Mplex, which results in losing Teku peers 
+- Ignore nil forkchoice node when saving orphaned atts
+- Sync: better handling of missing state summary in DB
+- Validator: creates invalid terminal block using the same timestamp as payload
+- P2P: uses incorrect goodbye codes
+- P2p: defaults Incorrectly to using Mplex, which results in losing Teku peers
 - Disable returning future state for API
 - Eth1 connection API panic
 
@@ -2041,14 +2178,15 @@ There are no security updates in this release.
 
 - Many fuzz test additions
 - Support bellatrix blocks with web3signer
-- Support for the Sepolia testnet with `--terminal-total-difficulty-override 17000000000000000`. The override flag is required in this release.
+- Support for the Sepolia testnet with `--terminal-total-difficulty-override 17000000000000000`. The override flag is
+  required in this release.
 - Support for the Ropsten testnet. No override flag required
 - JSON API allows SSZ-serialized blocks in `publishBlock`
 - JSON API allows SSZ-serialized blocks in `publishBlindedBlock`
 - JSON API allows SSZ-serialized requests in `produceBlockV2` and `produceBlindedBlock`
 - Progress towards Builder API and MEV boost support (not ready for testing in this release)
 - Support for `DOMAIN_APPLICATION_MARK` configuration
-- Ignore subset aggregates if a better aggregate has been seen already 
+- Ignore subset aggregates if a better aggregate has been seen already
 - Reinsertion of reorg'd attestations
 - Command `beacon-chain generate-auth-secret` to assist with generating a hex encoded secret for engine API
 - Return optimistic status to `ChainHead` related grpc service
@@ -2058,7 +2196,7 @@ There are no security updates in this release.
 ### Changed
 
 - Improvements to forkchoice
-- Invalid checksummed (or no checksum) addresses used for fee recipient will log a warning. fixes, 
+- Invalid checksummed (or no checksum) addresses used for fee recipient will log a warning. fixes,
 - Use cache backed `getBlock` method in several places of blockchain package
 - Reduced log frequency of "beacon node doesn't have a parent in db with root" error
 - Improved nil checks for state management
@@ -2068,26 +2206,27 @@ There are no security updates in this release.
 - Handle connection closing for web3/eth1 nil connection
 - Testing improvements
 - E2E test improvements
-- Increase file descriptor limit up to the maximum by default 
+- Increase file descriptor limit up to the maximum by default
 - Improved classification of "bad blocks"
 - Updated engine API error code handling
 - Improved "Synced new block" message to include minimal information based on the log verbosity.
 - Add nil checks for nil finalized checkpoints
-- Change weak subjectivity sync to use the most recent finalized state rather than the oldest state within the current period.
+- Change weak subjectivity sync to use the most recent finalized state rather than the oldest state within the current
+  period.
 - Ensure a finalized root can't be all zeros
-- Improved db lookup of HighestSlotBlocksBelow to start from the end of the index rather than the beginning. 
+- Improved db lookup of HighestSlotBlocksBelow to start from the end of the index rather than the beginning.
 - Improved packing of state balances for hashtreeroot
 - Improved field trie recomputation
 
 ### Removed
 
--  Removed handling of `INVALID_TERMINAL_BLOCK` response from engine API 
+- Removed handling of `INVALID_TERMINAL_BLOCK` response from engine API
 
 ### Fixed
 
 - `/eth/v1/beacon/blinded_blocks` JSON API endpoint
 - SSZ handling of JSON API payloads
-- Config registry fixes 
+- Config registry fixes
 - Withdrawal epoch overflows
 - Race condition with blockchain service Head()
 - Race condition with validator's highest valid slot accessor
@@ -2120,11 +2259,12 @@ There are no security updates in this release.
 ### Removed
 
 - Prymont testnet support
-- Flag `disable-proposer-atts-selection-using-max-cover` which disables defaulting max cover strategy for proposer selecting attestations
+- Flag `disable-proposer-atts-selection-using-max-cover` which disables defaulting max cover strategy for proposer
+  selecting attestations
 - Flag `disable-get-block-optimizations` which disables optimization with beacon block construction
 - Flag `disable-optimized-balance-update"` which disables optimized effective balance update
 - Flag `disable-active-balance-cache` which disables active balance cache
-- Flag `disable-balance-trie-computation` which disables balance trie optimization for hash tree root 
+- Flag `disable-balance-trie-computation` which disables balance trie optimization for hash tree root
 - Flag `disable-batch-gossip-verification` which disables batch gossip verification
 - Flag `disable-correctly-insert-orphaned-atts` which disables the fix for orphaned attestations insertion
 
@@ -2144,45 +2284,54 @@ This patch release includes 3 cherry picked fixes for regressions found in v2.1.
 
 View the full changelist from v2.1.0: https://github.com/prysmaticlabs/prysm/compare/v2.1.0...v2.1.1
 
-If upgrading from v2.0.6, please review the [full changelist](https://github.com/prysmaticlabs/prysm/compare/v2.0.6...v2.1.1) of both v2.1.0 and v2.1.1.
+If upgrading from v2.0.6, please review
+the [full changelist](https://github.com/prysmaticlabs/prysm/compare/v2.0.6...v2.1.1) of both v2.1.0 and v2.1.1.
 
 This release is required for users on v2.1.0 and recommended for anyone on v2.0.6.
 
 The following known issues exist in v2.1.0 and also exist in this release.
-    
-- Erroneous warning message in validator client when bellatrix fee recipient is unset. This is a cosmetic message and does not affect run time behavior in Phase0/Altair. 
+
+- Erroneous warning message in validator client when bellatrix fee recipient is unset. This is a cosmetic message and
+  does not affect run time behavior in Phase0/Altair.
 - In Bellatrix/Kiln: Fee recipient flags may not work as expected. See for a fix and more details.
 
 ### Fixed
 
-- Doppelganger false positives may have caused a failure to start in the validator client. 
-- Connections to execution layer clients were not properly cleaned up and lead to resource leaks when using ipc. 
-- Initial sync (or resync when beacon node falls out of sync) could lead to a panic. 
+- Doppelganger false positives may have caused a failure to start in the validator client.
+- Connections to execution layer clients were not properly cleaned up and lead to resource leaks when using ipc.
+- Initial sync (or resync when beacon node falls out of sync) could lead to a panic.
 
 ### Security
 
 There are no security updates in this release.
 
-## [v2.1.0](https://github.com/prysmaticlabs/prysm/compare/v2.0.6...v2.1.0) - 2022-04-26 
+## [v2.1.0](https://github.com/prysmaticlabs/prysm/compare/v2.0.6...v2.1.0) - 2022-04-26
 
 There are two known issues with this release:
 
-- Erroneous warning message in validator client when bellatrix fee recipient is unset. This is a cosmetic message and does not affect run time behavior in Phase0/Altair. 
+- Erroneous warning message in validator client when bellatrix fee recipient is unset. This is a cosmetic message and
+  does not affect run time behavior in Phase0/Altair.
 - In Bellatrix/Kiln: Fee recipient flags may not work as expected. See for a fix and more details.
 
 ### Added
 
-- Web3Signer support. See the [documentation](https://docs.prylabs.network/docs/next/wallet/web3signer) for more details.
+- Web3Signer support. See the [documentation](https://docs.prylabs.network/docs/next/wallet/web3signer) for more
+  details.
 - Bellatrix support. See [kiln testnet instructions](https://hackmd.io/OqIoTiQvS9KOIataIFksBQ?view)
-- Weak subjectivity sync / checkpoint sync. This is an experimental feature and may have unintended side effects for certain operators serving historical data. See the [documentation](https://docs.prylabs.network/docs/next/prysm-usage/checkpoint-sync) for more details.
-- A faster build of blst for beacon chain on linux amd64. Use the environment variable `USE_PRYSM_MODERN=true` with prysm.sh, use the "modern" binary, or bazel build with `--define=blst_modern=true`.
+- Weak subjectivity sync / checkpoint sync. This is an experimental feature and may have unintended side effects for
+  certain operators serving historical data. See
+  the [documentation](https://docs.prylabs.network/docs/next/prysm-usage/checkpoint-sync) for more details.
+- A faster build of blst for beacon chain on linux amd64. Use the environment variable `USE_PRYSM_MODERN=true` with
+  prysm.sh, use the "modern" binary, or bazel build with `--define=blst_modern=true`.
 - Vectorized sha256. This may have performance improvements with use of the new flag `--enable-vectorized-htr`.
-- A new forkchoice structure that uses a doubly linked tree implementation. Try this feature with the flag `--enable-forkchoice-doubly-linked-tree`
+- A new forkchoice structure that uses a doubly linked tree implementation. Try this feature with the
+  flag `--enable-forkchoice-doubly-linked-tree`
 - Fork choice proposer boost is implemented and enabled by default. See PR description for more details.
 
 ### Changed
 
-- **Flag Default Change** The default value for `--http-web3provider` is now `localhost:8545`. Previously was empty string.
+- **Flag Default Change** The default value for `--http-web3provider` is now `localhost:8545`. Previously was empty
+  string.
 - Updated spectest compliance to v1.1.10.
 - Updated to bazel 5.0.0
 - Gossip peer scorer is now part of the `--dev` flag.
@@ -2193,7 +2342,8 @@ There are two known issues with this release:
 
 ### Fixed
 
-Too many bug fixes and improvements to mention all of them. See the [full changelist](https://github.com/prysmaticlabs/prysm/compare/v2.0.6...v2.1.0)
+Too many bug fixes and improvements to mention all of them. See
+the [full changelist](https://github.com/prysmaticlabs/prysm/compare/v2.0.6...v2.1.0)
 
 ### Security
 
@@ -2285,7 +2435,9 @@ There are no security updates in this release.
 
 ### Deprecated
 
-Please be advised that Prysm's package path naming will change in the next release. If you are a downstream user of Prysm (i.e. import prysm libraries into your project) then you may be impacted. Please see issue https://github.com/prysmaticlabs/prysm/issues/10006.
+Please be advised that Prysm's package path naming will change in the next release. If you are a downstream user of
+Prysm (i.e. import prysm libraries into your project) then you may be impacted. Please see
+issue https://github.com/prysmaticlabs/prysm/issues/10006.
 
 ### Fixed
 
@@ -2314,7 +2466,8 @@ Please be advised that Prysm's package path naming will change in the next relea
 
 ### Fixed
 
-- Revert PR [9830](https://github.com/prysmaticlabs/prysm/pull/9830) to remove performance regression. See: issue [9935](https://github.com/prysmaticlabs/prysm/issues/9935)
+- Revert PR [9830](https://github.com/prysmaticlabs/prysm/pull/9830) to remove performance regression. See:
+  issue [9935](https://github.com/prysmaticlabs/prysm/issues/9935)
 
 ### Security
 
@@ -2322,7 +2475,8 @@ No security updates in this release.
 
 ## [v2.0.3](https://github.com/prysmaticlabs/prysm/compare/v2.0.2...v2.0.3) - 2021-11-22
 
-This release also includes a major update to the web UI. Please review the v1 web UI notes [here](https://github.com/prysmaticlabs/prysm-web-ui/releases/tag/v1.0.0)
+This release also includes a major update to the web UI. Please review the v1 web UI
+notes [here](https://github.com/prysmaticlabs/prysm-web-ui/releases/tag/v1.0.0)
 
 ### Added
 
@@ -2380,7 +2534,8 @@ This release also includes a major update to the web UI. Please review the v1 we
 
 ### Removed
 
-- Prysmatic Labs' [go-ethereum fork](https://github.com/prysmaticlabs/bazel-go-ethereum) removed from build tooling. Upstream go-ethereum is now used with familiar go.mod tooling.
+- Prysmatic Labs' [go-ethereum fork](https://github.com/prysmaticlabs/bazel-go-ethereum) removed from build tooling.
+  Upstream go-ethereum is now used with familiar go.mod tooling.
 - Removed duplicate aggergation validation p2p pipelines.
 - Metrics calculation removed extra condition
 - Removed superflous errors from peer scoring parameters registration
@@ -2391,7 +2546,8 @@ This release also includes a major update to the web UI. Please review the v1 we
 - Ignore validators without committee assignment when fetching attester duties
 - Return "version" field for ssz blocks in beacon API
 - Fixed bazel build transitions for dbg builds. Allows IDEs to hook into debugger again.
-- Fixed case where GetDuties RPC endpoint might return a false positive for sync committee selection for validators that have no deposited yet
+- Fixed case where GetDuties RPC endpoint might return a false positive for sync committee selection for validators that
+  have no deposited yet
 - Fixed validator exits in v1 method, broadcast correct object
 - Fix Altair individual votes endpoint
 - Validator performance calculations fixed
@@ -2400,7 +2556,7 @@ This release also includes a major update to the web UI. Please review the v1 we
 - Fix stategen with genesis state.
 - Fixed multiple typos
 - Fix genesis state registration in interop mode
-- Fix network flags in slashing protection export  
+- Fix network flags in slashing protection export
 
 ### Security
 
@@ -2410,7 +2566,9 @@ This release also includes a major update to the web UI. Please review the v1 we
 
 ### Added
 
-- Optimizations to block proposals. Enabled with `--enable-get-block-optimizations`. See [issue 8943](https://github.com/prysmaticlabs/prysm/issues/8943) and [issue 9708](https://github.com/prysmaticlabs/prysm/issues/9708) before enabling.
+- Optimizations to block proposals. Enabled with `--enable-get-block-optimizations`.
+  See [issue 8943](https://github.com/prysmaticlabs/prysm/issues/8943)
+  and [issue 9708](https://github.com/prysmaticlabs/prysm/issues/9708) before enabling.
 - Beacon Standard API: register v1alpha2 endpoints
 
 ### Changed
@@ -2458,64 +2616,87 @@ We've updated the Prysm base docker images to a more recent build.
 
 ## [v2.0.0](https://github.com/prysmaticlabs/prysm/compare/v1.4.4...v2.0.0)
 
-This release is the largest release of Prysm to date. v2.0.0 includes support for the upcoming Altair hard fork on the mainnet Ethereum Beacon Chain.
-This release consists of [380 changes](https://github.com/prysmaticlabs/prysm/compare/v1.4.4...f7845afa575963302116e673d400d2ab421252ac) to support Altair, improve performance of phase0 beacon nodes, and various bug fixes from v1.4.4.
+This release is the largest release of Prysm to date. v2.0.0 includes support for the upcoming Altair hard fork on the
+mainnet Ethereum Beacon Chain.
+This release consists
+of [380 changes](https://github.com/prysmaticlabs/prysm/compare/v1.4.4...f7845afa575963302116e673d400d2ab421252ac) to
+support Altair, improve performance of phase0 beacon nodes, and various bug fixes from v1.4.4.
 
 ### Upgrading From v1
 
-Please update your beacon node to v2.0.0 prior to updating your validator. The beacon node can serve requests to a v1.4.4 validator, however a v2.0.0 validator will not start against a v1.4.4 beacon node. If you're operating a highly available beacon chain service, ensure that all of your beacon nodes are updated to v2.0.0 before starting the upgrade on your validators.
+Please update your beacon node to v2.0.0 prior to updating your validator. The beacon node can serve requests to a
+v1.4.4 validator, however a v2.0.0 validator will not start against a v1.4.4 beacon node. If you're operating a highly
+available beacon chain service, ensure that all of your beacon nodes are updated to v2.0.0 before starting the upgrade
+on your validators.
 
 ### Added
 
-- Full Altair support. [Learn more about Altair.](https://github.com/ethereum/annotated-spec/blob/8473024d745a3a2b8a84535d57773a8e86b66c9a/altair/beacon-chain.md)
+- Full Altair
+  support. [Learn more about Altair.](https://github.com/ethereum/annotated-spec/blob/8473024d745a3a2b8a84535d57773a8e86b66c9a/altair/beacon-chain.md)
 - Added bootnodes from the Nimbus team.
-- Revamped slasher implementation. The slasher functionality is no longer a standalone binary. Slasher functionality is available from the beacon node with the `--slasher` flag. Note: Running the slasher has considerably increased resource requirements. Be sure to review the latest documentation before enabling this feature. This feature is experimental.
+- Revamped slasher implementation. The slasher functionality is no longer a standalone binary. Slasher functionality is
+  available from the beacon node with the `--slasher` flag. Note: Running the slasher has considerably increased
+  resource requirements. Be sure to review the latest documentation before enabling this feature. This feature is
+  experimental.
 - Support for standard JSON API in the beacon node. Prysm validators continue to use Prysm's API.
-- Configurable subnet peer requirements. Increased minimum desired peers per subnet from 4 to 6. This can be modified with `--minimum-peers-per-subnet` in the beacon node..
+- Configurable subnet peer requirements. Increased minimum desired peers per subnet from 4 to 6. This can be modified
+  with `--minimum-peers-per-subnet` in the beacon node..
 - Support for go build on darwin_arm64 devices (Mac M1 chips). Cross compiling for darwin_arm64 is not yet supported..
 - Batch verification of pubsub objects. This should improve pubsub processing performance on multithreaded machines.
-- Improved attestation pruning. This feature should improve block proposer performance and overall network attestation inclusion rates. Opt-out with `--disable-correctly-prune-canonical-atts` in the beacon node.
+- Improved attestation pruning. This feature should improve block proposer performance and overall network attestation
+  inclusion rates. Opt-out with `--disable-correctly-prune-canonical-atts` in the beacon node.
 - Active balance cache to improve epoch processing. Opt-out with `--disable-active-balance-cache`
-- Experimental database improvements to reduce history state entry space usage in the beaconchain.db. This functionality can be permanently enabled with the flag `--enable-historical-state-representation`. Enabling this feature can realize a 25% improvement in space utilization for the average user , while 70 -80% for power users(archival node operators). Note: once this feature is toggled on, it modifies the structure of the database with a migration and cannot be rolled back. This feature is experimental and should only be used in non-serving beacon nodes in case of database corruption or other critical issue.
+- Experimental database improvements to reduce history state entry space usage in the beaconchain.db. This functionality
+  can be permanently enabled with the flag `--enable-historical-state-representation`. Enabling this feature can realize
+  a 25% improvement in space utilization for the average user , while 70 -80% for power users(archival node operators).
+  Note: once this feature is toggled on, it modifies the structure of the database with a migration and cannot be rolled
+  back. This feature is experimental and should only be used in non-serving beacon nodes in case of database corruption
+  or other critical issue.
 
 #### New Metrics
 
 **Beacon chain node**
 
-| Metric                                           | Description                                                                                           | References  |
-|--------------------------------------------------|-------------------------------------------------------------------------------------------------------|-------------|
-| `p2p_message_ignored_validation_total`           | Count of messages that were ignored in validation                                                     |       |
-| `beacon_current_active_validators`               | Current total active validators                                                                       |       |
-| `beacon_processed_deposits_total`                | Total number of deposits processed                                                                    |       |
-| `sync_head_state_miss`                           | The number of sync head state requests that are not present in the cache                              |       |
-| `sync_head_state_hit`                            | The number of sync head state requests that are present in the cache                                  |       |
-| `total_effective_balance_cache_miss`             | The number of get requests that are not present in the cache                                          |       |
-| `total_effective_balance_cache_hit`              | The number of get requests that are present in the cache                                              |       |
-| `sync_committee_index_cache_miss_total`          | The number of committee requests that aren't present in the sync committee index cache                |       |
-| `sync_committee_index_cache_hit_total`           | The number of committee requests that are present in the sync committee index cache                   |       |
-| `next_slot_cache_hit`                            | The number of cache hits on the next slot state cache                                                 |       |
-| `next_slot_cache_miss`                           | The number of cache misses on the next slot state cache                                               |       |
-| `validator_entry_cache_hit_total`                | The number of cache hits on the validator entry cache                                                 | |
-| `validator_entry_cache_miss_total`               | The number of cache misses on the validator entry cache                                               | |
-| `validator_entry_cache_delete_total`             | The number of cache deletes on the validator entry cache                                              |       |
-| `saved_sync_committee_message_total`             | The number of saved sync committee message total                                                      |       |
-| `saved_sync_committee_contribution_total`        | The number of saved sync committee contribution total                                                 |       |
-| `libp2p_peers`                                   | Tracks the total number of libp2p peers                                                               |       |
-| `p2p_status_message_missing`                     | The number of attempts the connection handler rejects a peer for a missing status message             |       |
-| `p2p_sync_committee_subnet_recovered_broadcasts` | The number of sync committee messages that were attempted to be broadcast with no peers on the subnet |       |
-| `p2p_sync_committee_subnet_attempted_broadcasts` | The number of sync committees that were attempted to be broadcast                                     |       |
-| `p2p_subscribed_topic_peer_total`                | The number of peers subscribed to topics that a host node is also subscribed to                       |       |
-| `saved_orphaned_att_total`                       | Count the number of times an orphaned attestation is saved                                            |       |
+| Metric                                           | Description                                                                                           | References |
+|--------------------------------------------------|-------------------------------------------------------------------------------------------------------|------------|
+| `p2p_message_ignored_validation_total`           | Count of messages that were ignored in validation                                                     |            |
+| `beacon_current_active_validators`               | Current total active validators                                                                       |            |
+| `beacon_processed_deposits_total`                | Total number of deposits processed                                                                    |            |
+| `sync_head_state_miss`                           | The number of sync head state requests that are not present in the cache                              |            |
+| `sync_head_state_hit`                            | The number of sync head state requests that are present in the cache                                  |            |
+| `total_effective_balance_cache_miss`             | The number of get requests that are not present in the cache                                          |            |
+| `total_effective_balance_cache_hit`              | The number of get requests that are present in the cache                                              |            |
+| `sync_committee_index_cache_miss_total`          | The number of committee requests that aren't present in the sync committee index cache                |            |
+| `sync_committee_index_cache_hit_total`           | The number of committee requests that are present in the sync committee index cache                   |            |
+| `next_slot_cache_hit`                            | The number of cache hits on the next slot state cache                                                 |            |
+| `next_slot_cache_miss`                           | The number of cache misses on the next slot state cache                                               |            |
+| `validator_entry_cache_hit_total`                | The number of cache hits on the validator entry cache                                                 |            |
+| `validator_entry_cache_miss_total`               | The number of cache misses on the validator entry cache                                               |            |
+| `validator_entry_cache_delete_total`             | The number of cache deletes on the validator entry cache                                              |            |
+| `saved_sync_committee_message_total`             | The number of saved sync committee message total                                                      |            |
+| `saved_sync_committee_contribution_total`        | The number of saved sync committee contribution total                                                 |            |
+| `libp2p_peers`                                   | Tracks the total number of libp2p peers                                                               |            |
+| `p2p_status_message_missing`                     | The number of attempts the connection handler rejects a peer for a missing status message             |            |
+| `p2p_sync_committee_subnet_recovered_broadcasts` | The number of sync committee messages that were attempted to be broadcast with no peers on the subnet |            |
+| `p2p_sync_committee_subnet_attempted_broadcasts` | The number of sync committees that were attempted to be broadcast                                     |            |
+| `p2p_subscribed_topic_peer_total`                | The number of peers subscribed to topics that a host node is also subscribed to                       |            |
+| `saved_orphaned_att_total`                       | Count the number of times an orphaned attestation is saved                                            |            |
 
 ### Changed
 
 - Much refactoring of "util" packages into more canonical packages. Please review Prysm package structure and godocs.
-- Altair object keys in beacon-chain/db/kv are prefixed with "altair". BeaconBlocks and BeaconStates are the only objects affected by database key changes for Altair. This affects any third party tooling directly querying Prysm's beaconchain.db.
+- Altair object keys in beacon-chain/db/kv are prefixed with "altair". BeaconBlocks and BeaconStates are the only
+  objects affected by database key changes for Altair. This affects any third party tooling directly querying Prysm's
+  beaconchain.db.
 - Updated Teku bootnodes.
 - Updated Lighthouse bootnodes.
 - End to end testing now collects jaeger spans
 - Improvements to experimental peer quality scoring. This feature is only enabled with `--enable-peer-scorer`.
-- Validator performance logging behavior has changed in Altair. Post-Altair hardfork has the following changes: Inclusion distance and inclusion slots will no longer be displayed. Correctly voted target will only be true if also included within 32 slots. Correctly voted head will only be true if the attestation was included in the next slot. Correctly voted source will only be true if attestation is included within 5 slots. Inactivity score will be displayed.
+- Validator performance logging behavior has changed in Altair. Post-Altair hardfork has the following changes:
+  Inclusion distance and inclusion slots will no longer be displayed. Correctly voted target will only be true if also
+  included within 32 slots. Correctly voted head will only be true if the attestation was included in the next slot.
+  Correctly voted source will only be true if attestation is included within 5 slots. Inactivity score will be
+  displayed.
 - Increased pubsub message queue size from 256 to 600 to support larger networks and higher message volume.
 - The default attestation aggregation changed to the improved optimized max cover algorithm.
 - Prysm is passing spectests at v1.1.0 (latest available release).
@@ -2528,13 +2709,15 @@ Please update your beacon node to v2.0.0 prior to updating your validator. The b
 #### Changed Metrics
 
 **Beacon chain node**
-| Metric                | Old Name             | Description                                          | References |
+| Metric | Old Name | Description | References |
 |-----------------------|----------------------|------------------------------------------------------|------------|
-| `beacon_reorgs_total` | `beacon_reorg_total` | Count the number of times a beacon chain has a reorg |      |
+| `beacon_reorgs_total` | `beacon_reorg_total` | Count the number of times a beacon chain has a reorg | |
 
 ### Deprecated
 
-These flags are hidden from the help text and no longer modify the behavior of Prysm. These flags should be removed from user runtime configuration as the flags will eventually be removed entirely and Prysm will fail to start if a deleted or unknown flag is provided.
+These flags are hidden from the help text and no longer modify the behavior of Prysm. These flags should be removed from
+user runtime configuration as the flags will eventually be removed entirely and Prysm will fail to start if a deleted or
+unknown flag is provided.
 
 - `--enable-active-balance-cache`
 - `--correctly-prune-canonical-atts`
@@ -2546,17 +2729,24 @@ These flags are hidden from the help text and no longer modify the behavior of P
 Note: Removed flags will block starting up with an error "flag provided but not defined:".
 Please check that you are not using any of the removed flags in this section!
 
-- Prysm's standalone slasher application (cmd/slasher) has been fully removed. Use the `--slasher` flag with a beacon chain node for full slasher functionality.
-- `--disable-blst` (beacon node and validator). [blst](https://github.com/supranational/blst) is the only BLS library offered for Prysm.
-- `--disable-sync-backtracking` and `--enable-sync-backtracking` (beacon node). This feature has been released for some time. See.
+- Prysm's standalone slasher application (cmd/slasher) has been fully removed. Use the `--slasher` flag with a beacon
+  chain node for full slasher functionality.
+- `--disable-blst` (beacon node and validator). [blst](https://github.com/supranational/blst) is the only BLS library
+  offered for Prysm.
+- `--disable-sync-backtracking` and `--enable-sync-backtracking` (beacon node). This feature has been released for some
+  time. See.
 - `--diable-pruning-deposit-proofs` (beacon node). This feature has been released for some time. See.
 - `--disable-eth1-data-majority-vote` (beacon node). This feature is no longer in use in Prysm. See,.
 - `--proposer-atts-selection-using-max-cover` (beacon node). This feature has been released for some time. See.
 - `--update-head-timely` (beacon node). This feature was released in v1.4.4. See.
 - `--enable-optimized-balance-update` (beacon node). This feature was released in v1.4.4. See.
-- Kafka support is no longer available in the beacon node. This functionality was never fully completed and did not fulfill many desirable use cases. This removed the flag `--kafka-url` (beacon node). See.
-- Removed tools/faucet. Use the faucet in [prysmaticlabs/periphery](https://github.com/prysmaticlabs/periphery/tree/c2ac600882c37fc0f2a81b0508039124fb6bcf47/eth-faucet) if operating a testnet faucet server.
-- Tooling for prior testnet contracts has been removed. Any of the old testnet contracts with `drain()` function have been removed as well.
+- Kafka support is no longer available in the beacon node. This functionality was never fully completed and did not
+  fulfill many desirable use cases. This removed the flag `--kafka-url` (beacon node). See.
+- Removed tools/faucet. Use the faucet
+  in [prysmaticlabs/periphery](https://github.com/prysmaticlabs/periphery/tree/c2ac600882c37fc0f2a81b0508039124fb6bcf47/eth-faucet)
+  if operating a testnet faucet server.
+- Tooling for prior testnet contracts has been removed. Any of the old testnet contracts with `drain()` function have
+  been removed as well.
 - Toledo tesnet config is removed.
 - Removed --eth-api-port (beacon node). All APIs interactions have been moved to --grpc-gateway-port. See.
 
@@ -2574,10 +2764,14 @@ Please check that you are not using any of the removed flags in this section!
 
 ### Security
 
-- You MUST update to v2.0.0 or later release before epoch 74240 or your client will fork off from the rest of the network.
-- Prysm's JWT library has been updated to a maintained version of the previous JWT library. JWTs are only used in the UI.
+- You MUST update to v2.0.0 or later release before epoch 74240 or your client will fork off from the rest of the
+  network.
+- Prysm's JWT library has been updated to a maintained version of the previous JWT library. JWTs are only used in the
+  UI.
+
+Please review our newly
+updated [security reporting policy](https://github.com/prysmaticlabs/prysm/blob/develop/SECURITY.md).
 
-Please review our newly updated [security reporting policy](https://github.com/prysmaticlabs/prysm/blob/develop/SECURITY.md).
 - Fix subcommands such as validator accounts list
 
 ### Security
diff --git a/api/server/structs/BUILD.bazel b/api/server/structs/BUILD.bazel
index df11af3b0221..cbe01272a175 100644
--- a/api/server/structs/BUILD.bazel
+++ b/api/server/structs/BUILD.bazel
@@ -6,6 +6,7 @@ go_library(
         "block.go",
         "conversions.go",
         "conversions_block.go",
+        "conversions_lightclient.go",
         "conversions_state.go",
         "endpoints_beacon.go",
         "endpoints_blob.go",
diff --git a/api/server/structs/conversions_lightclient.go b/api/server/structs/conversions_lightclient.go
new file mode 100644
index 000000000000..aa780a37ac30
--- /dev/null
+++ b/api/server/structs/conversions_lightclient.go
@@ -0,0 +1,3 @@
+package structs
+
+//
diff --git a/api/server/structs/endpoints_lightclient.go b/api/server/structs/endpoints_lightclient.go
index 9ef4a3880a67..0abf361c44f0 100644
--- a/api/server/structs/endpoints_lightclient.go
+++ b/api/server/structs/endpoints_lightclient.go
@@ -1,28 +1,42 @@
 package structs
 
+import "encoding/json"
+
 type LightClientHeader struct {
 	Beacon *BeaconBlockHeader `json:"beacon"`
 }
 
-type LightClientBootstrapResponse struct {
-	Version string                `json:"version"`
-	Data    *LightClientBootstrap `json:"data"`
+type LightClientHeaderCapella struct {
+	Beacon          *BeaconBlockHeader             `json:"beacon"`
+	Execution       *ExecutionPayloadHeaderCapella `json:"execution"`
+	ExecutionBranch []string                       `json:"execution_branch"`
+}
+
+type LightClientHeaderDeneb struct {
+	Beacon          *BeaconBlockHeader           `json:"beacon"`
+	Execution       *ExecutionPayloadHeaderDeneb `json:"execution"`
+	ExecutionBranch []string                     `json:"execution_branch"`
 }
 
 type LightClientBootstrap struct {
-	Header                     *LightClientHeader `json:"header"`
-	CurrentSyncCommittee       *SyncCommittee     `json:"current_sync_committee"`
-	CurrentSyncCommitteeBranch []string           `json:"current_sync_committee_branch"`
+	Header                     json.RawMessage `json:"header"`
+	CurrentSyncCommittee       *SyncCommittee  `json:"current_sync_committee"`
+	CurrentSyncCommitteeBranch []string        `json:"current_sync_committee_branch"`
+}
+
+type LightClientBootstrapResponse struct {
+	Version string                `json:"version"`
+	Data    *LightClientBootstrap `json:"data"`
 }
 
 type LightClientUpdate struct {
-	AttestedHeader          *LightClientHeader `json:"attested_header"`
-	NextSyncCommittee       *SyncCommittee     `json:"next_sync_committee,omitempty"`
-	FinalizedHeader         *LightClientHeader `json:"finalized_header,omitempty"`
-	SyncAggregate           *SyncAggregate     `json:"sync_aggregate"`
-	NextSyncCommitteeBranch []string           `json:"next_sync_committee_branch,omitempty"`
-	FinalityBranch          []string           `json:"finality_branch,omitempty"`
-	SignatureSlot           string             `json:"signature_slot"`
+	AttestedHeader          json.RawMessage `json:"attested_header"`
+	NextSyncCommittee       *SyncCommittee  `json:"next_sync_committee,omitempty"`
+	FinalizedHeader         json.RawMessage `json:"finalized_header,omitempty"`
+	SyncAggregate           *SyncAggregate  `json:"sync_aggregate"`
+	NextSyncCommitteeBranch []string        `json:"next_sync_committee_branch,omitempty"`
+	FinalityBranch          []string        `json:"finality_branch,omitempty"`
+	SignatureSlot           string          `json:"signature_slot"`
 }
 
 type LightClientUpdateWithVersion struct {
diff --git a/beacon-chain/core/light-client/BUILD.bazel b/beacon-chain/core/light-client/BUILD.bazel
index 1643fdff3184..094c8782a2f6 100644
--- a/beacon-chain/core/light-client/BUILD.bazel
+++ b/beacon-chain/core/light-client/BUILD.bazel
@@ -7,13 +7,20 @@ go_library(
     visibility = ["//visibility:public"],
     deps = [
         "//beacon-chain/state:go_default_library",
+        "//config/fieldparams:go_default_library",
         "//config/params:go_default_library",
+        "//consensus-types:go_default_library",
+        "//consensus-types/blocks:go_default_library",
         "//consensus-types/interfaces:go_default_library",
         "//encoding/bytesutil:go_default_library",
+        "//encoding/ssz:go_default_library",
+        "//proto/engine/v1:go_default_library",
         "//proto/eth/v1:go_default_library",
         "//proto/eth/v2:go_default_library",
         "//proto/migration:go_default_library",
+        "//runtime/version:go_default_library",
         "//time/slots:go_default_library",
+        "@com_github_pkg_errors//:go_default_library",
     ],
 )
 
diff --git a/beacon-chain/core/light-client/lightclient.go b/beacon-chain/core/light-client/lightclient.go
index d0038af7b3a1..c572a6325c29 100644
--- a/beacon-chain/core/light-client/lightclient.go
+++ b/beacon-chain/core/light-client/lightclient.go
@@ -4,12 +4,19 @@ import (
 	"bytes"
 	"fmt"
 
+	"github.com/pkg/errors"
 	"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
+	fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
 	"github.com/prysmaticlabs/prysm/v5/config/params"
+	consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types"
+	"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
 	"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
+	"github.com/prysmaticlabs/prysm/v5/encoding/ssz"
+	enginev1 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
 	ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
 	ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
 	"github.com/prysmaticlabs/prysm/v5/proto/migration"
+	"github.com/prysmaticlabs/prysm/v5/runtime/version"
 	"github.com/prysmaticlabs/prysm/v5/time/slots"
 
 	"context"
@@ -32,13 +39,15 @@ const (
 //	    signature_slot=update.signature_slot,
 //	)
 func CreateLightClientFinalityUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2.LightClientFinalityUpdate {
-	return &ethpbv2.LightClientFinalityUpdate{
+	finalityUpdate := &ethpbv2.LightClientFinalityUpdate{
 		AttestedHeader:  update.AttestedHeader,
 		FinalizedHeader: update.FinalizedHeader,
 		FinalityBranch:  update.FinalityBranch,
 		SyncAggregate:   update.SyncAggregate,
 		SignatureSlot:   update.SignatureSlot,
 	}
+
+	return finalityUpdate
 }
 
 // CreateLightClientOptimisticUpdate - implements https://github.com/ethereum/consensus-specs/blob/3d235740e5f1e641d3b160c8688f26e7dc5a1894/specs/altair/light-client/full-node.md#create_light_client_optimistic_update
@@ -50,11 +59,13 @@ func CreateLightClientFinalityUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2
 //	    signature_slot=update.signature_slot,
 //	)
 func CreateLightClientOptimisticUpdate(update *ethpbv2.LightClientUpdate) *ethpbv2.LightClientOptimisticUpdate {
-	return &ethpbv2.LightClientOptimisticUpdate{
+	optimisticUpdate := &ethpbv2.LightClientOptimisticUpdate{
 		AttestedHeader: update.AttestedHeader,
 		SyncAggregate:  update.SyncAggregate,
 		SignatureSlot:  update.SignatureSlot,
 	}
+
+	return optimisticUpdate
 }
 
 func NewLightClientOptimisticUpdateFromBeaconState(
@@ -71,7 +82,7 @@ func NewLightClientOptimisticUpdateFromBeaconState(
 	// assert sum(block.message.body.sync_aggregate.sync_committee_bits) >= MIN_SYNC_COMMITTEE_PARTICIPANTS
 	syncAggregate, err := block.Block().Body().SyncAggregate()
 	if err != nil {
-		return nil, fmt.Errorf("could not get sync aggregate %w", err)
+		return nil, errors.Wrap(err, "could not get sync aggregate")
 	}
 
 	if syncAggregate.SyncCommitteeBits.Count() < params.BeaconConfig().MinSyncCommitteeParticipants {
@@ -87,18 +98,18 @@ func NewLightClientOptimisticUpdateFromBeaconState(
 	header := state.LatestBlockHeader()
 	stateRoot, err := state.HashTreeRoot(ctx)
 	if err != nil {
-		return nil, fmt.Errorf("could not get state root %w", err)
+		return nil, errors.Wrap(err, "could not get state root")
 	}
 	header.StateRoot = stateRoot[:]
 
 	headerRoot, err := header.HashTreeRoot()
 	if err != nil {
-		return nil, fmt.Errorf("could not get header root %w", err)
+		return nil, errors.Wrap(err, "could not get header root")
 	}
 
 	blockRoot, err := block.Block().HashTreeRoot()
 	if err != nil {
-		return nil, fmt.Errorf("could not get block root %w", err)
+		return nil, errors.Wrap(err, "could not get block root")
 	}
 
 	if headerRoot != blockRoot {
@@ -116,41 +127,100 @@ func NewLightClientOptimisticUpdateFromBeaconState(
 	// attested_header.state_root = hash_tree_root(attested_state)
 	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
 	if err != nil {
-		return nil, fmt.Errorf("could not get attested state root %w", err)
+		return nil, errors.Wrap(err, "could not get attested state root")
 	}
 	attestedHeader.StateRoot = attestedStateRoot[:]
 
 	// assert hash_tree_root(attested_header) == block.message.parent_root
 	attestedHeaderRoot, err := attestedHeader.HashTreeRoot()
 	if err != nil {
-		return nil, fmt.Errorf("could not get attested header root %w", err)
+		return nil, errors.Wrap(err, "could not get attested header root")
 	}
 
 	if attestedHeaderRoot != block.Block().ParentRoot() {
 		return nil, fmt.Errorf("attested header root %#x not equal to block parent root %#x", attestedHeaderRoot, block.Block().ParentRoot())
 	}
 
-	// Return result
-	attestedHeaderResult :=
-		&ethpbv2.LightClientHeader{
-			Beacon: &ethpbv1.BeaconBlockHeader{
-				Slot:          attestedHeader.Slot,
-				ProposerIndex: attestedHeader.ProposerIndex,
-				ParentRoot:    attestedHeader.ParentRoot,
-				StateRoot:     attestedHeader.StateRoot,
-				BodyRoot:      attestedHeader.BodyRoot,
-			},
-		}
-
 	syncAggregateResult := &ethpbv1.SyncAggregate{
 		SyncCommitteeBits:      syncAggregate.SyncCommitteeBits,
 		SyncCommitteeSignature: syncAggregate.SyncCommitteeSignature,
 	}
 
 	result := &ethpbv2.LightClientUpdate{
-		AttestedHeader: attestedHeaderResult,
-		SyncAggregate:  syncAggregateResult,
-		SignatureSlot:  block.Block().Slot(),
+		SyncAggregate: syncAggregateResult,
+		SignatureSlot: block.Block().Slot(),
+	}
+
+	switch block.Block().Version() {
+	case version.Altair, version.Bellatrix:
+		result.AttestedHeader = &ethpbv2.LightClientHeaderContainer{
+			Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+				HeaderAltair: &ethpbv2.LightClientHeader{
+					Beacon: &ethpbv1.BeaconBlockHeader{
+						Slot:          attestedHeader.Slot,
+						ProposerIndex: attestedHeader.ProposerIndex,
+						ParentRoot:    attestedHeader.ParentRoot,
+						StateRoot:     attestedHeader.StateRoot,
+						BodyRoot:      attestedHeader.BodyRoot,
+					},
+				},
+			},
+		}
+	case version.Capella:
+		executionPayloadHeader, err := getExecutionPayloadHeaderCapella(block)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get execution payload header")
+		}
+
+		executionPayloadProof, err := blocks.PayloadProof(ctx, block.Block())
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get execution payload proof")
+		}
+
+		result.AttestedHeader = &ethpbv2.LightClientHeaderContainer{
+			Header: &ethpbv2.LightClientHeaderContainer_HeaderCapella{
+				HeaderCapella: &ethpbv2.LightClientHeaderCapella{
+					Beacon: &ethpbv1.BeaconBlockHeader{
+						Slot:          attestedHeader.Slot,
+						ProposerIndex: attestedHeader.ProposerIndex,
+						ParentRoot:    attestedHeader.ParentRoot,
+						StateRoot:     attestedHeader.StateRoot,
+						BodyRoot:      attestedHeader.BodyRoot,
+					},
+					Execution:       executionPayloadHeader,
+					ExecutionBranch: executionPayloadProof,
+				},
+			},
+		}
+
+	case version.Deneb, version.Electra:
+		executionPayloadHeader, err := getExecutionPayloadHeaderDeneb(block)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get execution payload header")
+		}
+
+		executionPayloadProof, err := blocks.PayloadProof(ctx, block.Block())
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get execution payload proof")
+		}
+
+		result.AttestedHeader = &ethpbv2.LightClientHeaderContainer{
+			Header: &ethpbv2.LightClientHeaderContainer_HeaderDeneb{
+				HeaderDeneb: &ethpbv2.LightClientHeaderDeneb{
+					Beacon: &ethpbv1.BeaconBlockHeader{
+						Slot:          attestedHeader.Slot,
+						ProposerIndex: attestedHeader.ProposerIndex,
+						ParentRoot:    attestedHeader.ParentRoot,
+						StateRoot:     attestedHeader.StateRoot,
+						BodyRoot:      attestedHeader.BodyRoot,
+					},
+					Execution:       executionPayloadHeader,
+					ExecutionBranch: executionPayloadProof,
+				},
+			},
+		}
+	default:
+		return nil, fmt.Errorf("unsupported block version %s", version.String(block.Block().Version()))
 	}
 
 	return result, nil
@@ -173,20 +243,20 @@ func NewLightClientFinalityUpdateFromBeaconState(
 	}
 
 	// Indicate finality whenever possible
-	var finalizedHeader *ethpbv2.LightClientHeader
+	var finalizedHeaderBeacon *ethpbv1.BeaconBlockHeader
 	var finalityBranch [][]byte
 
 	if finalizedBlock != nil && !finalizedBlock.IsNil() {
 		if finalizedBlock.Block().Slot() != 0 {
 			tempFinalizedHeader, err := finalizedBlock.Header()
 			if err != nil {
-				return nil, fmt.Errorf("could not get finalized header %w", err)
+				return nil, errors.Wrap(err, "could not get finalized header")
 			}
-			finalizedHeader = &ethpbv2.LightClientHeader{Beacon: migration.V1Alpha1SignedHeaderToV1(tempFinalizedHeader).GetMessage()}
+			finalizedHeaderBeacon := migration.V1Alpha1SignedHeaderToV1(tempFinalizedHeader).GetMessage()
 
-			finalizedHeaderRoot, err := finalizedHeader.Beacon.HashTreeRoot()
+			finalizedHeaderRoot, err := finalizedHeaderBeacon.HashTreeRoot()
 			if err != nil {
-				return nil, fmt.Errorf("could not get finalized header root %w", err)
+				return nil, errors.Wrap(err, "could not get finalized header root")
 			}
 
 			if finalizedHeaderRoot != bytesutil.ToBytes32(attestedState.FinalizedCheckpoint().Root) {
@@ -197,28 +267,28 @@ func NewLightClientFinalityUpdateFromBeaconState(
 				return nil, fmt.Errorf("invalid finalized header root %v", attestedState.FinalizedCheckpoint().Root)
 			}
 
-			finalizedHeader = &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+			finalizedHeaderBeacon = &ethpbv1.BeaconBlockHeader{
 				Slot:          0,
 				ProposerIndex: 0,
 				ParentRoot:    make([]byte, 32),
 				StateRoot:     make([]byte, 32),
 				BodyRoot:      make([]byte, 32),
-			}}
+			}
 		}
 
 		var bErr error
 		finalityBranch, bErr = attestedState.FinalizedRootProof(ctx)
 		if bErr != nil {
-			return nil, fmt.Errorf("could not get finalized root proof %w", bErr)
+			return nil, errors.Wrap(bErr, "could not get finalized root proof")
 		}
 	} else {
-		finalizedHeader = &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+		finalizedHeaderBeacon = &ethpbv1.BeaconBlockHeader{
 			Slot:          0,
 			ProposerIndex: 0,
 			ParentRoot:    make([]byte, 32),
 			StateRoot:     make([]byte, 32),
 			BodyRoot:      make([]byte, 32),
-		}}
+		}
 
 		finalityBranch = make([][]byte, FinalityBranchNumOfLeaves)
 		for i := 0; i < FinalityBranchNumOfLeaves; i++ {
@@ -226,11 +296,244 @@ func NewLightClientFinalityUpdateFromBeaconState(
 		}
 	}
 
-	result.FinalizedHeader = finalizedHeader
-	result.FinalityBranch = finalityBranch
+	switch block.Block().Version() {
+	case version.Altair, version.Bellatrix:
+		result.FinalizedHeader = &ethpbv2.LightClientHeaderContainer{
+			Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+				HeaderAltair: &ethpbv2.LightClientHeader{Beacon: finalizedHeaderBeacon},
+			},
+		}
+		result.FinalityBranch = finalityBranch
+	case version.Capella:
+		if finalizedBlock != nil && !finalizedBlock.IsNil() {
+			execution, err := getExecutionPayloadHeaderCapella(finalizedBlock)
+			if err != nil {
+				return nil, errors.Wrap(err, "could not get execution payload header")
+			}
+			executionBranch, err := blocks.PayloadProof(ctx, finalizedBlock.Block())
+			if err != nil {
+				return nil, errors.Wrap(err, "could not get execution payload proof")
+			}
+
+			result.FinalizedHeader = &ethpbv2.LightClientHeaderContainer{
+				Header: &ethpbv2.LightClientHeaderContainer_HeaderCapella{
+					HeaderCapella: &ethpbv2.LightClientHeaderCapella{
+						Beacon:          finalizedHeaderBeacon,
+						Execution:       execution,
+						ExecutionBranch: executionBranch,
+					},
+				},
+			}
+			result.FinalityBranch = finalityBranch
+		} else {
+			execution := createEmptyExecutionPayloadHeaderCapella()
+			executionBranch := make([][]byte, 0)
+
+			result.FinalizedHeader = &ethpbv2.LightClientHeaderContainer{
+				Header: &ethpbv2.LightClientHeaderContainer_HeaderCapella{
+					HeaderCapella: &ethpbv2.LightClientHeaderCapella{
+						Beacon:          finalizedHeaderBeacon,
+						Execution:       execution,
+						ExecutionBranch: executionBranch,
+					},
+				},
+			}
+
+			result.FinalityBranch = finalityBranch
+		}
+	case version.Deneb, version.Electra:
+		if finalizedBlock != nil && !finalizedBlock.IsNil() {
+			execution, err := getExecutionPayloadHeaderDeneb(finalizedBlock)
+			if err != nil {
+				return nil, errors.Wrap(err, "could not get execution payload header")
+			}
+			executionBranch, err := blocks.PayloadProof(ctx, finalizedBlock.Block())
+			if err != nil {
+				return nil, errors.Wrap(err, "could not get execution payload proof")
+			}
+
+			result.FinalizedHeader = &ethpbv2.LightClientHeaderContainer{
+				Header: &ethpbv2.LightClientHeaderContainer_HeaderDeneb{
+					HeaderDeneb: &ethpbv2.LightClientHeaderDeneb{
+						Beacon:          finalizedHeaderBeacon,
+						Execution:       execution,
+						ExecutionBranch: executionBranch,
+					},
+				},
+			}
+			result.FinalityBranch = finalityBranch
+		} else {
+			execution := createEmptyExecutionPayloadHeaderDeneb()
+			executionBranch := make([][]byte, 0)
+
+			result.FinalizedHeader = &ethpbv2.LightClientHeaderContainer{
+				Header: &ethpbv2.LightClientHeaderContainer_HeaderDeneb{
+					HeaderDeneb: &ethpbv2.LightClientHeaderDeneb{
+						Beacon:          finalizedHeaderBeacon,
+						Execution:       execution,
+						ExecutionBranch: executionBranch,
+					},
+				},
+			}
+
+			result.FinalityBranch = finalityBranch
+		}
+	default:
+		return nil, fmt.Errorf("unsupported block version %s", version.String(block.Block().Version()))
+	}
+
 	return result, nil
 }
 
+func createEmptyExecutionPayloadHeaderCapella() *enginev1.ExecutionPayloadHeaderCapella {
+	return &enginev1.ExecutionPayloadHeaderCapella{
+		ParentHash:       make([]byte, 32),
+		FeeRecipient:     make([]byte, 20),
+		StateRoot:        make([]byte, 32),
+		ReceiptsRoot:     make([]byte, 32),
+		LogsBloom:        make([]byte, 256),
+		PrevRandao:       make([]byte, 32),
+		BlockNumber:      0,
+		GasLimit:         0,
+		GasUsed:          0,
+		Timestamp:        0,
+		ExtraData:        make([]byte, 32),
+		BaseFeePerGas:    make([]byte, 32),
+		BlockHash:        make([]byte, 32),
+		TransactionsRoot: make([]byte, 32),
+		WithdrawalsRoot:  make([]byte, 32),
+	}
+}
+
+func createEmptyExecutionPayloadHeaderDeneb() *enginev1.ExecutionPayloadHeaderDeneb {
+	return &enginev1.ExecutionPayloadHeaderDeneb{
+		ParentHash:       make([]byte, 32),
+		FeeRecipient:     make([]byte, 20),
+		StateRoot:        make([]byte, 32),
+		ReceiptsRoot:     make([]byte, 32),
+		LogsBloom:        make([]byte, 256),
+		PrevRandao:       make([]byte, 32),
+		BlockNumber:      0,
+		GasLimit:         0,
+		GasUsed:          0,
+		Timestamp:        0,
+		ExtraData:        make([]byte, 32),
+		BaseFeePerGas:    make([]byte, 32),
+		BlockHash:        make([]byte, 32),
+		TransactionsRoot: make([]byte, 32),
+		WithdrawalsRoot:  make([]byte, 32),
+	}
+}
+
+func getExecutionPayloadHeaderCapella(block interfaces.ReadOnlySignedBeaconBlock) (*enginev1.ExecutionPayloadHeaderCapella, error) {
+	payloadInterface, err := block.Block().Body().Execution()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get execution data")
+	}
+	transactionsRoot, err := payloadInterface.TransactionsRoot()
+	if errors.Is(err, consensus_types.ErrUnsupportedField) {
+		transactions, err := payloadInterface.Transactions()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get transactions")
+		}
+		transactionsRootArray, err := ssz.TransactionsRoot(transactions)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get transactions root")
+		}
+		transactionsRoot = transactionsRootArray[:]
+	} else if err != nil {
+		return nil, errors.Wrap(err, "could not get transactions root")
+	}
+	withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
+	if errors.Is(err, consensus_types.ErrUnsupportedField) {
+		withdrawals, err := payloadInterface.Withdrawals()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get withdrawals")
+		}
+		withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get withdrawals root")
+		}
+		withdrawalsRoot = withdrawalsRootArray[:]
+	} else if err != nil {
+		return nil, errors.Wrap(err, "could not get withdrawals root")
+	}
+
+	execution := &enginev1.ExecutionPayloadHeaderCapella{
+		ParentHash:       payloadInterface.ParentHash(),
+		FeeRecipient:     payloadInterface.FeeRecipient(),
+		StateRoot:        payloadInterface.StateRoot(),
+		ReceiptsRoot:     payloadInterface.ReceiptsRoot(),
+		LogsBloom:        payloadInterface.LogsBloom(),
+		PrevRandao:       payloadInterface.PrevRandao(),
+		BlockNumber:      payloadInterface.BlockNumber(),
+		GasLimit:         payloadInterface.GasLimit(),
+		GasUsed:          payloadInterface.GasUsed(),
+		Timestamp:        payloadInterface.Timestamp(),
+		ExtraData:        payloadInterface.ExtraData(),
+		BaseFeePerGas:    payloadInterface.BaseFeePerGas(),
+		BlockHash:        payloadInterface.BlockHash(),
+		TransactionsRoot: transactionsRoot,
+		WithdrawalsRoot:  withdrawalsRoot,
+	}
+
+	return execution, nil
+}
+
+func getExecutionPayloadHeaderDeneb(block interfaces.ReadOnlySignedBeaconBlock) (*enginev1.ExecutionPayloadHeaderDeneb, error) {
+	payloadInterface, err := block.Block().Body().Execution()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get execution data")
+	}
+	transactionsRoot, err := payloadInterface.TransactionsRoot()
+	if errors.Is(err, consensus_types.ErrUnsupportedField) {
+		transactions, err := payloadInterface.Transactions()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get transactions")
+		}
+		transactionsRootArray, err := ssz.TransactionsRoot(transactions)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get transactions root")
+		}
+		transactionsRoot = transactionsRootArray[:]
+	} else if err != nil {
+		return nil, errors.Wrap(err, "could not get transactions root")
+	}
+	withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
+	if errors.Is(err, consensus_types.ErrUnsupportedField) {
+		withdrawals, err := payloadInterface.Withdrawals()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get withdrawals")
+		}
+		withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get withdrawals root")
+		}
+		withdrawalsRoot = withdrawalsRootArray[:]
+	} else if err != nil {
+		return nil, errors.Wrap(err, "could not get withdrawals root")
+	}
+
+	execution := &enginev1.ExecutionPayloadHeaderDeneb{
+		ParentHash:       payloadInterface.ParentHash(),
+		FeeRecipient:     payloadInterface.FeeRecipient(),
+		StateRoot:        payloadInterface.StateRoot(),
+		ReceiptsRoot:     payloadInterface.ReceiptsRoot(),
+		LogsBloom:        payloadInterface.LogsBloom(),
+		PrevRandao:       payloadInterface.PrevRandao(),
+		BlockNumber:      payloadInterface.BlockNumber(),
+		GasLimit:         payloadInterface.GasLimit(),
+		GasUsed:          payloadInterface.GasUsed(),
+		Timestamp:        payloadInterface.Timestamp(),
+		ExtraData:        payloadInterface.ExtraData(),
+		BaseFeePerGas:    payloadInterface.BaseFeePerGas(),
+		BlockHash:        payloadInterface.BlockHash(),
+		TransactionsRoot: transactionsRoot,
+		WithdrawalsRoot:  withdrawalsRoot,
+	}
+
+	return execution, nil
+}
 func NewLightClientUpdateFromFinalityUpdate(update *ethpbv2.LightClientFinalityUpdate) *ethpbv2.LightClientUpdate {
 	return &ethpbv2.LightClientUpdate{
 		AttestedHeader:  update.AttestedHeader,
diff --git a/beacon-chain/core/light-client/lightclient_test.go b/beacon-chain/core/light-client/lightclient_test.go
index 568075c2db76..51e706706d23 100644
--- a/beacon-chain/core/light-client/lightclient_test.go
+++ b/beacon-chain/core/light-client/lightclient_test.go
@@ -11,8 +11,8 @@ import (
 	"github.com/prysmaticlabs/prysm/v5/testing/util"
 )
 
-func TestLightClient_NewLightClientOptimisticUpdateFromBeaconState(t *testing.T) {
-	l := util.NewTestLightClient(t).SetupTest()
+func TestLightClient_NewLightClientOptimisticUpdateFromBeaconStateCapella(t *testing.T) {
+	l := util.NewTestLightClient(t).SetupTestCapella()
 
 	update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState)
 	require.NoError(t, err)
@@ -23,12 +23,96 @@ func TestLightClient_NewLightClientOptimisticUpdateFromBeaconState(t *testing.T)
 	l.CheckSyncAggregate(update)
 	l.CheckAttestedHeader(update)
 
-	require.Equal(t, (*v2.LightClientHeader)(nil), update.FinalizedHeader, "Finalized header is not nil")
+	require.Equal(t, (*v2.LightClientHeaderContainer)(nil), update.FinalizedHeader, "Finalized header is not nil")
 	require.DeepSSZEqual(t, ([][]byte)(nil), update.FinalityBranch, "Finality branch is not nil")
 }
 
-func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) {
-	l := util.NewTestLightClient(t).SetupTest()
+func TestLightClient_NewLightClientOptimisticUpdateFromBeaconStateAltair(t *testing.T) {
+	l := util.NewTestLightClient(t).SetupTestAltair()
+
+	update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState)
+	require.NoError(t, err)
+	require.NotNil(t, update, "update is nil")
+
+	require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal")
+
+	l.CheckSyncAggregate(update)
+	l.CheckAttestedHeader(update)
+
+	require.Equal(t, (*v2.LightClientHeaderContainer)(nil), update.FinalizedHeader, "Finalized header is not nil")
+	require.DeepSSZEqual(t, ([][]byte)(nil), update.FinalityBranch, "Finality branch is not nil")
+}
+
+func TestLightClient_NewLightClientOptimisticUpdateFromBeaconStateDeneb(t *testing.T) {
+	l := util.NewTestLightClient(t).SetupTestDeneb()
+
+	update, err := lightClient.NewLightClientOptimisticUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState)
+	require.NoError(t, err)
+	require.NotNil(t, update, "update is nil")
+
+	require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal")
+
+	l.CheckSyncAggregate(update)
+	l.CheckAttestedHeader(update)
+
+	require.Equal(t, (*v2.LightClientHeaderContainer)(nil), update.FinalizedHeader, "Finalized header is not nil")
+	require.DeepSSZEqual(t, ([][]byte)(nil), update.FinalityBranch, "Finality branch is not nil")
+}
+func TestLightClient_NewLightClientFinalityUpdateFromBeaconStateCapella(t *testing.T) {
+	l := util.NewTestLightClient(t).SetupTestCapella()
+	update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, nil)
+	require.NoError(t, err)
+	require.NotNil(t, update, "update is nil")
+
+	require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal")
+
+	l.CheckSyncAggregate(update)
+	l.CheckAttestedHeader(update)
+
+	zeroHash := params.BeaconConfig().ZeroHash[:]
+	require.NotNil(t, update.FinalizedHeader, "Finalized header is nil")
+	updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon()
+	require.NoError(t, err)
+	require.Equal(t, primitives.Slot(0), updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not zero")
+	require.Equal(t, primitives.ValidatorIndex(0), updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not zero")
+	require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves")
+	for _, leaf := range update.FinalityBranch {
+		require.DeepSSZEqual(t, zeroHash, leaf, "Leaf is not zero")
+	}
+}
+
+func TestLightClient_NewLightClientFinalityUpdateFromBeaconStateAltair(t *testing.T) {
+	l := util.NewTestLightClient(t).SetupTestAltair()
+
+	update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, nil)
+	require.NoError(t, err)
+	require.NotNil(t, update, "update is nil")
+
+	require.Equal(t, l.Block.Block().Slot(), update.SignatureSlot, "Signature slot is not equal")
+
+	l.CheckSyncAggregate(update)
+	l.CheckAttestedHeader(update)
+
+	zeroHash := params.BeaconConfig().ZeroHash[:]
+	require.NotNil(t, update.FinalizedHeader, "Finalized header is nil")
+	updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon()
+	require.NoError(t, err)
+	require.Equal(t, primitives.Slot(0), updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not zero")
+	require.Equal(t, primitives.ValidatorIndex(0), updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not zero")
+	require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves")
+	for _, leaf := range update.FinalityBranch {
+		require.DeepSSZEqual(t, zeroHash, leaf, "Leaf is not zero")
+	}
+}
+
+func TestLightClient_NewLightClientFinalityUpdateFromBeaconStateDeneb(t *testing.T) {
+	l := util.NewTestLightClient(t).SetupTestDeneb()
 
 	update, err := lightClient.NewLightClientFinalityUpdateFromBeaconState(l.Ctx, l.State, l.Block, l.AttestedState, nil)
 	require.NoError(t, err)
@@ -41,13 +125,18 @@ func TestLightClient_NewLightClientFinalityUpdateFromBeaconState(t *testing.T) {
 
 	zeroHash := params.BeaconConfig().ZeroHash[:]
 	require.NotNil(t, update.FinalizedHeader, "Finalized header is nil")
-	require.Equal(t, primitives.Slot(0), update.FinalizedHeader.Beacon.Slot, "Finalized header slot is not zero")
-	require.Equal(t, primitives.ValidatorIndex(0), update.FinalizedHeader.Beacon.ProposerIndex, "Finalized header proposer index is not zero")
-	require.DeepSSZEqual(t, zeroHash, update.FinalizedHeader.Beacon.ParentRoot, "Finalized header parent root is not zero")
-	require.DeepSSZEqual(t, zeroHash, update.FinalizedHeader.Beacon.StateRoot, "Finalized header state root is not zero")
-	require.DeepSSZEqual(t, zeroHash, update.FinalizedHeader.Beacon.BodyRoot, "Finalized header body root is not zero")
+	updateFinalizedHeaderBeacon, err := update.FinalizedHeader.GetBeacon()
+	require.NoError(t, err)
+	require.Equal(t, primitives.Slot(0), updateFinalizedHeaderBeacon.Slot, "Finalized header slot is not zero")
+	require.Equal(t, primitives.ValidatorIndex(0), updateFinalizedHeaderBeacon.ProposerIndex, "Finalized header proposer index is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.ParentRoot, "Finalized header parent root is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.StateRoot, "Finalized header state root is not zero")
+	require.DeepSSZEqual(t, zeroHash, updateFinalizedHeaderBeacon.BodyRoot, "Finalized header body root is not zero")
+	require.DeepSSZEqual(t, zeroHash, update.FinalizedHeader.GetHeaderDeneb().Execution.BlockHash, "Execution BlockHash is not zero")
 	require.Equal(t, lightClient.FinalityBranchNumOfLeaves, len(update.FinalityBranch), "Invalid finality branch leaves")
 	for _, leaf := range update.FinalityBranch {
 		require.DeepSSZEqual(t, zeroHash, leaf, "Leaf is not zero")
 	}
 }
+
+// TODO - add finality update tests with non-nil finalized block for different versions
diff --git a/beacon-chain/rpc/eth/events/events.go b/beacon-chain/rpc/eth/events/events.go
index b39d99165d40..980171cd9f2b 100644
--- a/beacon-chain/rpc/eth/events/events.go
+++ b/beacon-chain/rpc/eth/events/events.go
@@ -306,21 +306,30 @@ func (s *Server) handleStateEvents(ctx context.Context, w http.ResponseWriter, f
 		for _, b := range updateData.Data.FinalityBranch {
 			finalityBranch = append(finalityBranch, hexutil.Encode(b))
 		}
+
+		attestedBeacon, err := updateData.Data.AttestedHeader.GetBeacon()
+		if err != nil {
+			return errors.Wrap(err, "could not get attested header")
+		}
+		finalizedBeacon, err := updateData.Data.FinalizedHeader.GetBeacon()
+		if err != nil {
+			return errors.Wrap(err, "could not get finalized header")
+		}
 		update := &structs.LightClientFinalityUpdateEvent{
 			Version: version.String(int(updateData.Version)),
 			Data: &structs.LightClientFinalityUpdate{
 				AttestedHeader: &structs.BeaconBlockHeader{
-					Slot:          fmt.Sprintf("%d", updateData.Data.AttestedHeader.Beacon.Slot),
-					ProposerIndex: fmt.Sprintf("%d", updateData.Data.AttestedHeader.Beacon.ProposerIndex),
-					ParentRoot:    hexutil.Encode(updateData.Data.AttestedHeader.Beacon.ParentRoot),
-					StateRoot:     hexutil.Encode(updateData.Data.AttestedHeader.Beacon.StateRoot),
-					BodyRoot:      hexutil.Encode(updateData.Data.AttestedHeader.Beacon.BodyRoot),
+					Slot:          fmt.Sprintf("%d", attestedBeacon.Slot),
+					ProposerIndex: fmt.Sprintf("%d", attestedBeacon.ProposerIndex),
+					ParentRoot:    hexutil.Encode(attestedBeacon.ParentRoot),
+					StateRoot:     hexutil.Encode(attestedBeacon.StateRoot),
+					BodyRoot:      hexutil.Encode(attestedBeacon.BodyRoot),
 				},
 				FinalizedHeader: &structs.BeaconBlockHeader{
-					Slot:          fmt.Sprintf("%d", updateData.Data.FinalizedHeader.Beacon.Slot),
-					ProposerIndex: fmt.Sprintf("%d", updateData.Data.FinalizedHeader.Beacon.ProposerIndex),
-					ParentRoot:    hexutil.Encode(updateData.Data.FinalizedHeader.Beacon.ParentRoot),
-					StateRoot:     hexutil.Encode(updateData.Data.FinalizedHeader.Beacon.StateRoot),
+					Slot:          fmt.Sprintf("%d", finalizedBeacon.Slot),
+					ProposerIndex: fmt.Sprintf("%d", finalizedBeacon.ProposerIndex),
+					ParentRoot:    hexutil.Encode(finalizedBeacon.ParentRoot),
+					StateRoot:     hexutil.Encode(finalizedBeacon.StateRoot),
 				},
 				FinalityBranch: finalityBranch,
 				SyncAggregate: &structs.SyncAggregate{
@@ -339,15 +348,19 @@ func (s *Server) handleStateEvents(ctx context.Context, w http.ResponseWriter, f
 		if !ok {
 			return write(w, flusher, topicDataMismatch, event.Data, LightClientOptimisticUpdateTopic)
 		}
+		attestedBeacon, err := updateData.Data.AttestedHeader.GetBeacon()
+		if err != nil {
+			return errors.Wrap(err, "could not get attested header")
+		}
 		update := &structs.LightClientOptimisticUpdateEvent{
 			Version: version.String(int(updateData.Version)),
 			Data: &structs.LightClientOptimisticUpdate{
 				AttestedHeader: &structs.BeaconBlockHeader{
-					Slot:          fmt.Sprintf("%d", updateData.Data.AttestedHeader.Beacon.Slot),
-					ProposerIndex: fmt.Sprintf("%d", updateData.Data.AttestedHeader.Beacon.ProposerIndex),
-					ParentRoot:    hexutil.Encode(updateData.Data.AttestedHeader.Beacon.ParentRoot),
-					StateRoot:     hexutil.Encode(updateData.Data.AttestedHeader.Beacon.StateRoot),
-					BodyRoot:      hexutil.Encode(updateData.Data.AttestedHeader.Beacon.BodyRoot),
+					Slot:          fmt.Sprintf("%d", attestedBeacon.Slot),
+					ProposerIndex: fmt.Sprintf("%d", attestedBeacon.ProposerIndex),
+					ParentRoot:    hexutil.Encode(attestedBeacon.ParentRoot),
+					StateRoot:     hexutil.Encode(attestedBeacon.StateRoot),
+					BodyRoot:      hexutil.Encode(attestedBeacon.BodyRoot),
 				},
 				SyncAggregate: &structs.SyncAggregate{
 					SyncCommitteeBits:      hexutil.Encode(updateData.Data.SyncAggregate.SyncCommitteeBits),
diff --git a/beacon-chain/rpc/eth/light-client/BUILD.bazel b/beacon-chain/rpc/eth/light-client/BUILD.bazel
index a95416814183..04848190b738 100644
--- a/beacon-chain/rpc/eth/light-client/BUILD.bazel
+++ b/beacon-chain/rpc/eth/light-client/BUILD.bazel
@@ -10,6 +10,7 @@ go_library(
     importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/light-client",
     visibility = ["//beacon-chain:__subpackages__"],
     deps = [
+        "//api:go_default_library",
         "//api/server/structs:go_default_library",
         "//beacon-chain/blockchain:go_default_library",
         "//beacon-chain/core/light-client:go_default_library",
@@ -19,8 +20,11 @@ go_library(
         "//beacon-chain/state:go_default_library",
         "//config/fieldparams:go_default_library",
         "//config/params:go_default_library",
+        "//consensus-types:go_default_library",
+        "//consensus-types/blocks:go_default_library",
         "//consensus-types/interfaces:go_default_library",
         "//consensus-types/primitives:go_default_library",
+        "//encoding/ssz:go_default_library",
         "//network/httputil:go_default_library",
         "//proto/eth/v1:go_default_library",
         "//proto/eth/v2:go_default_library",
@@ -29,6 +33,7 @@ go_library(
         "//time/slots:go_default_library",
         "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
         "@com_github_gorilla_mux//:go_default_library",
+        "@com_github_pkg_errors//:go_default_library",
         "@com_github_wealdtech_go_bytesutil//:go_default_library",
         "@io_opencensus_go//trace:go_default_library",
     ],
diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go
index 74296f192e85..33f07cf214e2 100644
--- a/beacon-chain/rpc/eth/light-client/handlers.go
+++ b/beacon-chain/rpc/eth/light-client/handlers.go
@@ -8,6 +8,8 @@ import (
 
 	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/gorilla/mux"
+	"github.com/pkg/errors"
+	"github.com/prysmaticlabs/prysm/v5/api"
 	"github.com/prysmaticlabs/prysm/v5/api/server/structs"
 	"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared"
 	"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
@@ -46,16 +48,16 @@ func (s *Server) GetLightClientBootstrap(w http.ResponseWriter, req *http.Reques
 		return
 	}
 
-	bootstrap, err := createLightClientBootstrap(ctx, state)
+	bootstrap, err := createLightClientBootstrap(ctx, state, blk.Block())
 	if err != nil {
 		httputil.HandleError(w, "could not get light client bootstrap: "+err.Error(), http.StatusInternalServerError)
 		return
 	}
-
 	response := &structs.LightClientBootstrapResponse{
 		Version: version.String(blk.Version()),
 		Data:    bootstrap,
 	}
+	w.Header().Set(api.VersionHeader, version.String(version.Deneb))
 
 	httputil.WriteJson(w, response)
 }
@@ -351,27 +353,27 @@ func (s *Server) getLightClientEventBlock(ctx context.Context, minSignaturesRequ
 	// Get the current state
 	state, err := s.HeadFetcher.HeadState(ctx)
 	if err != nil {
-		return nil, fmt.Errorf("could not get head state %w", err)
+		return nil, errors.Wrap(err, "could not get head state")
 	}
 
 	// Get the block
 	latestBlockHeader := *state.LatestBlockHeader()
 	stateRoot, err := state.HashTreeRoot(ctx)
 	if err != nil {
-		return nil, fmt.Errorf("could not get state root %w", err)
+		return nil, errors.Wrap(err, "could not get state root")
 	}
 	latestBlockHeader.StateRoot = stateRoot[:]
 	latestBlockHeaderRoot, err := latestBlockHeader.HashTreeRoot()
 	if err != nil {
-		return nil, fmt.Errorf("could not get latest block header root %w", err)
+		return nil, errors.Wrap(err, "could not get latest block header root")
 	}
 
 	block, err := s.Blocker.Block(ctx, latestBlockHeaderRoot[:])
 	if err != nil {
-		return nil, fmt.Errorf("could not get latest block %w", err)
+		return nil, errors.Wrap(err, "could not get latest block")
 	}
 	if block == nil {
-		return nil, fmt.Errorf("latest block is nil")
+		return nil, errors.New("latest block is nil")
 	}
 
 	// Loop through the blocks until we find a block that satisfies minSignaturesRequired requirement
@@ -385,10 +387,10 @@ func (s *Server) getLightClientEventBlock(ctx context.Context, minSignaturesRequ
 		parentRoot := block.Block().ParentRoot()
 		block, err = s.Blocker.Block(ctx, parentRoot[:])
 		if err != nil {
-			return nil, fmt.Errorf("could not get parent block %w", err)
+			return nil, errors.Wrap(err, "could not get parent block")
 		}
 		if block == nil {
-			return nil, fmt.Errorf("parent block is nil")
+			return nil, errors.New("parent block is nil")
 		}
 
 		// Get the number of sync committee signatures
diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go
index 8855aad8c57e..807afd578a8d 100644
--- a/beacon-chain/rpc/eth/light-client/handlers_test.go
+++ b/beacon-chain/rpc/eth/light-client/handlers_test.go
@@ -26,10 +26,65 @@ import (
 	"github.com/prysmaticlabs/prysm/v5/testing/util"
 )
 
-func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) {
+func TestLightClientHandler_GetLightClientBootstrap_Altair(t *testing.T) {
 	helpers.ClearCache()
 	slot := primitives.Slot(params.BeaconConfig().AltairForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
 
+	b := util.NewBeaconBlockAltair()
+	b.Block.StateRoot = bytesutil.PadTo([]byte("foo"), 32)
+	b.Block.Slot = slot
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(b)
+
+	require.NoError(t, err)
+	header, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	r, err := b.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	bs, err := util.NewBeaconStateAltair(func(state *ethpb.BeaconStateAltair) error {
+		state.BlockRoots[0] = r[:]
+		return nil
+	})
+	require.NoError(t, err)
+
+	require.NoError(t, bs.SetSlot(slot))
+	require.NoError(t, bs.SetLatestBlockHeader(header.Header))
+
+	mockBlocker := &testutil.MockBlocker{BlockToReturn: signedBlock}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot: bs,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	muxVars := make(map[string]string)
+	muxVars["block_root"] = hexutil.Encode(r[:])
+	request := httptest.NewRequest("GET", "http://foo.com/", nil)
+	request = mux.SetURLVars(request, muxVars)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientBootstrap(writer, request)
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientBootstrapResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeader
+	err = json.Unmarshal(resp.Data.Header, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, "altair", resp.Version)
+	require.Equal(t, hexutil.Encode(header.Header.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp.Data)
+}
+
+func TestLightClientHandler_GetLightClientBootstrap_Capella(t *testing.T) {
+	helpers.ClearCache()
+	slot := primitives.Slot(params.BeaconConfig().CapellaForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
+
 	b := util.NewBeaconBlockCapella()
 	b.Block.StateRoot = bytesutil.PadTo([]byte("foo"), 32)
 	b.Block.Slot = slot
@@ -37,58 +92,865 @@ func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) {
 	signedBlock, err := blocks.NewSignedBeaconBlock(b)
 
 	require.NoError(t, err)
-	header, err := signedBlock.Header()
+	header, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	r, err := b.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	bs, err := util.NewBeaconStateCapella(func(state *ethpb.BeaconStateCapella) error {
+		state.BlockRoots[0] = r[:]
+		return nil
+	})
+	require.NoError(t, err)
+
+	require.NoError(t, bs.SetSlot(slot))
+	require.NoError(t, bs.SetLatestBlockHeader(header.Header))
+
+	mockBlocker := &testutil.MockBlocker{BlockToReturn: signedBlock}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot: bs,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	muxVars := make(map[string]string)
+	muxVars["block_root"] = hexutil.Encode(r[:])
+	request := httptest.NewRequest("GET", "http://foo.com/", nil)
+	request = mux.SetURLVars(request, muxVars)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientBootstrap(writer, request)
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientBootstrapResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderCapella
+	err = json.Unmarshal(resp.Data.Header, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, "capella", resp.Version)
+	require.Equal(t, hexutil.Encode(header.Header.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp.Data)
+}
+
+func TestLightClientHandler_GetLightClientBootstrap_Deneb(t *testing.T) {
+	helpers.ClearCache()
+	slot := primitives.Slot(params.BeaconConfig().DenebForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
+
+	b := util.NewBeaconBlockDeneb()
+	b.Block.StateRoot = bytesutil.PadTo([]byte("foo"), 32)
+	b.Block.Slot = slot
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(b)
+
+	require.NoError(t, err)
+	header, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	r, err := b.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	bs, err := util.NewBeaconStateDeneb(func(state *ethpb.BeaconStateDeneb) error {
+		state.BlockRoots[0] = r[:]
+		return nil
+	})
+	require.NoError(t, err)
+
+	require.NoError(t, bs.SetSlot(slot))
+	require.NoError(t, bs.SetLatestBlockHeader(header.Header))
+
+	mockBlocker := &testutil.MockBlocker{BlockToReturn: signedBlock}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot: bs,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	muxVars := make(map[string]string)
+	muxVars["block_root"] = hexutil.Encode(r[:])
+	request := httptest.NewRequest("GET", "http://foo.com/", nil)
+	request = mux.SetURLVars(request, muxVars)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientBootstrap(writer, request)
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientBootstrapResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderDeneb
+	err = json.Unmarshal(resp.Data.Header, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, "deneb", resp.Version)
+	require.Equal(t, hexutil.Encode(header.Header.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp.Data)
+}
+
+func TestLightClientHandler_GetLightClientUpdatesByRangeAltair(t *testing.T) {
+	helpers.ClearCache()
+	ctx := context.Background()
+	config := params.BeaconConfig()
+	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+
+	attestedState, err := util.NewBeaconStateAltair()
+	require.NoError(t, err)
+	err = attestedState.SetSlot(slot.Sub(1))
+	require.NoError(t, err)
+
+	parent := util.NewBeaconBlockAltair()
+	parent.Block.Slot = slot.Sub(1)
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(t, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(t, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	st, err := util.NewBeaconStateAltair()
+	require.NoError(t, err)
+	err = st.SetSlot(slot)
+	require.NoError(t, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(t, err)
+
+	block := util.NewBeaconBlockAltair()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < config.SyncCommitteeSize; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	err = st.SetLatestBlockHeader(h.Header)
+	require.NoError(t, err)
+	stateRoot, err := st.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	root, err := block.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	mockBlocker := &testutil.MockBlocker{
+		RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{
+			parentRoot: signedParent,
+			root:       signedBlock,
+		},
+		SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
+			slot.Sub(1): signedParent,
+			slot:        signedBlock,
+		},
+	}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot.Sub(1): attestedState,
+			slot:        st,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
+	url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod)
+	request := httptest.NewRequest("GET", url, nil)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientUpdatesByRange(writer, request)
+
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientUpdatesByRangeResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeader
+	err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(resp.Updates))
+	require.Equal(t, "altair", resp.Updates[0].Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp)
+}
+
+func TestLightClientHandler_GetLightClientUpdatesByRangeCapella(t *testing.T) {
+	helpers.ClearCache()
+	ctx := context.Background()
+	config := params.BeaconConfig()
+	slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+
+	attestedState, err := util.NewBeaconStateCapella()
+	require.NoError(t, err)
+	err = attestedState.SetSlot(slot.Sub(1))
+	require.NoError(t, err)
+
+	parent := util.NewBeaconBlockCapella()
+	parent.Block.Slot = slot.Sub(1)
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(t, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(t, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	st, err := util.NewBeaconStateCapella()
+	require.NoError(t, err)
+	err = st.SetSlot(slot)
+	require.NoError(t, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(t, err)
+
+	block := util.NewBeaconBlockCapella()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < config.SyncCommitteeSize; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	err = st.SetLatestBlockHeader(h.Header)
+	require.NoError(t, err)
+	stateRoot, err := st.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	root, err := block.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	mockBlocker := &testutil.MockBlocker{
+		RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{
+			parentRoot: signedParent,
+			root:       signedBlock,
+		},
+		SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
+			slot.Sub(1): signedParent,
+			slot:        signedBlock,
+		},
+	}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot.Sub(1): attestedState,
+			slot:        st,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
+	url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod)
+	request := httptest.NewRequest("GET", url, nil)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientUpdatesByRange(writer, request)
+
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientUpdatesByRangeResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderCapella
+	err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(resp.Updates))
+	require.Equal(t, "capella", resp.Updates[0].Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp)
+}
+
+func TestLightClientHandler_GetLightClientUpdatesByRangeDeneb(t *testing.T) {
+	helpers.ClearCache()
+	ctx := context.Background()
+	config := params.BeaconConfig()
+	slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+
+	attestedState, err := util.NewBeaconStateDeneb()
+	require.NoError(t, err)
+	err = attestedState.SetSlot(slot.Sub(1))
+	require.NoError(t, err)
+
+	parent := util.NewBeaconBlockDeneb()
+	parent.Block.Slot = slot.Sub(1)
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(t, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(t, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	st, err := util.NewBeaconStateDeneb()
+	require.NoError(t, err)
+	err = st.SetSlot(slot)
+	require.NoError(t, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(t, err)
+
+	block := util.NewBeaconBlockDeneb()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < config.SyncCommitteeSize; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	err = st.SetLatestBlockHeader(h.Header)
+	require.NoError(t, err)
+	stateRoot, err := st.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	root, err := block.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	mockBlocker := &testutil.MockBlocker{
+		RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{
+			parentRoot: signedParent,
+			root:       signedBlock,
+		},
+		SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
+			slot.Sub(1): signedParent,
+			slot:        signedBlock,
+		},
+	}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot.Sub(1): attestedState,
+			slot:        st,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
+	url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod)
+	request := httptest.NewRequest("GET", url, nil)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientUpdatesByRange(writer, request)
+
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientUpdatesByRangeResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderDeneb
+	err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(resp.Updates))
+	require.Equal(t, "deneb", resp.Updates[0].Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp)
+}
+
+func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountAltair(t *testing.T) {
+	helpers.ClearCache()
+	ctx := context.Background()
+	config := params.BeaconConfig()
+	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+
+	attestedState, err := util.NewBeaconStateAltair()
+	require.NoError(t, err)
+	err = attestedState.SetSlot(slot.Sub(1))
+	require.NoError(t, err)
+
+	parent := util.NewBeaconBlockAltair()
+	parent.Block.Slot = slot.Sub(1)
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(t, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(t, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	st, err := util.NewBeaconStateAltair()
+	require.NoError(t, err)
+	err = st.SetSlot(slot)
+	require.NoError(t, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(t, err)
+
+	block := util.NewBeaconBlockAltair()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < config.SyncCommitteeSize; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	err = st.SetLatestBlockHeader(h.Header)
+	require.NoError(t, err)
+	stateRoot, err := st.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	root, err := block.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	mockBlocker := &testutil.MockBlocker{
+		RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{
+			parentRoot: signedParent,
+			root:       signedBlock,
+		},
+		SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
+			slot.Sub(1): signedParent,
+			slot:        signedBlock,
+		},
+	}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot.Sub(1): attestedState,
+			slot:        st,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
+	count := 129 // config.MaxRequestLightClientUpdates is 128
+	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
+	request := httptest.NewRequest("GET", url, nil)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientUpdatesByRange(writer, request)
+
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientUpdatesByRangeResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeader
+	err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case.
+	require.Equal(t, "altair", resp.Updates[0].Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp)
+}
+
+func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountCapella(t *testing.T) {
+	helpers.ClearCache()
+	ctx := context.Background()
+	config := params.BeaconConfig()
+	slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+
+	attestedState, err := util.NewBeaconStateCapella()
+	require.NoError(t, err)
+	err = attestedState.SetSlot(slot.Sub(1))
+	require.NoError(t, err)
+
+	parent := util.NewBeaconBlockCapella()
+	parent.Block.Slot = slot.Sub(1)
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(t, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(t, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	st, err := util.NewBeaconStateCapella()
+	require.NoError(t, err)
+	err = st.SetSlot(slot)
+	require.NoError(t, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(t, err)
+
+	block := util.NewBeaconBlockCapella()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < config.SyncCommitteeSize; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	err = st.SetLatestBlockHeader(h.Header)
+	require.NoError(t, err)
+	stateRoot, err := st.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	root, err := block.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	mockBlocker := &testutil.MockBlocker{
+		RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{
+			parentRoot: signedParent,
+			root:       signedBlock,
+		},
+		SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
+			slot.Sub(1): signedParent,
+			slot:        signedBlock,
+		},
+	}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot.Sub(1): attestedState,
+			slot:        st,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
+	count := 129 // config.MaxRequestLightClientUpdates is 128
+	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
+	request := httptest.NewRequest("GET", url, nil)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientUpdatesByRange(writer, request)
+
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientUpdatesByRangeResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderCapella
+	err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case.
+	require.Equal(t, "capella", resp.Updates[0].Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp)
+}
+
+func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCountDeneb(t *testing.T) {
+	helpers.ClearCache()
+	ctx := context.Background()
+	config := params.BeaconConfig()
+	slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+
+	attestedState, err := util.NewBeaconStateDeneb()
+	require.NoError(t, err)
+	err = attestedState.SetSlot(slot.Sub(1))
+	require.NoError(t, err)
+
+	parent := util.NewBeaconBlockDeneb()
+	parent.Block.Slot = slot.Sub(1)
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(t, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(t, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	st, err := util.NewBeaconStateDeneb()
+	require.NoError(t, err)
+	err = st.SetSlot(slot)
+	require.NoError(t, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(t, err)
+
+	block := util.NewBeaconBlockDeneb()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < config.SyncCommitteeSize; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	err = st.SetLatestBlockHeader(h.Header)
+	require.NoError(t, err)
+	stateRoot, err := st.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	root, err := block.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	mockBlocker := &testutil.MockBlocker{
+		RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{
+			parentRoot: signedParent,
+			root:       signedBlock,
+		},
+		SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
+			slot.Sub(1): signedParent,
+			slot:        signedBlock,
+		},
+	}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot.Sub(1): attestedState,
+			slot:        st,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
+	count := 129 // config.MaxRequestLightClientUpdates is 128
+	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
+	request := httptest.NewRequest("GET", url, nil)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientUpdatesByRange(writer, request)
+
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientUpdatesByRangeResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderDeneb
+	err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(resp.Updates)) // Even with big count input, the response is still the max available period, which is 1 in test case.
+	require.Equal(t, "deneb", resp.Updates[0].Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp)
+}
+
+// TODO - check for not having any blocks from the min period, and startPeriod being too early
+func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriodAltair(t *testing.T) {
+	helpers.ClearCache()
+	ctx := context.Background()
+	config := params.BeaconConfig()
+	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+
+	attestedState, err := util.NewBeaconStateAltair()
+	require.NoError(t, err)
+	err = attestedState.SetSlot(slot.Sub(1))
+	require.NoError(t, err)
+
+	parent := util.NewBeaconBlockAltair()
+	parent.Block.Slot = slot.Sub(1)
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(t, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(t, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	st, err := util.NewBeaconStateAltair()
+	require.NoError(t, err)
+	err = st.SetSlot(slot)
+	require.NoError(t, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(t, err)
+
+	block := util.NewBeaconBlockAltair()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < config.SyncCommitteeSize; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	h, err := signedBlock.Header()
 	require.NoError(t, err)
 
-	r, err := b.Block.HashTreeRoot()
+	err = st.SetLatestBlockHeader(h.Header)
+	require.NoError(t, err)
+	stateRoot, err := st.HashTreeRoot(ctx)
 	require.NoError(t, err)
 
-	bs, err := util.NewBeaconStateCapella(func(state *ethpb.BeaconStateCapella) error {
-		state.BlockRoots[0] = r[:]
-		return nil
-	})
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
 	require.NoError(t, err)
 
-	require.NoError(t, bs.SetSlot(slot))
-	require.NoError(t, bs.SetLatestBlockHeader(header.Header))
+	root, err := block.Block.HashTreeRoot()
+	require.NoError(t, err)
 
-	mockBlocker := &testutil.MockBlocker{BlockToReturn: signedBlock}
-	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot}
+	mockBlocker := &testutil.MockBlocker{
+		RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{
+			parentRoot: signedParent,
+			root:       signedBlock,
+		},
+		SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
+			slot.Sub(1): signedParent,
+			slot:        signedBlock,
+		},
+	}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
 	s := &Server{
 		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
-			slot: bs,
+			slot.Sub(1): attestedState,
+			slot:        st,
 		}},
 		Blocker:     mockBlocker,
 		HeadFetcher: mockChainService,
 	}
-	muxVars := make(map[string]string)
-	muxVars["block_root"] = hexutil.Encode(r[:])
-	request := httptest.NewRequest("GET", "http://foo.com/", nil)
-	request = mux.SetURLVars(request, muxVars)
+	startPeriod := 1 // very early period before Altair fork
+	count := 1
+	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
+	request := httptest.NewRequest("GET", url, nil)
 	writer := httptest.NewRecorder()
 	writer.Body = &bytes.Buffer{}
 
-	s.GetLightClientBootstrap(writer, request)
+	s.GetLightClientUpdatesByRange(writer, request)
+
 	require.Equal(t, http.StatusOK, writer.Code)
-	resp := &structs.LightClientBootstrapResponse{}
-	require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
-	require.Equal(t, "capella", resp.Version)
-	require.Equal(t, hexutil.Encode(header.Header.BodyRoot), resp.Data.Header.Beacon.BodyRoot)
-	require.NotNil(t, resp.Data)
+	var resp structs.LightClientUpdatesByRangeResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeader
+	err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(resp.Updates))
+	require.Equal(t, "altair", resp.Updates[0].Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp)
 }
 
-func TestLightClientHandler_GetLightClientUpdatesByRange(t *testing.T) {
+// TODO - same as above
+func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCountAltair(t *testing.T) {
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
 	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
 
-	attestedState, err := util.NewBeaconStateCapella()
+	attestedState, err := util.NewBeaconStateAltair()
 	require.NoError(t, err)
 	err = attestedState.SetSlot(slot.Sub(1))
 	require.NoError(t, err)
 
-	parent := util.NewBeaconBlockCapella()
+	parent := util.NewBeaconBlockAltair()
 	parent.Block.Slot = slot.Sub(1)
 
 	signedParent, err := blocks.NewSignedBeaconBlock(parent)
@@ -108,7 +970,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange(t *testing.T) {
 	signedParent, err = blocks.NewSignedBeaconBlock(parent)
 	require.NoError(t, err)
 
-	st, err := util.NewBeaconStateCapella()
+	st, err := util.NewBeaconStateAltair()
 	require.NoError(t, err)
 	err = st.SetSlot(slot)
 	require.NoError(t, err)
@@ -116,7 +978,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange(t *testing.T) {
 	parentRoot, err := signedParent.Block().HashTreeRoot()
 	require.NoError(t, err)
 
-	block := util.NewBeaconBlockCapella()
+	block := util.NewBeaconBlockAltair()
 	block.Block.Slot = slot
 	block.Block.ParentRoot = parentRoot[:]
 
@@ -162,8 +1024,9 @@ func TestLightClientHandler_GetLightClientUpdatesByRange(t *testing.T) {
 		Blocker:     mockBlocker,
 		HeadFetcher: mockChainService,
 	}
-	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
-	url := fmt.Sprintf("http://foo.com/?count=1&start_period=%d", startPeriod)
+	startPeriod := 1 // very early period before Altair fork
+	count := 10      // This is big count as we only have one period in test case.
+	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
 	request := httptest.NewRequest("GET", url, nil)
 	writer := httptest.NewRecorder()
 	writer.Body = &bytes.Buffer{}
@@ -171,19 +1034,23 @@ func TestLightClientHandler_GetLightClientUpdatesByRange(t *testing.T) {
 	s.GetLightClientUpdatesByRange(writer, request)
 
 	require.Equal(t, http.StatusOK, writer.Code)
-	var resp []structs.LightClientUpdateWithVersion
-	require.NoError(t, json.Unmarshal(writer.Body.Bytes(), &resp))
-	require.Equal(t, 1, len(resp))
-	require.Equal(t, "capella", resp[0].Version)
-	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), resp[0].Data.AttestedHeader.Beacon.BodyRoot)
+	var resp structs.LightClientUpdatesByRangeResponse
+	err = json.Unmarshal(writer.Body.Bytes(), &resp.Updates)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeader
+	err = json.Unmarshal(resp.Updates[0].Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(resp.Updates))
+	require.Equal(t, "altair", resp.Updates[0].Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
 	require.NotNil(t, resp)
 }
 
-func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCount(t *testing.T) {
+func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing.T) {
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
-	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Sub(1)
 
 	attestedState, err := util.NewBeaconStateCapella()
 	require.NoError(t, err)
@@ -265,7 +1132,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCount(t *tes
 		HeadFetcher: mockChainService,
 	}
 	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
-	count := 129 // config.MaxRequestLightClientUpdates is 128
+	count := 1
 	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
 	request := httptest.NewRequest("GET", url, nil)
 	writer := httptest.NewRecorder()
@@ -273,27 +1140,26 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigInputCount(t *tes
 
 	s.GetLightClientUpdatesByRange(writer, request)
 
-	require.Equal(t, http.StatusOK, writer.Code)
-	var resp []structs.LightClientUpdateWithVersion
-	require.NoError(t, json.Unmarshal(writer.Body.Bytes(), &resp))
-	require.Equal(t, 1, len(resp)) // Even with big count input, the response is still the max available period, which is 1 in test case.
-	require.Equal(t, "capella", resp[0].Version)
-	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), resp[0].Data.AttestedHeader.Beacon.BodyRoot)
-	require.NotNil(t, resp)
+	require.Equal(t, http.StatusNotFound, writer.Code)
 }
 
-func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriod(t *testing.T) {
+func TestLightClientHandler_GetLightClientFinalityUpdateAltair(t *testing.T) {
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
 	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
 
-	attestedState, err := util.NewBeaconStateCapella()
+	attestedState, err := util.NewBeaconStateAltair()
 	require.NoError(t, err)
 	err = attestedState.SetSlot(slot.Sub(1))
 	require.NoError(t, err)
 
-	parent := util.NewBeaconBlockCapella()
+	require.NoError(t, attestedState.SetFinalizedCheckpoint(&ethpb.Checkpoint{
+		Epoch: config.AltairForkEpoch - 10,
+		Root:  make([]byte, 32),
+	}))
+
+	parent := util.NewBeaconBlockAltair()
 	parent.Block.Slot = slot.Sub(1)
 
 	signedParent, err := blocks.NewSignedBeaconBlock(parent)
@@ -313,7 +1179,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriod(t *testi
 	signedParent, err = blocks.NewSignedBeaconBlock(parent)
 	require.NoError(t, err)
 
-	st, err := util.NewBeaconStateCapella()
+	st, err := util.NewBeaconStateAltair()
 	require.NoError(t, err)
 	err = st.SetSlot(slot)
 	require.NoError(t, err)
@@ -321,7 +1187,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriod(t *testi
 	parentRoot, err := signedParent.Block().HashTreeRoot()
 	require.NoError(t, err)
 
-	block := util.NewBeaconBlockCapella()
+	block := util.NewBeaconBlockAltair()
 	block.Block.Slot = slot
 	block.Block.ParentRoot = parentRoot[:]
 
@@ -358,7 +1224,9 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriod(t *testi
 			slot:        signedBlock,
 		},
 	}
-	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{
+		root: true,
+	}}
 	s := &Server{
 		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
 			slot.Sub(1): attestedState,
@@ -367,35 +1235,40 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooEarlyPeriod(t *testi
 		Blocker:     mockBlocker,
 		HeadFetcher: mockChainService,
 	}
-	startPeriod := 1 // very early period before Altair fork
-	count := 1
-	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
-	request := httptest.NewRequest("GET", url, nil)
+	request := httptest.NewRequest("GET", "http://foo.com", nil)
 	writer := httptest.NewRecorder()
 	writer.Body = &bytes.Buffer{}
 
-	s.GetLightClientUpdatesByRange(writer, request)
+	s.GetLightClientFinalityUpdate(writer, request)
 
 	require.Equal(t, http.StatusOK, writer.Code)
-	var resp []structs.LightClientUpdateWithVersion
-	require.NoError(t, json.Unmarshal(writer.Body.Bytes(), &resp))
-	require.Equal(t, 1, len(resp))
-	require.Equal(t, "capella", resp[0].Version)
-	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), resp[0].Data.AttestedHeader.Beacon.BodyRoot)
-	require.NotNil(t, resp)
+	var resp structs.LightClientUpdateWithVersion
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeader
+	err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, "altair", resp.Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp.Data)
 }
 
-func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCount(t *testing.T) {
+func TestLightClientHandler_GetLightClientFinalityUpdateCapella(t *testing.T) {
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
-	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+	slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
 
 	attestedState, err := util.NewBeaconStateCapella()
 	require.NoError(t, err)
 	err = attestedState.SetSlot(slot.Sub(1))
 	require.NoError(t, err)
 
+	require.NoError(t, attestedState.SetFinalizedCheckpoint(&ethpb.Checkpoint{
+		Epoch: config.AltairForkEpoch - 10,
+		Root:  make([]byte, 32),
+	}))
+
 	parent := util.NewBeaconBlockCapella()
 	parent.Block.Slot = slot.Sub(1)
 
@@ -461,7 +1334,9 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCount(t *testing.
 			slot:        signedBlock,
 		},
 	}
-	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{
+		root: true,
+	}}
 	s := &Server{
 		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
 			slot.Sub(1): attestedState,
@@ -470,36 +1345,41 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_TooBigCount(t *testing.
 		Blocker:     mockBlocker,
 		HeadFetcher: mockChainService,
 	}
-	startPeriod := 1 // very early period before Altair fork
-	count := 10      // This is big count as we only have one period in test case.
-	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
-	request := httptest.NewRequest("GET", url, nil)
+	request := httptest.NewRequest("GET", "http://foo.com", nil)
 	writer := httptest.NewRecorder()
 	writer.Body = &bytes.Buffer{}
 
-	s.GetLightClientUpdatesByRange(writer, request)
+	s.GetLightClientFinalityUpdate(writer, request)
 
 	require.Equal(t, http.StatusOK, writer.Code)
-	var resp []structs.LightClientUpdateWithVersion
-	require.NoError(t, json.Unmarshal(writer.Body.Bytes(), &resp))
-	require.Equal(t, 1, len(resp))
-	require.Equal(t, "capella", resp[0].Version)
-	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), resp[0].Data.AttestedHeader.Beacon.BodyRoot)
-	require.NotNil(t, resp)
+	var resp structs.LightClientUpdateWithVersion
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeader
+	err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, "capella", resp.Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp.Data)
 }
 
-func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing.T) {
+func TestLightClientHandler_GetLightClientFinalityUpdateDeneb(t *testing.T) {
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
-	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Sub(1)
+	slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
 
-	attestedState, err := util.NewBeaconStateCapella()
+	attestedState, err := util.NewBeaconStateDeneb()
 	require.NoError(t, err)
 	err = attestedState.SetSlot(slot.Sub(1))
 	require.NoError(t, err)
 
-	parent := util.NewBeaconBlockCapella()
+	require.NoError(t, attestedState.SetFinalizedCheckpoint(&ethpb.Checkpoint{
+		Epoch: config.AltairForkEpoch - 10,
+		Root:  make([]byte, 32),
+	}))
+
+	parent := util.NewBeaconBlockDeneb()
 	parent.Block.Slot = slot.Sub(1)
 
 	signedParent, err := blocks.NewSignedBeaconBlock(parent)
@@ -519,7 +1399,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing
 	signedParent, err = blocks.NewSignedBeaconBlock(parent)
 	require.NoError(t, err)
 
-	st, err := util.NewBeaconStateCapella()
+	st, err := util.NewBeaconStateDeneb()
 	require.NoError(t, err)
 	err = st.SetSlot(slot)
 	require.NoError(t, err)
@@ -527,7 +1407,7 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing
 	parentRoot, err := signedParent.Block().HashTreeRoot()
 	require.NoError(t, err)
 
-	block := util.NewBeaconBlockCapella()
+	block := util.NewBeaconBlockDeneb()
 	block.Block.Slot = slot
 	block.Block.ParentRoot = parentRoot[:]
 
@@ -564,7 +1444,9 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing
 			slot:        signedBlock,
 		},
 	}
-	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{
+		root: true,
+	}}
 	s := &Server{
 		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
 			slot.Sub(1): attestedState,
@@ -573,25 +1455,31 @@ func TestLightClientHandler_GetLightClientUpdatesByRange_BeforeAltair(t *testing
 		Blocker:     mockBlocker,
 		HeadFetcher: mockChainService,
 	}
-	startPeriod := slot.Div(uint64(config.EpochsPerSyncCommitteePeriod)).Div(uint64(config.SlotsPerEpoch))
-	count := 1
-	url := fmt.Sprintf("http://foo.com/?count=%d&start_period=%d", count, startPeriod)
-	request := httptest.NewRequest("GET", url, nil)
+	request := httptest.NewRequest("GET", "http://foo.com", nil)
 	writer := httptest.NewRecorder()
 	writer.Body = &bytes.Buffer{}
 
-	s.GetLightClientUpdatesByRange(writer, request)
+	s.GetLightClientFinalityUpdate(writer, request)
 
-	require.Equal(t, http.StatusNotFound, writer.Code)
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientUpdateWithVersion
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderDeneb
+	err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, "deneb", resp.Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp.Data)
 }
 
-func TestLightClientHandler_GetLightClientFinalityUpdate(t *testing.T) {
+func TestLightClientHandler_GetLightClientOptimisticUpdateAltair(t *testing.T) {
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
 	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
 
-	attestedState, err := util.NewBeaconStateCapella()
+	attestedState, err := util.NewBeaconStateAltair()
 	require.NoError(t, err)
 	err = attestedState.SetSlot(slot.Sub(1))
 	require.NoError(t, err)
@@ -601,7 +1489,7 @@ func TestLightClientHandler_GetLightClientFinalityUpdate(t *testing.T) {
 		Root:  make([]byte, 32),
 	}))
 
-	parent := util.NewBeaconBlockCapella()
+	parent := util.NewBeaconBlockAltair()
 	parent.Block.Slot = slot.Sub(1)
 
 	signedParent, err := blocks.NewSignedBeaconBlock(parent)
@@ -621,7 +1509,7 @@ func TestLightClientHandler_GetLightClientFinalityUpdate(t *testing.T) {
 	signedParent, err = blocks.NewSignedBeaconBlock(parent)
 	require.NoError(t, err)
 
-	st, err := util.NewBeaconStateCapella()
+	st, err := util.NewBeaconStateAltair()
 	require.NoError(t, err)
 	err = st.SetSlot(slot)
 	require.NoError(t, err)
@@ -629,7 +1517,7 @@ func TestLightClientHandler_GetLightClientFinalityUpdate(t *testing.T) {
 	parentRoot, err := signedParent.Block().HashTreeRoot()
 	require.NoError(t, err)
 
-	block := util.NewBeaconBlockCapella()
+	block := util.NewBeaconBlockAltair()
 	block.Block.Slot = slot
 	block.Block.ParentRoot = parentRoot[:]
 
@@ -681,21 +1569,25 @@ func TestLightClientHandler_GetLightClientFinalityUpdate(t *testing.T) {
 	writer := httptest.NewRecorder()
 	writer.Body = &bytes.Buffer{}
 
-	s.GetLightClientFinalityUpdate(writer, request)
+	s.GetLightClientOptimisticUpdate(writer, request)
 
 	require.Equal(t, http.StatusOK, writer.Code)
-	resp := &structs.LightClientUpdateWithVersion{}
-	require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
-	require.Equal(t, "capella", resp.Version)
-	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), resp.Data.AttestedHeader.Beacon.BodyRoot)
+	var resp structs.LightClientUpdateWithVersion
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeader
+	err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, "altair", resp.Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
 	require.NotNil(t, resp.Data)
 }
 
-func TestLightClientHandler_GetLightClientOptimisticUpdate(t *testing.T) {
+func TestLightClientHandler_GetLightClientOptimisticUpdateCapella(t *testing.T) {
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
-	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+	slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
 
 	attestedState, err := util.NewBeaconStateCapella()
 	require.NoError(t, err)
@@ -790,10 +1682,124 @@ func TestLightClientHandler_GetLightClientOptimisticUpdate(t *testing.T) {
 	s.GetLightClientOptimisticUpdate(writer, request)
 
 	require.Equal(t, http.StatusOK, writer.Code)
-	resp := &structs.LightClientUpdateWithVersion{}
-	require.NoError(t, json.Unmarshal(writer.Body.Bytes(), resp))
+	var resp structs.LightClientUpdateWithVersion
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderCapella
+	err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
 	require.Equal(t, "capella", resp.Version)
-	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), resp.Data.AttestedHeader.Beacon.BodyRoot)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
+	require.NotNil(t, resp.Data)
+}
+
+func TestLightClientHandler_GetLightClientOptimisticUpdateDeneb(t *testing.T) {
+	helpers.ClearCache()
+	ctx := context.Background()
+	config := params.BeaconConfig()
+	slot := primitives.Slot(config.DenebForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+
+	attestedState, err := util.NewBeaconStateDeneb()
+	require.NoError(t, err)
+	err = attestedState.SetSlot(slot.Sub(1))
+	require.NoError(t, err)
+
+	require.NoError(t, attestedState.SetFinalizedCheckpoint(&ethpb.Checkpoint{
+		Epoch: config.AltairForkEpoch - 10,
+		Root:  make([]byte, 32),
+	}))
+
+	parent := util.NewBeaconBlockDeneb()
+	parent.Block.Slot = slot.Sub(1)
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(t, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(t, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(t, err)
+
+	st, err := util.NewBeaconStateDeneb()
+	require.NoError(t, err)
+	err = st.SetSlot(slot)
+	require.NoError(t, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(t, err)
+
+	block := util.NewBeaconBlockDeneb()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < config.SyncCommitteeSize; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(t, err)
+
+	err = st.SetLatestBlockHeader(h.Header)
+	require.NoError(t, err)
+	stateRoot, err := st.HashTreeRoot(ctx)
+	require.NoError(t, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(t, err)
+
+	root, err := block.Block.HashTreeRoot()
+	require.NoError(t, err)
+
+	mockBlocker := &testutil.MockBlocker{
+		RootBlockMap: map[[32]byte]interfaces.ReadOnlySignedBeaconBlock{
+			parentRoot: signedParent,
+			root:       signedBlock,
+		},
+		SlotBlockMap: map[primitives.Slot]interfaces.ReadOnlySignedBeaconBlock{
+			slot.Sub(1): signedParent,
+			slot:        signedBlock,
+		},
+	}
+	mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot, State: st, FinalizedRoots: map[[32]byte]bool{
+		root: true,
+	}}
+	s := &Server{
+		Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{
+			slot.Sub(1): attestedState,
+			slot:        st,
+		}},
+		Blocker:     mockBlocker,
+		HeadFetcher: mockChainService,
+	}
+	request := httptest.NewRequest("GET", "http://foo.com", nil)
+	writer := httptest.NewRecorder()
+	writer.Body = &bytes.Buffer{}
+
+	s.GetLightClientOptimisticUpdate(writer, request)
+
+	require.Equal(t, http.StatusOK, writer.Code)
+	var resp structs.LightClientUpdateWithVersion
+	err = json.Unmarshal(writer.Body.Bytes(), &resp)
+	require.NoError(t, err)
+	var respHeader structs.LightClientHeaderDeneb
+	err = json.Unmarshal(resp.Data.AttestedHeader, &respHeader)
+	require.NoError(t, err)
+	require.Equal(t, "deneb", resp.Version)
+	require.Equal(t, hexutil.Encode(attestedHeader.BodyRoot), respHeader.Beacon.BodyRoot)
 	require.NotNil(t, resp.Data)
 }
 
@@ -801,7 +1807,7 @@ func TestLightClientHandler_GetLightClientEventBlock(t *testing.T) {
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
-	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+	slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
 
 	attestedState, err := util.NewBeaconStateCapella()
 	require.NoError(t, err)
@@ -905,7 +1911,7 @@ func TestLightClientHandler_GetLightClientEventBlock_NeedFetchParent(t *testing.
 	helpers.ClearCache()
 	ctx := context.Background()
 	config := params.BeaconConfig()
-	slot := primitives.Slot(config.AltairForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
+	slot := primitives.Slot(config.CapellaForkEpoch * primitives.Epoch(config.SlotsPerEpoch)).Add(1)
 
 	attestedState, err := util.NewBeaconStateCapella()
 	require.NoError(t, err)
diff --git a/beacon-chain/rpc/eth/light-client/helpers.go b/beacon-chain/rpc/eth/light-client/helpers.go
index c871f8b4943a..aa5f8a6b81dd 100644
--- a/beacon-chain/rpc/eth/light-client/helpers.go
+++ b/beacon-chain/rpc/eth/light-client/helpers.go
@@ -2,17 +2,24 @@ package lightclient
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 	"reflect"
 	"strconv"
 
+	"github.com/pkg/errors"
+
 	lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client"
+	consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types"
+	"github.com/prysmaticlabs/prysm/v5/encoding/ssz"
+	"github.com/prysmaticlabs/prysm/v5/runtime/version"
 
 	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/prysmaticlabs/prysm/v5/api/server/structs"
 	"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
 	fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
 	"github.com/prysmaticlabs/prysm/v5/config/params"
+	"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
 	"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
 	v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
 	v2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
@@ -20,7 +27,21 @@ import (
 	"github.com/prysmaticlabs/prysm/v5/time/slots"
 )
 
-// createLightClientBootstrap - implements https://github.com/ethereum/consensus-specs/blob/3d235740e5f1e641d3b160c8688f26e7dc5a1894/specs/altair/light-client/full-node.md#create_light_client_bootstrap
+func createLightClientBootstrap(ctx context.Context, state state.BeaconState, blk interfaces.ReadOnlyBeaconBlock) (*structs.LightClientBootstrap, error) {
+	switch blk.Version() {
+	case version.Phase0:
+		return nil, fmt.Errorf("light client bootstrap is not supported for phase0")
+	case version.Altair, version.Bellatrix:
+		return createLightClientBootstrapAltair(ctx, state)
+	case version.Capella:
+		return createLightClientBootstrapCapella(ctx, state, blk)
+	case version.Deneb, version.Electra:
+		return createLightClientBootstrapDeneb(ctx, state, blk)
+	}
+	return nil, fmt.Errorf("unsupported block version %s", version.String(blk.Version()))
+}
+
+// createLightClientBootstrapAltair - implements https://github.com/ethereum/consensus-specs/blob/3d235740e5f1e641d3b160c8688f26e7dc5a1894/specs/altair/light-client/full-node.md#create_light_client_bootstrap
 // def create_light_client_bootstrap(state: BeaconState) -> LightClientBootstrap:
 //
 //	assert compute_epoch_at_slot(state.slot) >= ALTAIR_FORK_EPOCH
@@ -37,7 +58,7 @@ import (
 //	    current_sync_committee=state.current_sync_committee,
 //	    current_sync_committee_branch=compute_merkle_proof_for_state(state, CURRENT_SYNC_COMMITTEE_INDEX)
 //	)
-func createLightClientBootstrap(ctx context.Context, state state.BeaconState) (*structs.LightClientBootstrap, error) {
+func createLightClientBootstrapAltair(ctx context.Context, state state.BeaconState) (*structs.LightClientBootstrap, error) {
 	// assert compute_epoch_at_slot(state.slot) >= ALTAIR_FORK_EPOCH
 	if slots.ToEpoch(state.Slot()) < params.BeaconConfig().AltairForkEpoch {
 		return nil, fmt.Errorf("light client bootstrap is not supported before Altair, invalid slot %d", state.Slot())
@@ -52,14 +73,14 @@ func createLightClientBootstrap(ctx context.Context, state state.BeaconState) (*
 	// Prepare data
 	currentSyncCommittee, err := state.CurrentSyncCommittee()
 	if err != nil {
-		return nil, fmt.Errorf("could not get current sync committee: %s", err.Error())
+		return nil, errors.Wrap(err, "could not get current sync committee")
 	}
 
 	committee := structs.SyncCommitteeFromConsensus(currentSyncCommittee)
 
 	currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx)
 	if err != nil {
-		return nil, fmt.Errorf("could not get current sync committee proof: %s", err.Error())
+		return nil, errors.Wrap(err, "could not get current sync committee proof")
 	}
 
 	branch := make([]string, fieldparams.NextSyncCommitteeBranchDepth)
@@ -78,13 +99,249 @@ func createLightClientBootstrap(ctx context.Context, state state.BeaconState) (*
 	// Above shared util function won't calculate state root, so we need to do it manually
 	stateRoot, err := state.HashTreeRoot(ctx)
 	if err != nil {
-		return nil, fmt.Errorf("could not get state root: %s", err.Error())
+		return nil, errors.Wrap(err, "could not get state root")
 	}
 	header.Beacon.StateRoot = hexutil.Encode(stateRoot[:])
 
+	headerJson, err := json.Marshal(header)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not convert header to raw message")
+	}
+
 	// Return result
 	result := &structs.LightClientBootstrap{
-		Header:                     header,
+		Header:                     headerJson,
+		CurrentSyncCommittee:       committee,
+		CurrentSyncCommitteeBranch: branch,
+	}
+
+	return result, nil
+}
+
+func createLightClientBootstrapCapella(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlyBeaconBlock) (*structs.LightClientBootstrap, error) {
+	// assert compute_epoch_at_slot(state.slot) >= CAPELLA_FORK_EPOCH
+	if slots.ToEpoch(state.Slot()) < params.BeaconConfig().CapellaForkEpoch {
+		return nil, fmt.Errorf("creating Capella light client bootstrap is not supported before Capella, invalid slot %d", state.Slot())
+	}
+
+	// assert state.slot == state.latest_block_header.slot
+	latestBlockHeader := state.LatestBlockHeader()
+	if state.Slot() != latestBlockHeader.Slot {
+		return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot)
+	}
+
+	// Prepare data
+	currentSyncCommittee, err := state.CurrentSyncCommittee()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get current sync committee")
+	}
+
+	committee := structs.SyncCommitteeFromConsensus(currentSyncCommittee)
+
+	currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get current sync committee proof")
+	}
+
+	branch := make([]string, fieldparams.NextSyncCommitteeBranchDepth)
+	for i, proof := range currentSyncCommitteeProof {
+		branch[i] = hexutil.Encode(proof)
+	}
+
+	beacon := structs.BeaconBlockHeaderFromConsensus(latestBlockHeader)
+
+	payloadInterface, err := block.Body().Execution()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get execution payload")
+	}
+	transactionsRoot, err := payloadInterface.TransactionsRoot()
+	if errors.Is(err, consensus_types.ErrUnsupportedField) {
+		transactions, err := payloadInterface.Transactions()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get transactions")
+		}
+		transactionsRootArray, err := ssz.TransactionsRoot(transactions)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get transactions root")
+		}
+		transactionsRoot = transactionsRootArray[:]
+	} else if err != nil {
+		return nil, errors.Wrap(err, "could not get transactions root")
+	}
+	withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
+	if errors.Is(err, consensus_types.ErrUnsupportedField) {
+		withdrawals, err := payloadInterface.Withdrawals()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get withdrawals")
+		}
+		withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get withdrawals root")
+		}
+		withdrawalsRoot = withdrawalsRootArray[:]
+	}
+	executionPayloadHeader := &structs.ExecutionPayloadHeaderCapella{
+		ParentHash:       hexutil.Encode(payloadInterface.ParentHash()),
+		FeeRecipient:     hexutil.Encode(payloadInterface.FeeRecipient()),
+		StateRoot:        hexutil.Encode(payloadInterface.StateRoot()),
+		ReceiptsRoot:     hexutil.Encode(payloadInterface.ReceiptsRoot()),
+		LogsBloom:        hexutil.Encode(payloadInterface.LogsBloom()),
+		PrevRandao:       hexutil.Encode(payloadInterface.PrevRandao()),
+		BlockNumber:      hexutil.EncodeUint64(payloadInterface.BlockNumber()),
+		GasLimit:         hexutil.EncodeUint64(payloadInterface.GasLimit()),
+		GasUsed:          hexutil.EncodeUint64(payloadInterface.GasUsed()),
+		Timestamp:        hexutil.EncodeUint64(payloadInterface.Timestamp()),
+		ExtraData:        hexutil.Encode(payloadInterface.ExtraData()),
+		BaseFeePerGas:    hexutil.Encode(payloadInterface.BaseFeePerGas()),
+		BlockHash:        hexutil.Encode(payloadInterface.BlockHash()),
+		TransactionsRoot: hexutil.Encode(transactionsRoot),
+		WithdrawalsRoot:  hexutil.Encode(withdrawalsRoot),
+	}
+
+	executionPayloadProof, err := blocks.PayloadProof(ctx, block)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get execution payload proof")
+	}
+	executionPayloadProofStr := make([]string, len(executionPayloadProof))
+	for i, proof := range executionPayloadProof {
+		executionPayloadProofStr[i] = hexutil.Encode(proof)
+	}
+	header := &structs.LightClientHeaderCapella{
+		Beacon:          beacon,
+		Execution:       executionPayloadHeader,
+		ExecutionBranch: executionPayloadProofStr,
+	}
+
+	// Above shared util function won't calculate state root, so we need to do it manually
+	stateRoot, err := state.HashTreeRoot(ctx)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get state root")
+	}
+	header.Beacon.StateRoot = hexutil.Encode(stateRoot[:])
+
+	headerJson, err := json.Marshal(header)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not convert header to raw message")
+	}
+
+	// Return result
+	result := &structs.LightClientBootstrap{
+		Header:                     headerJson,
+		CurrentSyncCommittee:       committee,
+		CurrentSyncCommitteeBranch: branch,
+	}
+
+	return result, nil
+}
+
+func createLightClientBootstrapDeneb(ctx context.Context, state state.BeaconState, block interfaces.ReadOnlyBeaconBlock) (*structs.LightClientBootstrap, error) {
+	// assert compute_epoch_at_slot(state.slot) >= DENEB_FORK_EPOCH
+	if slots.ToEpoch(state.Slot()) < params.BeaconConfig().DenebForkEpoch {
+		return nil, fmt.Errorf("creating Deneb light client bootstrap is not supported before Deneb, invalid slot %d", state.Slot())
+	}
+
+	// assert state.slot == state.latest_block_header.slot
+	latestBlockHeader := state.LatestBlockHeader()
+	if state.Slot() != latestBlockHeader.Slot {
+		return nil, fmt.Errorf("state slot %d not equal to latest block header slot %d", state.Slot(), latestBlockHeader.Slot)
+	}
+
+	// Prepare data
+	currentSyncCommittee, err := state.CurrentSyncCommittee()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get current sync committee")
+	}
+
+	committee := structs.SyncCommitteeFromConsensus(currentSyncCommittee)
+
+	currentSyncCommitteeProof, err := state.CurrentSyncCommitteeProof(ctx)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get current sync committee proof")
+	}
+
+	branch := make([]string, fieldparams.NextSyncCommitteeBranchDepth)
+	for i, proof := range currentSyncCommitteeProof {
+		branch[i] = hexutil.Encode(proof)
+	}
+
+	beacon := structs.BeaconBlockHeaderFromConsensus(latestBlockHeader)
+
+	payloadInterface, err := block.Body().Execution()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get execution payload")
+	}
+	transactionsRoot, err := payloadInterface.TransactionsRoot()
+	if errors.Is(err, consensus_types.ErrUnsupportedField) {
+		transactions, err := payloadInterface.Transactions()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get transactions")
+		}
+		transactionsRootArray, err := ssz.TransactionsRoot(transactions)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get transactions root")
+		}
+		transactionsRoot = transactionsRootArray[:]
+	} else if err != nil {
+		return nil, errors.Wrap(err, "could not get transactions root")
+	}
+	withdrawalsRoot, err := payloadInterface.WithdrawalsRoot()
+	if errors.Is(err, consensus_types.ErrUnsupportedField) {
+		withdrawals, err := payloadInterface.Withdrawals()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get withdrawals")
+		}
+		withdrawalsRootArray, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get withdrawals root")
+		}
+		withdrawalsRoot = withdrawalsRootArray[:]
+	}
+	executionPayloadHeader := &structs.ExecutionPayloadHeaderDeneb{
+		ParentHash:       hexutil.Encode(payloadInterface.ParentHash()),
+		FeeRecipient:     hexutil.Encode(payloadInterface.FeeRecipient()),
+		StateRoot:        hexutil.Encode(payloadInterface.StateRoot()),
+		ReceiptsRoot:     hexutil.Encode(payloadInterface.ReceiptsRoot()),
+		LogsBloom:        hexutil.Encode(payloadInterface.LogsBloom()),
+		PrevRandao:       hexutil.Encode(payloadInterface.PrevRandao()),
+		BlockNumber:      hexutil.EncodeUint64(payloadInterface.BlockNumber()),
+		GasLimit:         hexutil.EncodeUint64(payloadInterface.GasLimit()),
+		GasUsed:          hexutil.EncodeUint64(payloadInterface.GasUsed()),
+		Timestamp:        hexutil.EncodeUint64(payloadInterface.Timestamp()),
+		ExtraData:        hexutil.Encode(payloadInterface.ExtraData()),
+		BaseFeePerGas:    hexutil.Encode(payloadInterface.BaseFeePerGas()),
+		BlockHash:        hexutil.Encode(payloadInterface.BlockHash()),
+		TransactionsRoot: hexutil.Encode(transactionsRoot),
+		WithdrawalsRoot:  hexutil.Encode(withdrawalsRoot),
+	}
+
+	executionPayloadProof, err := blocks.PayloadProof(ctx, block)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get execution payload proof")
+	}
+	executionPayloadProofStr := make([]string, len(executionPayloadProof))
+	for i, proof := range executionPayloadProof {
+		executionPayloadProofStr[i] = hexutil.Encode(proof)
+	}
+	header := &structs.LightClientHeaderDeneb{
+		Beacon:          beacon,
+		Execution:       executionPayloadHeader,
+		ExecutionBranch: executionPayloadProofStr,
+	}
+
+	// Above shared util function won't calculate state root, so we need to do it manually
+	stateRoot, err := state.HashTreeRoot(ctx)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get state root")
+	}
+	header.Beacon.StateRoot = hexutil.Encode(stateRoot[:])
+
+	headerJson, err := json.Marshal(header)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not convert header to raw message")
+	}
+	// Return result
+	result := &structs.LightClientBootstrap{
+		Header:                     headerJson,
 		CurrentSyncCommittee:       committee,
 		CurrentSyncCommitteeBranch: branch,
 	}
@@ -169,12 +426,16 @@ func createLightClientUpdate(
 	updateSignaturePeriod := slots.SyncCommitteePeriod(slots.ToEpoch(block.Block().Slot()))
 
 	// update_attested_period = compute_sync_committee_period(compute_epoch_at_slot(attested_header.slot))
-	updateAttestedPeriod := slots.SyncCommitteePeriod(slots.ToEpoch(result.AttestedHeader.Beacon.Slot))
+	resultAttestedHeaderBeacon, err := result.AttestedHeader.GetBeacon()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get attested header beacon")
+	}
+	updateAttestedPeriod := slots.SyncCommitteePeriod(slots.ToEpoch(resultAttestedHeaderBeacon.Slot))
 
 	if updateAttestedPeriod == updateSignaturePeriod {
 		tempNextSyncCommittee, err := attestedState.NextSyncCommittee()
 		if err != nil {
-			return nil, fmt.Errorf("could not get next sync committee: %s", err.Error())
+			return nil, errors.Wrap(err, "could not get next sync committee")
 		}
 
 		nextSyncCommittee = &v2.SyncCommittee{
@@ -184,7 +445,7 @@ func createLightClientUpdate(
 
 		nextSyncCommitteeBranch, err = attestedState.NextSyncCommitteeProof(ctx)
 		if err != nil {
-			return nil, fmt.Errorf("could not get next sync committee proof: %s", err.Error())
+			return nil, errors.Wrap(err, "could not get next sync committee proof")
 		}
 	} else {
 		syncCommitteeSize := params.BeaconConfig().SyncCommitteeSize
@@ -205,7 +466,11 @@ func createLightClientUpdate(
 
 	result.NextSyncCommittee = nextSyncCommittee
 	result.NextSyncCommitteeBranch = nextSyncCommitteeBranch
-	return newLightClientUpdateToJSON(result), nil
+	res, err := newLightClientUpdateToJSON(result)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not convert light client update to JSON")
+	}
+	return res, nil
 }
 
 func newLightClientFinalityUpdateFromBeaconState(
@@ -219,7 +484,11 @@ func newLightClientFinalityUpdateFromBeaconState(
 		return nil, err
 	}
 
-	return newLightClientUpdateToJSON(result), nil
+	res, err := newLightClientUpdateToJSON(result)
+	if err != nil {
+		return nil, errors.Wrap(err, "could not convert light client update to JSON")
+	}
+	return res, nil
 }
 
 func newLightClientOptimisticUpdateFromBeaconState(
@@ -232,42 +501,11 @@ func newLightClientOptimisticUpdateFromBeaconState(
 		return nil, err
 	}
 
-	return newLightClientUpdateToJSON(result), nil
-}
-
-func NewLightClientBootstrapFromJSON(bootstrapJSON *structs.LightClientBootstrap) (*v2.LightClientBootstrap, error) {
-	bootstrap := &v2.LightClientBootstrap{}
-
-	var err error
-
-	v1Alpha1Header, err := bootstrapJSON.Header.Beacon.ToConsensus()
+	res, err := newLightClientUpdateToJSON(result)
 	if err != nil {
-		return nil, err
-	}
-	bootstrap.Header = &v2.LightClientHeader{Beacon: migration.V1Alpha1HeaderToV1(v1Alpha1Header)}
-
-	currentSyncCommittee, err := bootstrapJSON.CurrentSyncCommittee.ToConsensus()
-	if err != nil {
-		return nil, err
-	}
-	bootstrap.CurrentSyncCommittee = migration.V1Alpha1SyncCommitteeToV2(currentSyncCommittee)
-
-	if bootstrap.CurrentSyncCommitteeBranch, err = branchFromJSON(bootstrapJSON.CurrentSyncCommitteeBranch); err != nil {
-		return nil, err
-	}
-	return bootstrap, nil
-}
-
-func branchFromJSON(branch []string) ([][]byte, error) {
-	var branchBytes [][]byte
-	for _, root := range branch {
-		branch, err := hexutil.Decode(root)
-		if err != nil {
-			return nil, err
-		}
-		branchBytes = append(branchBytes, branch)
+		return nil, errors.Wrap(err, "could not convert light client update to JSON")
 	}
-	return branchBytes, nil
+	return res, nil
 }
 
 func branchToJSON(branchBytes [][]byte) []string {
@@ -291,9 +529,9 @@ func syncAggregateToJSON(input *v1.SyncAggregate) *structs.SyncAggregate {
 	}
 }
 
-func newLightClientUpdateToJSON(input *v2.LightClientUpdate) *structs.LightClientUpdate {
+func newLightClientUpdateToJSON(input *v2.LightClientUpdate) (*structs.LightClientUpdate, error) {
 	if input == nil {
-		return nil
+		return nil, errors.New("input is nil")
 	}
 
 	var nextSyncCommittee *structs.SyncCommittee
@@ -303,18 +541,36 @@ func newLightClientUpdateToJSON(input *v2.LightClientUpdate) *structs.LightClien
 
 	var finalizedHeader *structs.BeaconBlockHeader
 	if input.FinalizedHeader != nil {
-		finalizedHeader = structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(input.FinalizedHeader.Beacon))
+		inputFinalizedHeaderBeacon, err := input.FinalizedHeader.GetBeacon()
+		if err != nil {
+			return nil, errors.Wrap(err, "could not get finalized header beacon")
+		}
+		finalizedHeader = structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(inputFinalizedHeaderBeacon))
 	}
 
-	return &structs.LightClientUpdate{
-		AttestedHeader:          &structs.LightClientHeader{Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(input.AttestedHeader.Beacon))},
+	inputAttestedHeaderBeacon, err := input.AttestedHeader.GetBeacon()
+	if err != nil {
+		return nil, errors.Wrap(err, "could not get attested header beacon")
+	}
+	attestedHeaderJson, err := json.Marshal(&structs.LightClientHeader{Beacon: structs.BeaconBlockHeaderFromConsensus(migration.V1HeaderToV1Alpha1(inputAttestedHeaderBeacon))})
+	if err != nil {
+		return nil, errors.Wrap(err, "could not convert attested header to raw message")
+	}
+	finalizedHeaderJson, err := json.Marshal(&structs.LightClientHeader{Beacon: finalizedHeader})
+	if err != nil {
+		return nil, errors.Wrap(err, "could not convert finalized header to raw message")
+	}
+	result := &structs.LightClientUpdate{
+		AttestedHeader:          attestedHeaderJson,
 		NextSyncCommittee:       nextSyncCommittee,
 		NextSyncCommitteeBranch: branchToJSON(input.NextSyncCommitteeBranch),
-		FinalizedHeader:         &structs.LightClientHeader{Beacon: finalizedHeader},
+		FinalizedHeader:         finalizedHeaderJson,
 		FinalityBranch:          branchToJSON(input.FinalityBranch),
 		SyncAggregate:           syncAggregateToJSON(input.SyncAggregate),
 		SignatureSlot:           strconv.FormatUint(uint64(input.SignatureSlot), 10),
 	}
+
+	return result, nil
 }
 
 func IsSyncCommitteeUpdate(update *v2.LightClientUpdate) bool {
@@ -327,7 +583,7 @@ func IsFinalityUpdate(update *v2.LightClientUpdate) bool {
 	return !reflect.DeepEqual(update.FinalityBranch, finalityBranch)
 }
 
-func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) bool {
+func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) (bool, error) {
 	maxActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Len()
 	newNumActiveParticipants := newUpdate.SyncAggregate.SyncCommitteeBits.Count()
 	oldNumActiveParticipants := oldUpdate.SyncAggregate.SyncCommitteeBits.Count()
@@ -335,45 +591,63 @@ func IsBetterUpdate(newUpdate, oldUpdate *v2.LightClientUpdate) bool {
 	oldHasSupermajority := oldNumActiveParticipants*3 >= maxActiveParticipants*2
 
 	if newHasSupermajority != oldHasSupermajority {
-		return newHasSupermajority
+		return newHasSupermajority, nil
 	}
 	if !newHasSupermajority && newNumActiveParticipants != oldNumActiveParticipants {
-		return newNumActiveParticipants > oldNumActiveParticipants
+		return newNumActiveParticipants > oldNumActiveParticipants, nil
+	}
+
+	newUpdateAttestedHeaderBeacon, err := newUpdate.AttestedHeader.GetBeacon()
+	if err != nil {
+		return false, errors.Wrap(err, "could not get attested header beacon")
+	}
+	oldUpdateAttestedHeaderBeacon, err := oldUpdate.AttestedHeader.GetBeacon()
+	if err != nil {
+		return false, errors.Wrap(err, "could not get attested header beacon")
 	}
 
 	// Compare presence of relevant sync committee
-	newHasRelevantSyncCommittee := IsSyncCommitteeUpdate(newUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.AttestedHeader.Beacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot)))
-	oldHasRelevantSyncCommittee := IsSyncCommitteeUpdate(oldUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.AttestedHeader.Beacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot)))
+	newHasRelevantSyncCommittee := IsSyncCommitteeUpdate(newUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.SignatureSlot)))
+	oldHasRelevantSyncCommittee := IsSyncCommitteeUpdate(oldUpdate) && (slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.SignatureSlot)))
 
 	if newHasRelevantSyncCommittee != oldHasRelevantSyncCommittee {
-		return newHasRelevantSyncCommittee
+		return newHasRelevantSyncCommittee, nil
 	}
 
 	// Compare indication of any finality
 	newHasFinality := IsFinalityUpdate(newUpdate)
 	oldHasFinality := IsFinalityUpdate(oldUpdate)
 	if newHasFinality != oldHasFinality {
-		return newHasFinality
+		return newHasFinality, nil
+	}
+
+	newUpdateFinalizedHeaderBeacon, err := newUpdate.FinalizedHeader.GetBeacon()
+	if err != nil {
+		return false, errors.Wrap(err, "could not get finalized header beacon")
+	}
+	oldUpdateFinalizedHeaderBeacon, err := oldUpdate.FinalizedHeader.GetBeacon()
+	if err != nil {
+		return false, errors.Wrap(err, "could not get finalized header beacon")
 	}
 
 	// Compare sync committee finality
 	if newHasFinality {
-		newHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.FinalizedHeader.Beacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdate.AttestedHeader.Beacon.Slot))
-		oldHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.FinalizedHeader.Beacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdate.AttestedHeader.Beacon.Slot))
+		newHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateFinalizedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(newUpdateAttestedHeaderBeacon.Slot))
+		oldHasSyncCommitteeFinality := slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateFinalizedHeaderBeacon.Slot)) == slots.SyncCommitteePeriod(slots.ToEpoch(oldUpdateAttestedHeaderBeacon.Slot))
 
 		if newHasSyncCommitteeFinality != oldHasSyncCommitteeFinality {
-			return newHasSyncCommitteeFinality
+			return newHasSyncCommitteeFinality, nil
 		}
 	}
 
 	// Tiebreaker 1: Sync committee participation beyond supermajority
 	if newNumActiveParticipants != oldNumActiveParticipants {
-		return newNumActiveParticipants > oldNumActiveParticipants
+		return newNumActiveParticipants > oldNumActiveParticipants, nil
 	}
 
 	// Tiebreaker 2: Prefer older data (fewer changes to best)
-	if newUpdate.AttestedHeader.Beacon.Slot != oldUpdate.AttestedHeader.Beacon.Slot {
-		return newUpdate.AttestedHeader.Beacon.Slot < oldUpdate.AttestedHeader.Beacon.Slot
+	if newUpdateAttestedHeaderBeacon.Slot != oldUpdateAttestedHeaderBeacon.Slot {
+		return newUpdateAttestedHeaderBeacon.Slot < oldUpdateAttestedHeaderBeacon.Slot, nil
 	}
-	return newUpdate.SignatureSlot < oldUpdate.SignatureSlot
+	return newUpdate.SignatureSlot < oldUpdate.SignatureSlot, nil
 }
diff --git a/beacon-chain/rpc/eth/light-client/helpers_test.go b/beacon-chain/rpc/eth/light-client/helpers_test.go
index f693f9b88be3..726527ef8be4 100644
--- a/beacon-chain/rpc/eth/light-client/helpers_test.go
+++ b/beacon-chain/rpc/eth/light-client/helpers_test.go
@@ -94,9 +94,13 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: make([][]byte, fieldparams.NextSyncCommitteeBranchDepth),
 				SignatureSlot:           9999,
 			},
@@ -104,9 +108,13 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000001,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000001,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           1000000,
 			},
@@ -118,9 +126,13 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000001,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000001,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           1000000,
 			},
@@ -128,9 +140,13 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: make([][]byte, fieldparams.NextSyncCommitteeBranchDepth),
 				SignatureSlot:           9999,
 			},
@@ -142,9 +158,13 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          make([][]byte, lightclient.FinalityBranchNumOfLeaves),
@@ -153,9 +173,13 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
@@ -168,9 +192,13 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
@@ -179,9 +207,13 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          make([][]byte, lightclient.FinalityBranchNumOfLeaves),
@@ -194,29 +226,45 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			newUpdate: &ethpbv2.LightClientUpdate{
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           999999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 999999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 999999,
+						}},
+					},
+				},
 			},
 			expectedResult: true,
 		},
@@ -226,29 +274,45 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           999999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 999999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 999999,
+						}},
+					},
+				},
 			},
 			newUpdate: &ethpbv2.LightClientUpdate{
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			expectedResult: false,
 		},
@@ -258,29 +322,45 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			newUpdate: &ethpbv2.LightClientUpdate{
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			expectedResult: true,
 		},
@@ -290,29 +370,45 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b01111100, 0b1}, // [0,1,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			newUpdate: &ethpbv2.LightClientUpdate{
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			expectedResult: false,
 		},
@@ -322,29 +418,45 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			newUpdate: &ethpbv2.LightClientUpdate{
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 999999,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 999999,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			expectedResult: true,
 		},
@@ -354,29 +466,45 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 999999,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 999999,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			newUpdate: &ethpbv2.LightClientUpdate{
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			expectedResult: false,
 		},
@@ -386,29 +514,45 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			newUpdate: &ethpbv2.LightClientUpdate{
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9998,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			expectedResult: true,
 		},
@@ -418,29 +562,45 @@ func TestIsBetterUpdate(t *testing.T) {
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9998,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			newUpdate: &ethpbv2.LightClientUpdate{
 				SyncAggregate: &ethpbv1.SyncAggregate{
 					SyncCommitteeBits: []byte{0b00111100, 0b1}, // [0,0,1,1,1,1,0,0]
 				},
-				AttestedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 1000000,
-				}},
+				AttestedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 1000000,
+						}},
+					},
+				},
 				NextSyncCommitteeBranch: createNonEmptySyncCommitteeBranch(),
 				SignatureSlot:           9999,
 				FinalityBranch:          createNonEmptyFinalityBranch(),
-				FinalizedHeader: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
-					Slot: 9999,
-				}},
+				FinalizedHeader: &ethpbv2.LightClientHeaderContainer{
+					Header: &ethpbv2.LightClientHeaderContainer_HeaderAltair{
+						HeaderAltair: &ethpbv2.LightClientHeader{Beacon: &ethpbv1.BeaconBlockHeader{
+							Slot: 9999,
+						}},
+					},
+				},
 			},
 			expectedResult: false,
 		},
@@ -448,7 +608,9 @@ func TestIsBetterUpdate(t *testing.T) {
 
 	for _, testCase := range testCases {
 		t.Run(testCase.name, func(t *testing.T) {
-			assert.Equal(t, testCase.expectedResult, IsBetterUpdate(testCase.newUpdate, testCase.oldUpdate))
+			result, err := IsBetterUpdate(testCase.newUpdate, testCase.oldUpdate)
+			assert.NoError(t, err)
+			assert.Equal(t, testCase.expectedResult, result)
 		})
 	}
 }
diff --git a/consensus-types/blocks/proofs.go b/consensus-types/blocks/proofs.go
index 34e0f394a055..5b9c756a2b74 100644
--- a/consensus-types/blocks/proofs.go
+++ b/consensus-types/blocks/proofs.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil"
 	"github.com/prysmaticlabs/prysm/v5/config/params"
+	"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
 	"github.com/prysmaticlabs/prysm/v5/container/trie"
 	"github.com/prysmaticlabs/prysm/v5/crypto/hash/htr"
 	"github.com/prysmaticlabs/prysm/v5/encoding/ssz"
@@ -181,7 +182,7 @@ func ComputeBlockBodyFieldRoots(ctx context.Context, blockBody *BeaconBlockBody)
 	return fieldRoots, nil
 }
 
-func ComputeBlockFieldRoots(ctx context.Context, block *BeaconBlock) ([][]byte, error) {
+func ComputeBlockFieldRoots(ctx context.Context, block interfaces.ReadOnlyBeaconBlock) ([][]byte, error) {
 	_, span := trace.StartSpan(ctx, "blocks.ComputeBlockFieldRoots")
 	defer span.End()
 
@@ -195,21 +196,23 @@ func ComputeBlockFieldRoots(ctx context.Context, block *BeaconBlock) ([][]byte,
 	}
 
 	// Slot
-	slotRoot := ssz.Uint64Root(uint64(block.slot))
+	slotRoot := ssz.Uint64Root(uint64(block.Slot()))
 	copy(fieldRoots[0], slotRoot[:])
 
 	// Proposer Index
-	proposerRoot := ssz.Uint64Root(uint64(block.proposerIndex))
+	proposerRoot := ssz.Uint64Root(uint64(block.ProposerIndex()))
 	copy(fieldRoots[1], proposerRoot[:])
 
 	// Parent Root
-	copy(fieldRoots[2], block.parentRoot[:])
+	parentRoot := block.ParentRoot()
+	copy(fieldRoots[2], parentRoot[:])
 
 	// State Root
-	copy(fieldRoots[3], block.stateRoot[:])
+	stateRoot := block.StateRoot()
+	copy(fieldRoots[3], stateRoot[:])
 
 	// block body Root
-	blockBodyRoot, err := block.body.HashTreeRoot()
+	blockBodyRoot, err := block.Body().HashTreeRoot()
 	if err != nil {
 		return nil, err
 	}
@@ -218,7 +221,7 @@ func ComputeBlockFieldRoots(ctx context.Context, block *BeaconBlock) ([][]byte,
 	return fieldRoots, nil
 }
 
-func PayloadProof(ctx context.Context, block *BeaconBlock) ([][]byte, error) {
+func PayloadProof(ctx context.Context, block interfaces.ReadOnlyBeaconBlock) ([][]byte, error) {
 	i := block.Body()
 	blockBody, ok := i.(*BeaconBlockBody)
 	if !ok {
diff --git a/proto/eth/v2/BUILD.bazel b/proto/eth/v2/BUILD.bazel
index 1e8dab8675d2..37b7368c46b8 100644
--- a/proto/eth/v2/BUILD.bazel
+++ b/proto/eth/v2/BUILD.bazel
@@ -77,6 +77,7 @@ go_library(
     name = "go_default_library",
     srcs = [
         ":ssz_generated_files",
+        "custom.go",
     ],
     embed = [":go_proto"],
     importpath = "github.com/prysmaticlabs/prysm/v5/proto/eth/v2",
diff --git a/proto/eth/v2/beacon_lightclient.pb.go b/proto/eth/v2/beacon_lightclient.pb.go
index c5020da60529..e9f2f3704e5c 100755
--- a/proto/eth/v2/beacon_lightclient.pb.go
+++ b/proto/eth/v2/beacon_lightclient.pb.go
@@ -11,6 +11,7 @@ import (
 	sync "sync"
 
 	github_com_prysmaticlabs_prysm_v5_consensus_types_primitives "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
+	v11 "github.com/prysmaticlabs/prysm/v5/proto/engine/v1"
 	_ "github.com/prysmaticlabs/prysm/v5/proto/eth/ext"
 	v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@@ -71,20 +72,241 @@ func (x *LightClientHeader) GetBeacon() *v1.BeaconBlockHeader {
 	return nil
 }
 
+type LightClientHeaderCapella struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Beacon          *v1.BeaconBlockHeader              `protobuf:"bytes,1,opt,name=beacon,proto3" json:"beacon,omitempty"`
+	Execution       *v11.ExecutionPayloadHeaderCapella `protobuf:"bytes,2,opt,name=execution,proto3" json:"execution,omitempty"`
+	ExecutionBranch [][]byte                           `protobuf:"bytes,3,rep,name=execution_branch,json=executionBranch,proto3" json:"execution_branch,omitempty"`
+}
+
+func (x *LightClientHeaderCapella) Reset() {
+	*x = LightClientHeaderCapella{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LightClientHeaderCapella) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LightClientHeaderCapella) ProtoMessage() {}
+
+func (x *LightClientHeaderCapella) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LightClientHeaderCapella.ProtoReflect.Descriptor instead.
+func (*LightClientHeaderCapella) Descriptor() ([]byte, []int) {
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *LightClientHeaderCapella) GetBeacon() *v1.BeaconBlockHeader {
+	if x != nil {
+		return x.Beacon
+	}
+	return nil
+}
+
+func (x *LightClientHeaderCapella) GetExecution() *v11.ExecutionPayloadHeaderCapella {
+	if x != nil {
+		return x.Execution
+	}
+	return nil
+}
+
+func (x *LightClientHeaderCapella) GetExecutionBranch() [][]byte {
+	if x != nil {
+		return x.ExecutionBranch
+	}
+	return nil
+}
+
+type LightClientHeaderDeneb struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Beacon          *v1.BeaconBlockHeader            `protobuf:"bytes,1,opt,name=beacon,proto3" json:"beacon,omitempty"`
+	Execution       *v11.ExecutionPayloadHeaderDeneb `protobuf:"bytes,2,opt,name=execution,proto3" json:"execution,omitempty"`
+	ExecutionBranch [][]byte                         `protobuf:"bytes,3,rep,name=execution_branch,json=executionBranch,proto3" json:"execution_branch,omitempty"`
+}
+
+func (x *LightClientHeaderDeneb) Reset() {
+	*x = LightClientHeaderDeneb{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LightClientHeaderDeneb) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LightClientHeaderDeneb) ProtoMessage() {}
+
+func (x *LightClientHeaderDeneb) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LightClientHeaderDeneb.ProtoReflect.Descriptor instead.
+func (*LightClientHeaderDeneb) Descriptor() ([]byte, []int) {
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *LightClientHeaderDeneb) GetBeacon() *v1.BeaconBlockHeader {
+	if x != nil {
+		return x.Beacon
+	}
+	return nil
+}
+
+func (x *LightClientHeaderDeneb) GetExecution() *v11.ExecutionPayloadHeaderDeneb {
+	if x != nil {
+		return x.Execution
+	}
+	return nil
+}
+
+func (x *LightClientHeaderDeneb) GetExecutionBranch() [][]byte {
+	if x != nil {
+		return x.ExecutionBranch
+	}
+	return nil
+}
+
+type LightClientHeaderContainer struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Types that are assignable to Header:
+	//
+	//	*LightClientHeaderContainer_HeaderAltair
+	//	*LightClientHeaderContainer_HeaderCapella
+	//	*LightClientHeaderContainer_HeaderDeneb
+	Header isLightClientHeaderContainer_Header `protobuf_oneof:"header"`
+}
+
+func (x *LightClientHeaderContainer) Reset() {
+	*x = LightClientHeaderContainer{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LightClientHeaderContainer) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LightClientHeaderContainer) ProtoMessage() {}
+
+func (x *LightClientHeaderContainer) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LightClientHeaderContainer.ProtoReflect.Descriptor instead.
+func (*LightClientHeaderContainer) Descriptor() ([]byte, []int) {
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{3}
+}
+
+func (m *LightClientHeaderContainer) GetHeader() isLightClientHeaderContainer_Header {
+	if m != nil {
+		return m.Header
+	}
+	return nil
+}
+
+func (x *LightClientHeaderContainer) GetHeaderAltair() *LightClientHeader {
+	if x, ok := x.GetHeader().(*LightClientHeaderContainer_HeaderAltair); ok {
+		return x.HeaderAltair
+	}
+	return nil
+}
+
+func (x *LightClientHeaderContainer) GetHeaderCapella() *LightClientHeaderCapella {
+	if x, ok := x.GetHeader().(*LightClientHeaderContainer_HeaderCapella); ok {
+		return x.HeaderCapella
+	}
+	return nil
+}
+
+func (x *LightClientHeaderContainer) GetHeaderDeneb() *LightClientHeaderDeneb {
+	if x, ok := x.GetHeader().(*LightClientHeaderContainer_HeaderDeneb); ok {
+		return x.HeaderDeneb
+	}
+	return nil
+}
+
+type isLightClientHeaderContainer_Header interface {
+	isLightClientHeaderContainer_Header()
+}
+
+type LightClientHeaderContainer_HeaderAltair struct {
+	HeaderAltair *LightClientHeader `protobuf:"bytes,1,opt,name=header_altair,json=headerAltair,proto3,oneof"`
+}
+
+type LightClientHeaderContainer_HeaderCapella struct {
+	HeaderCapella *LightClientHeaderCapella `protobuf:"bytes,2,opt,name=header_capella,json=headerCapella,proto3,oneof"`
+}
+
+type LightClientHeaderContainer_HeaderDeneb struct {
+	HeaderDeneb *LightClientHeaderDeneb `protobuf:"bytes,3,opt,name=header_deneb,json=headerDeneb,proto3,oneof"`
+}
+
+func (*LightClientHeaderContainer_HeaderAltair) isLightClientHeaderContainer_Header() {}
+
+func (*LightClientHeaderContainer_HeaderCapella) isLightClientHeaderContainer_Header() {}
+
+func (*LightClientHeaderContainer_HeaderDeneb) isLightClientHeaderContainer_Header() {}
+
 type LightClientBootstrap struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Header                     *LightClientHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
-	CurrentSyncCommittee       *SyncCommittee     `protobuf:"bytes,2,opt,name=current_sync_committee,json=currentSyncCommittee,proto3" json:"current_sync_committee,omitempty"`
-	CurrentSyncCommitteeBranch [][]byte           `protobuf:"bytes,3,rep,name=current_sync_committee_branch,json=currentSyncCommitteeBranch,proto3" json:"current_sync_committee_branch,omitempty"`
+	Header                     *LightClientHeaderContainer `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
+	CurrentSyncCommittee       *SyncCommittee              `protobuf:"bytes,2,opt,name=current_sync_committee,json=currentSyncCommittee,proto3" json:"current_sync_committee,omitempty"`
+	CurrentSyncCommitteeBranch [][]byte                    `protobuf:"bytes,3,rep,name=current_sync_committee_branch,json=currentSyncCommitteeBranch,proto3" json:"current_sync_committee_branch,omitempty"`
 }
 
 func (x *LightClientBootstrap) Reset() {
 	*x = LightClientBootstrap{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[1]
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[4]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -97,7 +319,7 @@ func (x *LightClientBootstrap) String() string {
 func (*LightClientBootstrap) ProtoMessage() {}
 
 func (x *LightClientBootstrap) ProtoReflect() protoreflect.Message {
-	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[1]
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[4]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -110,10 +332,10 @@ func (x *LightClientBootstrap) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use LightClientBootstrap.ProtoReflect.Descriptor instead.
 func (*LightClientBootstrap) Descriptor() ([]byte, []int) {
-	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{1}
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{4}
 }
 
-func (x *LightClientBootstrap) GetHeader() *LightClientHeader {
+func (x *LightClientBootstrap) GetHeader() *LightClientHeaderContainer {
 	if x != nil {
 		return x.Header
 	}
@@ -139,10 +361,10 @@ type LightClientUpdate struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	AttestedHeader          *LightClientHeader                                                `protobuf:"bytes,1,opt,name=attested_header,json=attestedHeader,proto3" json:"attested_header,omitempty"`
+	AttestedHeader          *LightClientHeaderContainer                                       `protobuf:"bytes,1,opt,name=attested_header,json=attestedHeader,proto3" json:"attested_header,omitempty"`
 	NextSyncCommittee       *SyncCommittee                                                    `protobuf:"bytes,2,opt,name=next_sync_committee,json=nextSyncCommittee,proto3" json:"next_sync_committee,omitempty"`
 	NextSyncCommitteeBranch [][]byte                                                          `protobuf:"bytes,3,rep,name=next_sync_committee_branch,json=nextSyncCommitteeBranch,proto3" json:"next_sync_committee_branch,omitempty"`
-	FinalizedHeader         *LightClientHeader                                                `protobuf:"bytes,4,opt,name=finalized_header,json=finalizedHeader,proto3" json:"finalized_header,omitempty"`
+	FinalizedHeader         *LightClientHeaderContainer                                       `protobuf:"bytes,4,opt,name=finalized_header,json=finalizedHeader,proto3" json:"finalized_header,omitempty"`
 	FinalityBranch          [][]byte                                                          `protobuf:"bytes,5,rep,name=finality_branch,json=finalityBranch,proto3" json:"finality_branch,omitempty"`
 	SyncAggregate           *v1.SyncAggregate                                                 `protobuf:"bytes,6,opt,name=sync_aggregate,json=syncAggregate,proto3" json:"sync_aggregate,omitempty"`
 	SignatureSlot           github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Slot `protobuf:"varint,7,opt,name=signature_slot,json=signatureSlot,proto3" json:"signature_slot,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Slot"`
@@ -151,7 +373,7 @@ type LightClientUpdate struct {
 func (x *LightClientUpdate) Reset() {
 	*x = LightClientUpdate{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[2]
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[5]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -164,7 +386,7 @@ func (x *LightClientUpdate) String() string {
 func (*LightClientUpdate) ProtoMessage() {}
 
 func (x *LightClientUpdate) ProtoReflect() protoreflect.Message {
-	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[2]
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[5]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -177,10 +399,10 @@ func (x *LightClientUpdate) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use LightClientUpdate.ProtoReflect.Descriptor instead.
 func (*LightClientUpdate) Descriptor() ([]byte, []int) {
-	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{2}
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{5}
 }
 
-func (x *LightClientUpdate) GetAttestedHeader() *LightClientHeader {
+func (x *LightClientUpdate) GetAttestedHeader() *LightClientHeaderContainer {
 	if x != nil {
 		return x.AttestedHeader
 	}
@@ -201,7 +423,7 @@ func (x *LightClientUpdate) GetNextSyncCommitteeBranch() [][]byte {
 	return nil
 }
 
-func (x *LightClientUpdate) GetFinalizedHeader() *LightClientHeader {
+func (x *LightClientUpdate) GetFinalizedHeader() *LightClientHeaderContainer {
 	if x != nil {
 		return x.FinalizedHeader
 	}
@@ -241,7 +463,7 @@ type LightClientFinalityUpdateWithVersion struct {
 func (x *LightClientFinalityUpdateWithVersion) Reset() {
 	*x = LightClientFinalityUpdateWithVersion{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[3]
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -254,7 +476,7 @@ func (x *LightClientFinalityUpdateWithVersion) String() string {
 func (*LightClientFinalityUpdateWithVersion) ProtoMessage() {}
 
 func (x *LightClientFinalityUpdateWithVersion) ProtoReflect() protoreflect.Message {
-	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[3]
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -267,7 +489,7 @@ func (x *LightClientFinalityUpdateWithVersion) ProtoReflect() protoreflect.Messa
 
 // Deprecated: Use LightClientFinalityUpdateWithVersion.ProtoReflect.Descriptor instead.
 func (*LightClientFinalityUpdateWithVersion) Descriptor() ([]byte, []int) {
-	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{3}
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *LightClientFinalityUpdateWithVersion) GetVersion() Version {
@@ -289,8 +511,8 @@ type LightClientFinalityUpdate struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	AttestedHeader  *LightClientHeader                                                `protobuf:"bytes,1,opt,name=attested_header,json=attestedHeader,proto3" json:"attested_header,omitempty"`
-	FinalizedHeader *LightClientHeader                                                `protobuf:"bytes,2,opt,name=finalized_header,json=finalizedHeader,proto3" json:"finalized_header,omitempty"`
+	AttestedHeader  *LightClientHeaderContainer                                       `protobuf:"bytes,1,opt,name=attested_header,json=attestedHeader,proto3" json:"attested_header,omitempty"`
+	FinalizedHeader *LightClientHeaderContainer                                       `protobuf:"bytes,2,opt,name=finalized_header,json=finalizedHeader,proto3" json:"finalized_header,omitempty"`
 	FinalityBranch  [][]byte                                                          `protobuf:"bytes,3,rep,name=finality_branch,json=finalityBranch,proto3" json:"finality_branch,omitempty"`
 	SyncAggregate   *v1.SyncAggregate                                                 `protobuf:"bytes,4,opt,name=sync_aggregate,json=syncAggregate,proto3" json:"sync_aggregate,omitempty"`
 	SignatureSlot   github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Slot `protobuf:"varint,5,opt,name=signature_slot,json=signatureSlot,proto3" json:"signature_slot,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Slot"`
@@ -299,7 +521,7 @@ type LightClientFinalityUpdate struct {
 func (x *LightClientFinalityUpdate) Reset() {
 	*x = LightClientFinalityUpdate{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[4]
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[7]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -312,7 +534,7 @@ func (x *LightClientFinalityUpdate) String() string {
 func (*LightClientFinalityUpdate) ProtoMessage() {}
 
 func (x *LightClientFinalityUpdate) ProtoReflect() protoreflect.Message {
-	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[4]
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[7]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -325,17 +547,17 @@ func (x *LightClientFinalityUpdate) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use LightClientFinalityUpdate.ProtoReflect.Descriptor instead.
 func (*LightClientFinalityUpdate) Descriptor() ([]byte, []int) {
-	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{4}
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{7}
 }
 
-func (x *LightClientFinalityUpdate) GetAttestedHeader() *LightClientHeader {
+func (x *LightClientFinalityUpdate) GetAttestedHeader() *LightClientHeaderContainer {
 	if x != nil {
 		return x.AttestedHeader
 	}
 	return nil
 }
 
-func (x *LightClientFinalityUpdate) GetFinalizedHeader() *LightClientHeader {
+func (x *LightClientFinalityUpdate) GetFinalizedHeader() *LightClientHeaderContainer {
 	if x != nil {
 		return x.FinalizedHeader
 	}
@@ -375,7 +597,7 @@ type LightClientOptimisticUpdateWithVersion struct {
 func (x *LightClientOptimisticUpdateWithVersion) Reset() {
 	*x = LightClientOptimisticUpdateWithVersion{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[5]
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[8]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -388,7 +610,7 @@ func (x *LightClientOptimisticUpdateWithVersion) String() string {
 func (*LightClientOptimisticUpdateWithVersion) ProtoMessage() {}
 
 func (x *LightClientOptimisticUpdateWithVersion) ProtoReflect() protoreflect.Message {
-	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[5]
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[8]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -401,7 +623,7 @@ func (x *LightClientOptimisticUpdateWithVersion) ProtoReflect() protoreflect.Mes
 
 // Deprecated: Use LightClientOptimisticUpdateWithVersion.ProtoReflect.Descriptor instead.
 func (*LightClientOptimisticUpdateWithVersion) Descriptor() ([]byte, []int) {
-	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{5}
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{8}
 }
 
 func (x *LightClientOptimisticUpdateWithVersion) GetVersion() Version {
@@ -423,7 +645,7 @@ type LightClientOptimisticUpdate struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	AttestedHeader *LightClientHeader                                                `protobuf:"bytes,1,opt,name=attested_header,json=attestedHeader,proto3" json:"attested_header,omitempty"`
+	AttestedHeader *LightClientHeaderContainer                                       `protobuf:"bytes,1,opt,name=attested_header,json=attestedHeader,proto3" json:"attested_header,omitempty"`
 	SyncAggregate  *v1.SyncAggregate                                                 `protobuf:"bytes,2,opt,name=sync_aggregate,json=syncAggregate,proto3" json:"sync_aggregate,omitempty"`
 	SignatureSlot  github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.Slot `protobuf:"varint,3,opt,name=signature_slot,json=signatureSlot,proto3" json:"signature_slot,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Slot"`
 }
@@ -431,7 +653,7 @@ type LightClientOptimisticUpdate struct {
 func (x *LightClientOptimisticUpdate) Reset() {
 	*x = LightClientOptimisticUpdate{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[6]
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[9]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -444,7 +666,7 @@ func (x *LightClientOptimisticUpdate) String() string {
 func (*LightClientOptimisticUpdate) ProtoMessage() {}
 
 func (x *LightClientOptimisticUpdate) ProtoReflect() protoreflect.Message {
-	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[6]
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[9]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -457,10 +679,10 @@ func (x *LightClientOptimisticUpdate) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use LightClientOptimisticUpdate.ProtoReflect.Descriptor instead.
 func (*LightClientOptimisticUpdate) Descriptor() ([]byte, []int) {
-	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{6}
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{9}
 }
 
-func (x *LightClientOptimisticUpdate) GetAttestedHeader() *LightClientHeader {
+func (x *LightClientOptimisticUpdate) GetAttestedHeader() *LightClientHeaderContainer {
 	if x != nil {
 		return x.AttestedHeader
 	}
@@ -493,7 +715,7 @@ type LightClientUpdateWithVersion struct {
 func (x *LightClientUpdateWithVersion) Reset() {
 	*x = LightClientUpdateWithVersion{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[7]
+		mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[10]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -506,7 +728,7 @@ func (x *LightClientUpdateWithVersion) String() string {
 func (*LightClientUpdateWithVersion) ProtoMessage() {}
 
 func (x *LightClientUpdateWithVersion) ProtoReflect() protoreflect.Message {
-	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[7]
+	mi := &file_proto_eth_v2_beacon_lightclient_proto_msgTypes[10]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -519,7 +741,7 @@ func (x *LightClientUpdateWithVersion) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use LightClientUpdateWithVersion.ProtoReflect.Descriptor instead.
 func (*LightClientUpdateWithVersion) Descriptor() ([]byte, []int) {
-	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{7}
+	return file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP(), []int{10}
 }
 
 func (x *LightClientUpdateWithVersion) GetVersion() Version {
@@ -550,142 +772,191 @@ var file_proto_eth_v2_beacon_lightclient_proto_rawDesc = []byte{
 	0x68, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
 	0x74, 0x6f, 0x1a, 0x21, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32,
 	0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4f, 0x0a, 0x11, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c,
-	0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x06, 0x62, 0x65,
-	0x61, 0x63, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68,
-	0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65, 0x61,
-	0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06,
-	0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x22, 0xeb, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x67, 0x68, 0x74,
-	0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12,
-	0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76,
-	0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61,
-	0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x16, 0x63,
-	0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
-	0x69, 0x74, 0x74, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74,
-	0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x79,
-	0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x52, 0x14, 0x63, 0x75, 0x72,
-	0x72, 0x65, 0x6e, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65,
-	0x65, 0x12, 0x41, 0x0a, 0x1d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x79, 0x6e,
-	0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x62, 0x72, 0x61, 0x6e,
-	0x63, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x1a, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
-	0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x42, 0x72,
-	0x61, 0x6e, 0x63, 0x68, 0x22, 0x9a, 0x04, 0x0a, 0x11, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c,
-	0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x61, 0x74,
-	0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
-	0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e,
-	0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65,
-	0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x4e, 0x0a, 0x13, 0x6e, 0x65, 0x78, 0x74, 0x5f,
-	0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
-	0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69,
-	0x74, 0x74, 0x65, 0x65, 0x52, 0x11, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f,
-	0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x12, 0x3b, 0x0a, 0x1a, 0x6e, 0x65, 0x78, 0x74, 0x5f,
-	0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x62,
-	0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x17, 0x6e, 0x65, 0x78,
-	0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x42, 0x72,
-	0x61, 0x6e, 0x63, 0x68, 0x12, 0x4d, 0x0a, 0x10, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65,
-	0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
-	0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32,
-	0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64,
-	0x65, 0x72, 0x52, 0x0f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x48, 0x65, 0x61,
-	0x64, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f,
-	0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69,
-	0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x45, 0x0a, 0x0e,
-	0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x06,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
-	0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65,
-	0x67, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
-	0x61, 0x74, 0x65, 0x12, 0x6c, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
-	0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18,
-	0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73,
-	0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f,
-	0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70,
-	0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c,
-	0x6f, 0x74, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x6c, 0x6f,
-	0x74, 0x22, 0x9a, 0x01, 0x0a, 0x24, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e,
-	0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57,
-	0x69, 0x74, 0x68, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x76, 0x65,
-	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x74,
-	0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x65,
-	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e,
-	0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x65,
-	0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c,
-	0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69,
-	0x74, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x95,
-	0x03, 0x0a, 0x19, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, 0x69,
-	0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x4b, 0x0a, 0x0f,
-	0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
-	0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69,
-	0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0e, 0x61, 0x74, 0x74, 0x65, 0x73,
-	0x74, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x10, 0x66, 0x69, 0x6e,
-	0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x26, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x6e, 0x67,
+	0x69, 0x6e, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+	0x5f, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4f, 0x0a,
+	0x11, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64,
+	0x65, 0x72, 0x12, 0x3a, 0x0a, 0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
+	0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
+	0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x22, 0xd2,
+	0x01, 0x0a, 0x18, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65,
+	0x61, 0x64, 0x65, 0x72, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x12, 0x3a, 0x0a, 0x06, 0x62,
+	0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74,
+	0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x65,
+	0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52,
+	0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x4f, 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x75,
+	0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x65, 0x74, 0x68,
+	0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e,
+	0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
+	0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61, 0x52, 0x09, 0x65,
+	0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x65, 0x63,
+	0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03,
+	0x28, 0x0c, 0x52, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72, 0x61,
+	0x6e, 0x63, 0x68, 0x22, 0xce, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69,
+	0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x12, 0x3a,
+	0x0a, 0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22,
+	0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31,
+	0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64,
+	0x65, 0x72, 0x52, 0x06, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x09, 0x65, 0x78,
+	0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e,
+	0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e,
+	0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c,
+	0x6f, 0x61, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x52, 0x09,
+	0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x65,
+	0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20,
+	0x03, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x72,
+	0x61, 0x6e, 0x63, 0x68, 0x22, 0x93, 0x02, 0x0a, 0x1a, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c,
+	0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
+	0x6e, 0x65, 0x72, 0x12, 0x49, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x6c,
+	0x74, 0x61, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68,
+	0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67,
+	0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x48, 0x00,
+	0x52, 0x0c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x12, 0x52,
+	0x0a, 0x0e, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x70, 0x65, 0x6c, 0x6c, 0x61,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
+	0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c,
+	0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x61, 0x70, 0x65, 0x6c, 0x6c,
+	0x61, 0x48, 0x00, 0x52, 0x0d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x61, 0x70, 0x65, 0x6c,
+	0x6c, 0x61, 0x12, 0x4c, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x6e,
+	0x65, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
+	0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74,
+	0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x65, 0x6e, 0x65,
+	0x62, 0x48, 0x00, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x65, 0x6e, 0x65, 0x62,
+	0x42, 0x08, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0xf4, 0x01, 0x0a, 0x14, 0x4c,
+	0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74,
+	0x72, 0x61, 0x70, 0x12, 0x43, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
 	0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e,
-	0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x0f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a,
-	0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6e, 0x61,
-	0x6c, 0x69, 0x74, 0x79, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28,
-	0x0c, 0x52, 0x0e, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63,
-	0x68, 0x12, 0x45, 0x0a, 0x0e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67,
-	0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65,
-	0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63,
-	0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x63, 0x41,
-	0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x6c, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e,
-	0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04,
-	0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
-	0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70,
-	0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75,
-	0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76,
-	0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
-	0x72, 0x65, 0x53, 0x6c, 0x6f, 0x74, 0x22, 0x9e, 0x01, 0x0a, 0x26, 0x4c, 0x69, 0x67, 0x68, 0x74,
-	0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x73, 0x74, 0x69, 0x63,
-	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
-	0x6e, 0x12, 0x32, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74,
-	0x68, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65,
-	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
-	0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e,
-	0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x73, 0x74, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x9f, 0x02, 0x0a, 0x1b, 0x4c, 0x69, 0x67, 0x68,
-	0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x73, 0x74, 0x69,
-	0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x4b, 0x0a, 0x0f, 0x61, 0x74, 0x74, 0x65, 0x73,
+	0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
+	0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x54, 0x0a, 0x16, 0x63, 0x75, 0x72, 0x72,
+	0x65, 0x6e, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74,
+	0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
+	0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43,
+	0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x52, 0x14, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
+	0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x12, 0x41,
+	0x0a, 0x1d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63,
+	0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18,
+	0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x1a, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x79,
+	0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63,
+	0x68, 0x22, 0xac, 0x04, 0x0a, 0x11, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e,
+	0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x61, 0x74, 0x74, 0x65, 0x73,
 	0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
+	0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
 	0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65,
-	0x61, 0x64, 0x65, 0x72, 0x52, 0x0e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65,
-	0x61, 0x64, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x0e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67,
-	0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65,
-	0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53,
-	0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x73, 0x79,
-	0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x6c, 0x0a, 0x0e, 0x73,
-	0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x03, 0x20,
-	0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
-	0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62,
-	0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65,
-	0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69,
-	0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e,
-	0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x6c, 0x6f, 0x74, 0x22, 0x8a, 0x01, 0x0a, 0x1c, 0x4c, 0x69,
-	0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57,
-	0x69, 0x74, 0x68, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x76, 0x65,
-	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x74,
-	0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x65,
-	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36,
-	0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65,
-	0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c,
-	0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
-	0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x83, 0x01, 0x0a, 0x13, 0x6f, 0x72, 0x67, 0x2e, 0x65,
-	0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x42, 0x12,
-	0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x50, 0x72, 0x6f,
-	0x74, 0x6f, 0x50, 0x01, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
-	0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70,
-	0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74,
-	0x68, 0x2f, 0x76, 0x32, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72,
-	0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0f, 0x45, 0x74, 0x68,
-	0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x32, 0x62, 0x06, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x33,
+	0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0e, 0x61,
+	0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x4e, 0x0a,
+	0x13, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
+	0x74, 0x74, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68,
+	0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x79, 0x6e,
+	0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x52, 0x11, 0x6e, 0x65, 0x78, 0x74,
+	0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x12, 0x3b, 0x0a,
+	0x1a, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69,
+	0x74, 0x74, 0x65, 0x65, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03, 0x28,
+	0x0c, 0x52, 0x17, 0x6e, 0x65, 0x78, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69,
+	0x74, 0x74, 0x65, 0x65, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x56, 0x0a, 0x10, 0x66, 0x69,
+	0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
+	0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
+	0x72, 0x52, 0x0f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64,
+	0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x62,
+	0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69, 0x6e,
+	0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x45, 0x0a, 0x0e, 0x73,
+	0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
+	0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67,
+	0x61, 0x74, 0x65, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61,
+	0x74, 0x65, 0x12, 0x6c, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f,
+	0x73, 0x6c, 0x6f, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41,
+	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
+	0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76,
+	0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65,
+	0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f,
+	0x74, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53, 0x6c, 0x6f, 0x74,
+	0x22, 0x9a, 0x01, 0x0a, 0x24, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74,
+	0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x69,
+	0x74, 0x68, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x76, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x74, 0x68,
+	0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a,
+	0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x65, 0x74,
+	0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69,
+	0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74,
+	0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa7, 0x03,
+	0x0a, 0x19, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6e,
+	0x61, 0x6c, 0x69, 0x74, 0x79, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x61,
+	0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
+	0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
+	0x72, 0x52, 0x0e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65,
+	0x72, 0x12, 0x56, 0x0a, 0x10, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x68,
+	0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74,
+	0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69,
+	0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43,
+	0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69,
+	0x7a, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6e,
+	0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x03, 0x20, 0x03,
+	0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6e,
+	0x63, 0x68, 0x12, 0x45, 0x0a, 0x0e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65,
+	0x67, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68,
+	0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e,
+	0x63, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x63,
+	0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x6c, 0x0a, 0x0e, 0x73, 0x69, 0x67,
+	0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
+	0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+	0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f,
+	0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73,
+	0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69,
+	0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
+	0x75, 0x72, 0x65, 0x53, 0x6c, 0x6f, 0x74, 0x22, 0x9e, 0x01, 0x0a, 0x26, 0x4c, 0x69, 0x67, 0x68,
+	0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x73, 0x74, 0x69,
+	0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x56, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65,
+	0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x76,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
+	0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65,
+	0x6e, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x73, 0x74, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xa8, 0x02, 0x0a, 0x1b, 0x4c, 0x69, 0x67,
+	0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x73, 0x74,
+	0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x61, 0x74, 0x74, 0x65,
+	0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68,
+	0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48,
+	0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0e,
+	0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x45,
+	0x0a, 0x0e, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
+	0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67,
+	0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x63, 0x41, 0x67, 0x67, 0x72,
+	0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x6c, 0x0a, 0x0e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
+	0x72, 0x65, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82,
+	0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72,
+	0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73,
+	0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74,
+	0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e,
+	0x53, 0x6c, 0x6f, 0x74, 0x52, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x53,
+	0x6c, 0x6f, 0x74, 0x22, 0x8a, 0x01, 0x0a, 0x1c, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c, 0x69,
+	0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x57, 0x69, 0x74, 0x68, 0x56, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
+	0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52,
+	0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
+	0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x67, 0x68, 0x74, 0x43, 0x6c,
+	0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61,
+	0x42, 0x83, 0x01, 0x0a, 0x13, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
+	0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x42, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f,
+	0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x32,
+	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
+	0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76,
+	0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x3b, 0x65,
+	0x74, 0x68, 0xaa, 0x02, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74,
+	0x68, 0x2e, 0x56, 0x32, 0xca, 0x02, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c,
+	0x45, 0x74, 0x68, 0x5c, 0x76, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -700,45 +971,57 @@ func file_proto_eth_v2_beacon_lightclient_proto_rawDescGZIP() []byte {
 	return file_proto_eth_v2_beacon_lightclient_proto_rawDescData
 }
 
-var file_proto_eth_v2_beacon_lightclient_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
+var file_proto_eth_v2_beacon_lightclient_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
 var file_proto_eth_v2_beacon_lightclient_proto_goTypes = []interface{}{
 	(*LightClientHeader)(nil),                      // 0: ethereum.eth.v2.LightClientHeader
-	(*LightClientBootstrap)(nil),                   // 1: ethereum.eth.v2.LightClientBootstrap
-	(*LightClientUpdate)(nil),                      // 2: ethereum.eth.v2.LightClientUpdate
-	(*LightClientFinalityUpdateWithVersion)(nil),   // 3: ethereum.eth.v2.LightClientFinalityUpdateWithVersion
-	(*LightClientFinalityUpdate)(nil),              // 4: ethereum.eth.v2.LightClientFinalityUpdate
-	(*LightClientOptimisticUpdateWithVersion)(nil), // 5: ethereum.eth.v2.LightClientOptimisticUpdateWithVersion
-	(*LightClientOptimisticUpdate)(nil),            // 6: ethereum.eth.v2.LightClientOptimisticUpdate
-	(*LightClientUpdateWithVersion)(nil),           // 7: ethereum.eth.v2.LightClientUpdateWithVersion
-	(*v1.BeaconBlockHeader)(nil),                   // 8: ethereum.eth.v1.BeaconBlockHeader
-	(*SyncCommittee)(nil),                          // 9: ethereum.eth.v2.SyncCommittee
-	(*v1.SyncAggregate)(nil),                       // 10: ethereum.eth.v1.SyncAggregate
-	(Version)(0),                                   // 11: ethereum.eth.v2.Version
+	(*LightClientHeaderCapella)(nil),               // 1: ethereum.eth.v2.LightClientHeaderCapella
+	(*LightClientHeaderDeneb)(nil),                 // 2: ethereum.eth.v2.LightClientHeaderDeneb
+	(*LightClientHeaderContainer)(nil),             // 3: ethereum.eth.v2.LightClientHeaderContainer
+	(*LightClientBootstrap)(nil),                   // 4: ethereum.eth.v2.LightClientBootstrap
+	(*LightClientUpdate)(nil),                      // 5: ethereum.eth.v2.LightClientUpdate
+	(*LightClientFinalityUpdateWithVersion)(nil),   // 6: ethereum.eth.v2.LightClientFinalityUpdateWithVersion
+	(*LightClientFinalityUpdate)(nil),              // 7: ethereum.eth.v2.LightClientFinalityUpdate
+	(*LightClientOptimisticUpdateWithVersion)(nil), // 8: ethereum.eth.v2.LightClientOptimisticUpdateWithVersion
+	(*LightClientOptimisticUpdate)(nil),            // 9: ethereum.eth.v2.LightClientOptimisticUpdate
+	(*LightClientUpdateWithVersion)(nil),           // 10: ethereum.eth.v2.LightClientUpdateWithVersion
+	(*v1.BeaconBlockHeader)(nil),                   // 11: ethereum.eth.v1.BeaconBlockHeader
+	(*v11.ExecutionPayloadHeaderCapella)(nil),      // 12: ethereum.engine.v1.ExecutionPayloadHeaderCapella
+	(*v11.ExecutionPayloadHeaderDeneb)(nil),        // 13: ethereum.engine.v1.ExecutionPayloadHeaderDeneb
+	(*SyncCommittee)(nil),                          // 14: ethereum.eth.v2.SyncCommittee
+	(*v1.SyncAggregate)(nil),                       // 15: ethereum.eth.v1.SyncAggregate
+	(Version)(0),                                   // 16: ethereum.eth.v2.Version
 }
 var file_proto_eth_v2_beacon_lightclient_proto_depIdxs = []int32{
-	8,  // 0: ethereum.eth.v2.LightClientHeader.beacon:type_name -> ethereum.eth.v1.BeaconBlockHeader
-	0,  // 1: ethereum.eth.v2.LightClientBootstrap.header:type_name -> ethereum.eth.v2.LightClientHeader
-	9,  // 2: ethereum.eth.v2.LightClientBootstrap.current_sync_committee:type_name -> ethereum.eth.v2.SyncCommittee
-	0,  // 3: ethereum.eth.v2.LightClientUpdate.attested_header:type_name -> ethereum.eth.v2.LightClientHeader
-	9,  // 4: ethereum.eth.v2.LightClientUpdate.next_sync_committee:type_name -> ethereum.eth.v2.SyncCommittee
-	0,  // 5: ethereum.eth.v2.LightClientUpdate.finalized_header:type_name -> ethereum.eth.v2.LightClientHeader
-	10, // 6: ethereum.eth.v2.LightClientUpdate.sync_aggregate:type_name -> ethereum.eth.v1.SyncAggregate
-	11, // 7: ethereum.eth.v2.LightClientFinalityUpdateWithVersion.version:type_name -> ethereum.eth.v2.Version
-	4,  // 8: ethereum.eth.v2.LightClientFinalityUpdateWithVersion.data:type_name -> ethereum.eth.v2.LightClientFinalityUpdate
-	0,  // 9: ethereum.eth.v2.LightClientFinalityUpdate.attested_header:type_name -> ethereum.eth.v2.LightClientHeader
-	0,  // 10: ethereum.eth.v2.LightClientFinalityUpdate.finalized_header:type_name -> ethereum.eth.v2.LightClientHeader
-	10, // 11: ethereum.eth.v2.LightClientFinalityUpdate.sync_aggregate:type_name -> ethereum.eth.v1.SyncAggregate
-	11, // 12: ethereum.eth.v2.LightClientOptimisticUpdateWithVersion.version:type_name -> ethereum.eth.v2.Version
-	6,  // 13: ethereum.eth.v2.LightClientOptimisticUpdateWithVersion.data:type_name -> ethereum.eth.v2.LightClientOptimisticUpdate
-	0,  // 14: ethereum.eth.v2.LightClientOptimisticUpdate.attested_header:type_name -> ethereum.eth.v2.LightClientHeader
-	10, // 15: ethereum.eth.v2.LightClientOptimisticUpdate.sync_aggregate:type_name -> ethereum.eth.v1.SyncAggregate
-	11, // 16: ethereum.eth.v2.LightClientUpdateWithVersion.version:type_name -> ethereum.eth.v2.Version
-	2,  // 17: ethereum.eth.v2.LightClientUpdateWithVersion.data:type_name -> ethereum.eth.v2.LightClientUpdate
-	18, // [18:18] is the sub-list for method output_type
-	18, // [18:18] is the sub-list for method input_type
-	18, // [18:18] is the sub-list for extension type_name
-	18, // [18:18] is the sub-list for extension extendee
-	0,  // [0:18] is the sub-list for field type_name
+	11, // 0: ethereum.eth.v2.LightClientHeader.beacon:type_name -> ethereum.eth.v1.BeaconBlockHeader
+	11, // 1: ethereum.eth.v2.LightClientHeaderCapella.beacon:type_name -> ethereum.eth.v1.BeaconBlockHeader
+	12, // 2: ethereum.eth.v2.LightClientHeaderCapella.execution:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderCapella
+	11, // 3: ethereum.eth.v2.LightClientHeaderDeneb.beacon:type_name -> ethereum.eth.v1.BeaconBlockHeader
+	13, // 4: ethereum.eth.v2.LightClientHeaderDeneb.execution:type_name -> ethereum.engine.v1.ExecutionPayloadHeaderDeneb
+	0,  // 5: ethereum.eth.v2.LightClientHeaderContainer.header_altair:type_name -> ethereum.eth.v2.LightClientHeader
+	1,  // 6: ethereum.eth.v2.LightClientHeaderContainer.header_capella:type_name -> ethereum.eth.v2.LightClientHeaderCapella
+	2,  // 7: ethereum.eth.v2.LightClientHeaderContainer.header_deneb:type_name -> ethereum.eth.v2.LightClientHeaderDeneb
+	3,  // 8: ethereum.eth.v2.LightClientBootstrap.header:type_name -> ethereum.eth.v2.LightClientHeaderContainer
+	14, // 9: ethereum.eth.v2.LightClientBootstrap.current_sync_committee:type_name -> ethereum.eth.v2.SyncCommittee
+	3,  // 10: ethereum.eth.v2.LightClientUpdate.attested_header:type_name -> ethereum.eth.v2.LightClientHeaderContainer
+	14, // 11: ethereum.eth.v2.LightClientUpdate.next_sync_committee:type_name -> ethereum.eth.v2.SyncCommittee
+	3,  // 12: ethereum.eth.v2.LightClientUpdate.finalized_header:type_name -> ethereum.eth.v2.LightClientHeaderContainer
+	15, // 13: ethereum.eth.v2.LightClientUpdate.sync_aggregate:type_name -> ethereum.eth.v1.SyncAggregate
+	16, // 14: ethereum.eth.v2.LightClientFinalityUpdateWithVersion.version:type_name -> ethereum.eth.v2.Version
+	7,  // 15: ethereum.eth.v2.LightClientFinalityUpdateWithVersion.data:type_name -> ethereum.eth.v2.LightClientFinalityUpdate
+	3,  // 16: ethereum.eth.v2.LightClientFinalityUpdate.attested_header:type_name -> ethereum.eth.v2.LightClientHeaderContainer
+	3,  // 17: ethereum.eth.v2.LightClientFinalityUpdate.finalized_header:type_name -> ethereum.eth.v2.LightClientHeaderContainer
+	15, // 18: ethereum.eth.v2.LightClientFinalityUpdate.sync_aggregate:type_name -> ethereum.eth.v1.SyncAggregate
+	16, // 19: ethereum.eth.v2.LightClientOptimisticUpdateWithVersion.version:type_name -> ethereum.eth.v2.Version
+	9,  // 20: ethereum.eth.v2.LightClientOptimisticUpdateWithVersion.data:type_name -> ethereum.eth.v2.LightClientOptimisticUpdate
+	3,  // 21: ethereum.eth.v2.LightClientOptimisticUpdate.attested_header:type_name -> ethereum.eth.v2.LightClientHeaderContainer
+	15, // 22: ethereum.eth.v2.LightClientOptimisticUpdate.sync_aggregate:type_name -> ethereum.eth.v1.SyncAggregate
+	16, // 23: ethereum.eth.v2.LightClientUpdateWithVersion.version:type_name -> ethereum.eth.v2.Version
+	5,  // 24: ethereum.eth.v2.LightClientUpdateWithVersion.data:type_name -> ethereum.eth.v2.LightClientUpdate
+	25, // [25:25] is the sub-list for method output_type
+	25, // [25:25] is the sub-list for method input_type
+	25, // [25:25] is the sub-list for extension type_name
+	25, // [25:25] is the sub-list for extension extendee
+	0,  // [0:25] is the sub-list for field type_name
 }
 
 func init() { file_proto_eth_v2_beacon_lightclient_proto_init() }
@@ -762,7 +1045,7 @@ func file_proto_eth_v2_beacon_lightclient_proto_init() {
 			}
 		}
 		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*LightClientBootstrap); i {
+			switch v := v.(*LightClientHeaderCapella); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -774,7 +1057,7 @@ func file_proto_eth_v2_beacon_lightclient_proto_init() {
 			}
 		}
 		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*LightClientUpdate); i {
+			switch v := v.(*LightClientHeaderDeneb); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -786,7 +1069,7 @@ func file_proto_eth_v2_beacon_lightclient_proto_init() {
 			}
 		}
 		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*LightClientFinalityUpdateWithVersion); i {
+			switch v := v.(*LightClientHeaderContainer); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -798,7 +1081,7 @@ func file_proto_eth_v2_beacon_lightclient_proto_init() {
 			}
 		}
 		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*LightClientFinalityUpdate); i {
+			switch v := v.(*LightClientBootstrap); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -810,7 +1093,7 @@ func file_proto_eth_v2_beacon_lightclient_proto_init() {
 			}
 		}
 		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*LightClientOptimisticUpdateWithVersion); i {
+			switch v := v.(*LightClientUpdate); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -822,7 +1105,7 @@ func file_proto_eth_v2_beacon_lightclient_proto_init() {
 			}
 		}
 		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*LightClientOptimisticUpdate); i {
+			switch v := v.(*LightClientFinalityUpdateWithVersion); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -834,6 +1117,42 @@ func file_proto_eth_v2_beacon_lightclient_proto_init() {
 			}
 		}
 		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*LightClientFinalityUpdate); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*LightClientOptimisticUpdateWithVersion); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*LightClientOptimisticUpdate); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_proto_eth_v2_beacon_lightclient_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*LightClientUpdateWithVersion); i {
 			case 0:
 				return &v.state
@@ -846,13 +1165,18 @@ func file_proto_eth_v2_beacon_lightclient_proto_init() {
 			}
 		}
 	}
+	file_proto_eth_v2_beacon_lightclient_proto_msgTypes[3].OneofWrappers = []interface{}{
+		(*LightClientHeaderContainer_HeaderAltair)(nil),
+		(*LightClientHeaderContainer_HeaderCapella)(nil),
+		(*LightClientHeaderContainer_HeaderDeneb)(nil),
+	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
 		File: protoimpl.DescBuilder{
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_proto_eth_v2_beacon_lightclient_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   8,
+			NumMessages:   11,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/proto/eth/v2/beacon_lightclient.proto b/proto/eth/v2/beacon_lightclient.proto
index 6a3933daf99a..e52fe819dcca 100644
--- a/proto/eth/v2/beacon_lightclient.proto
+++ b/proto/eth/v2/beacon_lightclient.proto
@@ -19,6 +19,7 @@ import "proto/eth/ext/options.proto";
 import "proto/eth/v1/beacon_block.proto";
 import "proto/eth/v2/version.proto";
 import "proto/eth/v2/sync_committee.proto";
+import "proto/engine/v1/execution_engine.proto";
 
 option csharp_namespace = "Ethereum.Eth.V2";
 option go_package = "github.com/prysmaticlabs/prysm/v5/proto/eth/v2;eth";
@@ -33,17 +34,38 @@ message LightClientHeader {
   v1.BeaconBlockHeader beacon = 1;
 }
 
+message LightClientHeaderCapella {
+  v1.BeaconBlockHeader beacon = 1;
+  ethereum.engine.v1.ExecutionPayloadHeaderCapella execution = 2;
+  repeated bytes execution_branch = 3;
+}
+
+message LightClientHeaderDeneb {
+  v1.BeaconBlockHeader beacon = 1;
+  ethereum.engine.v1.ExecutionPayloadHeaderDeneb execution = 2;
+  repeated bytes execution_branch = 3;
+}
+
+message LightClientHeaderContainer {
+  oneof header {
+    LightClientHeader header_altair = 1;
+    LightClientHeaderCapella header_capella = 2;
+    LightClientHeaderDeneb header_deneb = 3;
+  }
+}
+
+
 message LightClientBootstrap {
-  LightClientHeader header = 1;
+  LightClientHeaderContainer header = 1;
   SyncCommittee current_sync_committee = 2;
   repeated bytes current_sync_committee_branch = 3;
 }
 
 message LightClientUpdate {
-  LightClientHeader attested_header = 1;
+  LightClientHeaderContainer attested_header = 1;
   SyncCommittee next_sync_committee = 2;
   repeated bytes next_sync_committee_branch = 3;
-  LightClientHeader finalized_header = 4;
+  LightClientHeaderContainer finalized_header = 4;
   repeated bytes finality_branch = 5;
   v1.SyncAggregate sync_aggregate = 6;
   uint64 signature_slot = 7 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Slot"];
@@ -55,8 +77,8 @@ message LightClientFinalityUpdateWithVersion {
 }
 
 message LightClientFinalityUpdate {
-  LightClientHeader attested_header = 1;
-  LightClientHeader finalized_header = 2;
+  LightClientHeaderContainer attested_header = 1;
+  LightClientHeaderContainer finalized_header = 2;
   repeated bytes finality_branch = 3;
   v1.SyncAggregate sync_aggregate = 4;
   uint64 signature_slot = 5 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Slot"];
@@ -68,7 +90,7 @@ message LightClientOptimisticUpdateWithVersion {
 }
 
 message LightClientOptimisticUpdate {
-  LightClientHeader attested_header = 1;
+  LightClientHeaderContainer attested_header = 1;
   v1.SyncAggregate sync_aggregate = 2;
   uint64 signature_slot = 3 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.Slot"];
 }
diff --git a/proto/eth/v2/custom.go b/proto/eth/v2/custom.go
index 9e7d97493fbc..9a9633db2df3 100644
--- a/proto/eth/v2/custom.go
+++ b/proto/eth/v2/custom.go
@@ -2,7 +2,10 @@ package eth
 
 import (
 	"bytes"
+	"fmt"
 	"math/bits"
+
+	v1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
 )
 
 const (
@@ -42,10 +45,23 @@ func isEmptyWithLength(bb [][]byte, length uint64) bool {
 	return true
 }
 
-func (x *LightClientUpdate) IsSyncCommiteeUpdate() bool {
+func (x *LightClientUpdate) IsSyncCommitteeUpdate() bool {
 	return !isEmptyWithLength(x.GetNextSyncCommitteeBranch(), NextSyncCommitteeIndex)
 }
 
 func (x *LightClientUpdate) IsFinalityUpdate() bool {
 	return !isEmptyWithLength(x.GetFinalityBranch(), FinalizedRootIndex)
 }
+
+func (x *LightClientHeaderContainer) GetBeacon() (*v1.BeaconBlockHeader, error) {
+	switch input := x.Header.(type) {
+	case *LightClientHeaderContainer_HeaderAltair:
+		return input.HeaderAltair.Beacon, nil
+	case *LightClientHeaderContainer_HeaderCapella:
+		return input.HeaderCapella.Beacon, nil
+	case *LightClientHeaderContainer_HeaderDeneb:
+		return input.HeaderDeneb.Beacon, nil
+	default:
+		return nil, fmt.Errorf("unknown header type: %T", input)
+	}
+}
diff --git a/testing/util/lightclient.go b/testing/util/lightclient.go
index 37cd8f26ffd1..dbdbaec9fb34 100644
--- a/testing/util/lightclient.go
+++ b/testing/util/lightclient.go
@@ -21,16 +21,17 @@ type TestLightClient struct {
 	Block          interfaces.ReadOnlySignedBeaconBlock
 	AttestedState  state.BeaconState
 	AttestedHeader *ethpb.BeaconBlockHeader
+	FinalizedBlock interfaces.ReadOnlySignedBeaconBlock
 }
 
 func NewTestLightClient(t *testing.T) *TestLightClient {
 	return &TestLightClient{T: t}
 }
 
-func (l *TestLightClient) SetupTest() *TestLightClient {
+func (l *TestLightClient) SetupTestCapella() *TestLightClient {
 	ctx := context.Background()
 
-	slot := primitives.Slot(params.BeaconConfig().AltairForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
+	slot := primitives.Slot(params.BeaconConfig().CapellaForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
 
 	attestedState, err := NewBeaconStateCapella()
 	require.NoError(l.T, err)
@@ -98,15 +99,159 @@ func (l *TestLightClient) SetupTest() *TestLightClient {
 	return l
 }
 
+func (l *TestLightClient) SetupTestAltair() *TestLightClient {
+	ctx := context.Background()
+
+	slot := primitives.Slot(params.BeaconConfig().AltairForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
+
+	attestedState, err := NewBeaconStateAltair()
+	require.NoError(l.T, err)
+	err = attestedState.SetSlot(slot)
+	require.NoError(l.T, err)
+
+	parent := NewBeaconBlockAltair()
+	parent.Block.Slot = slot
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(l.T, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(l.T, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(l.T, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(l.T, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(l.T, err)
+
+	state, err := NewBeaconStateAltair()
+	require.NoError(l.T, err)
+	err = state.SetSlot(slot)
+	require.NoError(l.T, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(l.T, err)
+
+	block := NewBeaconBlockAltair()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < params.BeaconConfig().MinSyncCommitteeParticipants; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(l.T, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(l.T, err)
+
+	err = state.SetLatestBlockHeader(h.Header)
+	require.NoError(l.T, err)
+	stateRoot, err := state.HashTreeRoot(ctx)
+	require.NoError(l.T, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(l.T, err)
+
+	l.State = state
+	l.AttestedState = attestedState
+	l.AttestedHeader = attestedHeader
+	l.Block = signedBlock
+	l.Ctx = ctx
+
+	return l
+}
+
+func (l *TestLightClient) SetupTestDeneb() *TestLightClient {
+	ctx := context.Background()
+
+	slot := primitives.Slot(params.BeaconConfig().DenebForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1)
+
+	attestedState, err := NewBeaconStateDeneb()
+	require.NoError(l.T, err)
+	err = attestedState.SetSlot(slot)
+	require.NoError(l.T, err)
+
+	parent := NewBeaconBlockDeneb()
+	parent.Block.Slot = slot
+
+	signedParent, err := blocks.NewSignedBeaconBlock(parent)
+	require.NoError(l.T, err)
+
+	parentHeader, err := signedParent.Header()
+	require.NoError(l.T, err)
+	attestedHeader := parentHeader.Header
+
+	err = attestedState.SetLatestBlockHeader(attestedHeader)
+	require.NoError(l.T, err)
+	attestedStateRoot, err := attestedState.HashTreeRoot(ctx)
+	require.NoError(l.T, err)
+
+	// get a new signed block so the root is updated with the new state root
+	parent.Block.StateRoot = attestedStateRoot[:]
+	signedParent, err = blocks.NewSignedBeaconBlock(parent)
+	require.NoError(l.T, err)
+
+	state, err := NewBeaconStateDeneb()
+	require.NoError(l.T, err)
+	err = state.SetSlot(slot)
+	require.NoError(l.T, err)
+
+	parentRoot, err := signedParent.Block().HashTreeRoot()
+	require.NoError(l.T, err)
+
+	block := NewBeaconBlockDeneb()
+	block.Block.Slot = slot
+	block.Block.ParentRoot = parentRoot[:]
+
+	for i := uint64(0); i < params.BeaconConfig().MinSyncCommitteeParticipants; i++ {
+		block.Block.Body.SyncAggregate.SyncCommitteeBits.SetBitAt(i, true)
+	}
+
+	signedBlock, err := blocks.NewSignedBeaconBlock(block)
+	require.NoError(l.T, err)
+
+	h, err := signedBlock.Header()
+	require.NoError(l.T, err)
+
+	err = state.SetLatestBlockHeader(h.Header)
+	require.NoError(l.T, err)
+	stateRoot, err := state.HashTreeRoot(ctx)
+	require.NoError(l.T, err)
+
+	// get a new signed block so the root is updated with the new state root
+	block.Block.StateRoot = stateRoot[:]
+	signedBlock, err = blocks.NewSignedBeaconBlock(block)
+	require.NoError(l.T, err)
+
+	l.State = state
+	l.AttestedState = attestedState
+	l.AttestedHeader = attestedHeader
+	l.Block = signedBlock
+	l.Ctx = ctx
+
+	return l
+}
+
 func (l *TestLightClient) CheckAttestedHeader(update *ethpbv2.LightClientUpdate) {
-	require.Equal(l.T, l.AttestedHeader.Slot, update.AttestedHeader.Beacon.Slot, "Attested header slot is not equal")
-	require.Equal(l.T, l.AttestedHeader.ProposerIndex, update.AttestedHeader.Beacon.ProposerIndex, "Attested header proposer index is not equal")
-	require.DeepSSZEqual(l.T, l.AttestedHeader.ParentRoot, update.AttestedHeader.Beacon.ParentRoot, "Attested header parent root is not equal")
-	require.DeepSSZEqual(l.T, l.AttestedHeader.BodyRoot, update.AttestedHeader.Beacon.BodyRoot, "Attested header body root is not equal")
+	updateAttestedHeaderBeacon, err := update.AttestedHeader.GetBeacon()
+	require.NoError(l.T, err)
+	require.Equal(l.T, l.AttestedHeader.Slot, updateAttestedHeaderBeacon.Slot, "Attested header slot is not equal")
+	require.Equal(l.T, l.AttestedHeader.ProposerIndex, updateAttestedHeaderBeacon.ProposerIndex, "Attested header proposer index is not equal")
+	require.DeepSSZEqual(l.T, l.AttestedHeader.ParentRoot, updateAttestedHeaderBeacon.ParentRoot, "Attested header parent root is not equal")
+	require.DeepSSZEqual(l.T, l.AttestedHeader.BodyRoot, updateAttestedHeaderBeacon.BodyRoot, "Attested header body root is not equal")
 
 	attestedStateRoot, err := l.AttestedState.HashTreeRoot(l.Ctx)
 	require.NoError(l.T, err)
-	require.DeepSSZEqual(l.T, attestedStateRoot[:], update.AttestedHeader.Beacon.StateRoot, "Attested header state root is not equal")
+	require.DeepSSZEqual(l.T, attestedStateRoot[:], updateAttestedHeaderBeacon.StateRoot, "Attested header state root is not equal")
 }
 
 func (l *TestLightClient) CheckSyncAggregate(update *ethpbv2.LightClientUpdate) {