From 6f6d02e79ee4945463c210812444e2952cb7ff94 Mon Sep 17 00:00:00 2001 From: pk910 Date: Tue, 9 Dec 2025 21:07:10 +0100 Subject: [PATCH] show full bpo schedule from EL config when available --- clients/execution/chainstate.go | 6 +++ handlers/index.go | 73 +++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/clients/execution/chainstate.go b/clients/execution/chainstate.go index 359e622e..1c5ac13e 100644 --- a/clients/execution/chainstate.go +++ b/clients/execution/chainstate.go @@ -223,6 +223,7 @@ func (cache *ChainState) getBlobScheduleForTimestampFromConfig(timestamp time.Ti type BlobScheduleEntry struct { Timestamp time.Time Schedule rpc.EthConfigBlobSchedule + IsBpo bool } func (cache *ChainState) GetFullBlobSchedule() []BlobScheduleEntry { @@ -273,6 +274,7 @@ func (cache *ChainState) GetFullBlobSchedule() []BlobScheduleEntry { Target: uint64(cache.config.Config.BlobScheduleConfig.BPO1.Target), BaseFeeUpdateFraction: uint64(cache.config.Config.BlobScheduleConfig.BPO1.UpdateFraction), }, + IsBpo: true, }) } @@ -284,6 +286,7 @@ func (cache *ChainState) GetFullBlobSchedule() []BlobScheduleEntry { Target: uint64(cache.config.Config.BlobScheduleConfig.BPO2.Target), BaseFeeUpdateFraction: uint64(cache.config.Config.BlobScheduleConfig.BPO2.UpdateFraction), }, + IsBpo: true, }) } @@ -295,6 +298,7 @@ func (cache *ChainState) GetFullBlobSchedule() []BlobScheduleEntry { Target: uint64(cache.config.Config.BlobScheduleConfig.BPO3.Target), BaseFeeUpdateFraction: uint64(cache.config.Config.BlobScheduleConfig.BPO3.UpdateFraction), }, + IsBpo: true, }) } @@ -306,6 +310,7 @@ func (cache *ChainState) GetFullBlobSchedule() []BlobScheduleEntry { Target: uint64(cache.config.Config.BlobScheduleConfig.BPO4.Target), BaseFeeUpdateFraction: uint64(cache.config.Config.BlobScheduleConfig.BPO4.UpdateFraction), }, + IsBpo: true, }) } @@ -317,6 +322,7 @@ func (cache *ChainState) GetFullBlobSchedule() []BlobScheduleEntry { Target: uint64(cache.config.Config.BlobScheduleConfig.BPO5.Target), BaseFeeUpdateFraction: uint64(cache.config.Config.BlobScheduleConfig.BPO5.UpdateFraction), }, + IsBpo: true, }) } diff --git a/handlers/index.go b/handlers/index.go index ab9fee88..7f1e1f36 100644 --- a/handlers/index.go +++ b/handlers/index.go @@ -291,25 +291,62 @@ func buildIndexPageData() (*models.IndexPageData, time.Duration) { } // Add BPO forks from BLOB_SCHEDULE - for i, blobSchedule := range specs.BlobSchedule { - // BPO forks use the fork version that's active at the time of BPO activation - forkVersion := chainState.GetForkVersionAtEpoch(phase0.Epoch(blobSchedule.Epoch)) - blobParams := &consensus.BlobScheduleEntry{ - Epoch: blobSchedule.Epoch, - MaxBlobsPerBlock: blobSchedule.MaxBlobsPerBlock, - } - forkDigest := chainState.GetForkDigest(forkVersion, blobParams) + elBlobSchedule := services.GlobalBeaconService.GetExecutionChainState().GetFullBlobSchedule() + if len(elBlobSchedule) > 0 { + // get blob schedule from el config (we have the full blob schedule available) + bpoIdx := 0 + for _, blobSchedule := range elBlobSchedule { + if !blobSchedule.IsBpo { + continue + } - pageData.NetworkForks = append(pageData.NetworkForks, &models.IndexPageDataForks{ - Name: fmt.Sprintf("BPO%d", i+1), - Epoch: blobSchedule.Epoch, - Version: nil, // BPO forks don't have fork versions - Time: uint64(chainState.EpochToTime(phase0.Epoch(blobSchedule.Epoch)).Unix()), - Active: uint64(currentEpoch) >= blobSchedule.Epoch, - Type: "bpo", - MaxBlobsPerBlock: &blobSchedule.MaxBlobsPerBlock, - ForkDigest: forkDigest[:], - }) + bpoIdx++ + + bpoEpoch := phase0.Epoch(0) + if blobSchedule.Timestamp.After(networkGenesis.GenesisTime) { + bpoEpoch = chainState.EpochOfSlot(chainState.TimeToSlot(blobSchedule.Timestamp)) + } + + forkVersion := chainState.GetForkVersionAtEpoch(bpoEpoch) + blobParams := &consensus.BlobScheduleEntry{ + Epoch: uint64(bpoEpoch), + MaxBlobsPerBlock: blobSchedule.Schedule.Max, + } + forkDigest := chainState.GetForkDigest(forkVersion, blobParams) + + pageData.NetworkForks = append(pageData.NetworkForks, &models.IndexPageDataForks{ + Name: fmt.Sprintf("BPO%d", bpoIdx), + Epoch: uint64(bpoEpoch), + Version: nil, + Time: uint64(blobSchedule.Timestamp.Unix()), + Active: currentEpoch >= bpoEpoch, + Type: "bpo", + MaxBlobsPerBlock: &blobSchedule.Schedule.Max, + ForkDigest: forkDigest[:], + }) + } + } else { + // get blob schedule from cl specs (no el config available, so we only get the deduplicated blob schedule from the cl specs) + for i, blobSchedule := range specs.BlobSchedule { + // BPO forks use the fork version that's active at the time of BPO activation + forkVersion := chainState.GetForkVersionAtEpoch(phase0.Epoch(blobSchedule.Epoch)) + blobParams := &consensus.BlobScheduleEntry{ + Epoch: blobSchedule.Epoch, + MaxBlobsPerBlock: blobSchedule.MaxBlobsPerBlock, + } + forkDigest := chainState.GetForkDigest(forkVersion, blobParams) + + pageData.NetworkForks = append(pageData.NetworkForks, &models.IndexPageDataForks{ + Name: fmt.Sprintf("BPO%d", i+1), + Epoch: blobSchedule.Epoch, + Version: nil, // BPO forks don't have fork versions + Time: uint64(chainState.EpochToTime(phase0.Epoch(blobSchedule.Epoch)).Unix()), + Active: uint64(currentEpoch) >= blobSchedule.Epoch, + Type: "bpo", + MaxBlobsPerBlock: &blobSchedule.MaxBlobsPerBlock, + ForkDigest: forkDigest[:], + }) + } } // Sort all forks by epoch