Skip to content

Commit

Permalink
add(dashboard): calculate total missed el rewards using postgres db
Browse files Browse the repository at this point in the history
  • Loading branch information
sasha-bitfly committed Jan 16, 2025
1 parent 7faa26a commit ac58ef8
Showing 1 changed file with 69 additions and 49 deletions.
118 changes: 69 additions & 49 deletions backend/pkg/api/data_access/vdb_summary.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,56 +521,70 @@ func (d *DataAccessService) GetValidatorDashboardGroupSummary(ctx context.Contex
return nil, err
}

getMissedELRewards := func(validatorId uint32, epochStart, epochEnd uint64) (float64, error) {
getMissedELRewards := func(epochStart, epochEnd uint64) (float64, error) {
// Initialize the result variable
var missedElRewards float64

// Execute the query
err := d.readerDb.GetContext(ctx, &missedElRewards,
`SELECT
COALESCE(SUM(v), 0) AS total_median_rewards
FROM (
SELECT
a.slot,
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY b.value)::numeric(76,0) AS v
FROM (
SELECT
b.slot AS slot
FROM
blocks b
WHERE
b.proposer = $1
AND b.status != '1'
AND b.epoch BETWEEN $2 AND $3
) a
LEFT JOIN
execution_rewards_finalized b
ON
(b.slot BETWEEN a.slot - 16 AND a.slot + 16)
GROUP BY
a.slot
) res;`, validatorId, epochStart, epochEnd)

// Handle query execution error
var totalMissedRewardsEl float64

// SQL query
query := `
WITH targets AS (
SELECT
b.slot AS slot
FROM
blocks b
JOIN
users_val_dashboards_validators uvdv
ON
b.proposer = uvdv.validator_index
WHERE
uvdv.dashboard_id = $1
AND b.status != '1'
AND epoch >= $2
AND epoch <= $3
),
res AS (
SELECT
a.slot,
percentile_cont(0.5) WITHIN GROUP (ORDER BY b.value)::numeric(76,0) AS v
FROM
targets a
LEFT JOIN
execution_rewards_finalized b
ON
b.slot >= a.slot - 16
AND b.slot < a.slot + 16
GROUP BY
a.slot
)
SELECT
COALESCE(SUM(v), 0)
FROM
res;
`

// Execute the query with the provided parameters
err := d.readerDb.GetContext(ctx, &totalMissedRewardsEl, query, dashboardId.Id, epochStart, epochEnd)
if err != nil {
return 0, fmt.Errorf("failed to execute query: %w", err)
}

// Return the computed total median rewards
return missedElRewards, nil
return totalMissedRewardsEl, nil
}

getLastScheduledBlockAndSyncDate := func() (time.Time, time.Time, error) {
getLastScheduledBlockAndSyncDate := func() (time.Time, time.Time, uint64, uint64, error) {
// we need to go to the all time table for last scheduled block/sync committee epoch
clickhouseTotalTable, _, err := d.getTablesForPeriod(enums.AllTime)
if err != nil {
return time.Time{}, time.Time{}, err
return time.Time{}, time.Time{}, 0, 0, err
}

ds := goqu.Dialect("postgres").
Select(
goqu.L("MAX(last_scheduled_block_epoch) as last_scheduled_block_epoch"),
goqu.L("MAX(last_scheduled_sync_epoch) as last_scheduled_sync_epoch")).
goqu.L("MAX(last_scheduled_sync_epoch) as last_scheduled_sync_epoch"),
goqu.L("MIN(epoch_start) as min_epoch_start"),
goqu.L("MAX(epoch_end) as max_epoch_end")).
From(goqu.L(fmt.Sprintf(`%s AS r FINAL`, clickhouseTotalTable)))

if dashboardId.Validators == nil {
Expand All @@ -585,23 +599,29 @@ func (d *DataAccessService) GetValidatorDashboardGroupSummary(ctx context.Contex

query, args, err := ds.Prepared(true).ToSQL()
if err != nil {
return time.Time{}, time.Time{}, err
return time.Time{}, time.Time{}, 0, 0, err
}

var row struct {
LastScheduledBlockEpoch *int64 `db:"last_scheduled_block_epoch"`
LastSyncEpoch *int64 `db:"last_scheduled_sync_epoch"`
LastScheduledBlockEpoch *int64 `db:"last_scheduled_block_epoch"`
LastSyncEpoch *int64 `db:"last_scheduled_sync_epoch"`
MinEpochStart *uint64 `db:"min_epoch_start"`
MaxEpochEnd *uint64 `db:"max_epoch_end"`
}
err = d.clickhouseReader.GetContext(ctx, &row, query, args...)
if err != nil {
return time.Time{}, time.Time{}, err
return time.Time{}, time.Time{}, 0, 0, err
}

if row.LastScheduledBlockEpoch == nil || row.LastSyncEpoch == nil {
return time.Time{}, time.Time{}, nil
return time.Time{}, time.Time{}, 0, 0, nil
}

return utils.EpochToTime(uint64(*row.LastScheduledBlockEpoch)), utils.EpochToTime(uint64(*row.LastSyncEpoch)), nil
return utils.EpochToTime(uint64(*row.LastScheduledBlockEpoch)),
utils.EpochToTime(uint64(*row.LastSyncEpoch)),
*row.MinEpochStart,
*row.MaxEpochEnd,
nil
}

ds := goqu.Dialect("postgres").
Expand Down Expand Up @@ -691,10 +711,11 @@ func (d *DataAccessService) GetValidatorDashboardGroupSummary(ctx context.Contex
return nil
})

var minEpochStart, maxEpochEnd uint64
var lastBlockTs, lastSyncTs time.Time
errGroup.Go(func() error {
var err error
lastBlockTs, lastSyncTs, err = getLastScheduledBlockAndSyncDate()
lastBlockTs, lastSyncTs, minEpochStart, maxEpochEnd, err = getLastScheduledBlockAndSyncDate()
return err
})

Expand All @@ -720,7 +741,6 @@ func (d *DataAccessService) GetValidatorDashboardGroupSummary(ctx context.Contex
totalBlocksScheduled := uint32(0)
totalBlocksProposed := uint32(0)

totalMissedRewardsEl := float64(0)
totalMissedRewardsCl := int64(0)
totalMissedRewardsAttestations := int64(0)
totalMissedRewardsSync := int64(0)
Expand All @@ -740,12 +760,6 @@ func (d *DataAccessService) GetValidatorDashboardGroupSummary(ctx context.Contex
ret.AttestationsTarget.Success += uint64(row.AttestationsTargetExecuted)
ret.AttestationsTarget.Failed += uint64(row.AttestationsScheduled) - uint64(row.AttestationsTargetExecuted)

missedRewards, err := getMissedELRewards(row.ValidatorIndex, row.EpochStart, row.EpochEnd)
if err != nil {
return nil, err
}

totalMissedRewardsEl += missedRewards
totalMissedRewardsCl += row.BlocksCLMissedReward
totalMissedRewardsAttestations += row.AttestationsIdealReward - row.AttestationsRewardRewardsOnly
totalMissedRewardsSync += row.SyncLocalizedMaxRewards - row.SyncRewardRewardsOnly
Expand Down Expand Up @@ -799,10 +813,16 @@ func (d *DataAccessService) GetValidatorDashboardGroupSummary(ctx context.Contex
totalInclusionDelayDivisor += row.AttestationsObserved
}
}

totalMissedRewardsEl, err := getMissedELRewards(minEpochStart, maxEpochEnd)
if err != nil {
return nil, err
}

ret.MissedRewards.Attestations = utils.GWeiToWei(big.NewInt(totalMissedRewardsAttestations))
ret.MissedRewards.Sync = utils.GWeiToWei(big.NewInt(totalMissedRewardsSync))
ret.MissedRewards.ProposerRewards.Cl = utils.GWeiToWei(big.NewInt(totalMissedRewardsCl))
//ret.MissedRewards.ProposerRewards.El = utils.GWeiToEther(big.NewInt(totalMissedRewardsEl))
ret.MissedRewards.ProposerRewards.El = decimal.NewFromFloat(totalMissedRewardsEl)

ret.Rewards.El, ret.Apr.El, ret.Rewards.Cl, ret.Apr.Cl, err = d.getElClAPR(ctx, dashboardId, groupId, hours)
if err != nil {
Expand Down

0 comments on commit ac58ef8

Please sign in to comment.