Skip to content

Commit 42a8588

Browse files
authored
Merge pull request #900 from gobitfly/BEDS-520/fix-blocks-query
(BEDS-520) DA: removed query to mat view
2 parents 09b2451 + 3e1f57c commit 42a8588

File tree

1 file changed

+91
-76
lines changed

1 file changed

+91
-76
lines changed

backend/pkg/api/data_access/vdb_blocks.go

Lines changed: 91 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
115115
Epoch uint64 `db:"epoch"`
116116
Slot uint64 `db:"slot"`
117117
Status uint64 `db:"status"`
118-
Block sql.NullInt64 `db:"block"`
118+
Block sql.NullInt64 `db:"exec_block_number"`
119119
FeeRecipient []byte `db:"fee_recipient"`
120120
ElReward decimal.NullDecimal `db:"el_reward"`
121121
ClReward decimal.NullDecimal `db:"cl_reward"`
@@ -132,7 +132,7 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
132132
if colSort.Desc {
133133
sortOrder = ` DESC`
134134
}
135-
val := t.VDBValidator(0)
135+
var val any
136136
sortColName := `slot`
137137
switch colSort.Column {
138138
case enums.VDBBlockProposer:
@@ -142,8 +142,8 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
142142
sortColName = `status`
143143
val = currentCursor.Status
144144
case enums.VDBBlockProposerReward:
145-
sortColName = `reward`
146-
val = currentCursor.Reward.BigInt().Uint64()
145+
sortColName = `el_reward + cl_reward`
146+
val = currentCursor.Reward
147147
}
148148
onlyPrimarySort := sortColName == `slot`
149149
if currentCursor.IsValid() {
@@ -218,78 +218,28 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
218218
} else {
219219
log.Debugf("duties info not available, skipping scheduled slots: %s", err)
220220
}
221-
if len(scheduledProposers) > 0 {
222-
// make sure the distinct clause filters out the correct duplicated row (e.g. block=nil)
223-
orderBy += `, block`
224-
}
225221
}
226222

227223
groupIdCol := "group_id"
228-
// this is actually just used for sorting for "reward".. will not consider EL rewards of unfinalized blocks atm
229-
reward := "reward"
230224
if dashboardId.Validators != nil {
231225
groupIdCol = fmt.Sprintf("%d AS %s", t.DefaultGroupId, groupIdCol)
232-
reward = "coalesce(rb.value / 1e18, ep.fee_recipient_reward) AS " + reward
233226
}
234227
selectFields := fmt.Sprintf(`
235-
r.proposer,
228+
blocks.proposer,
229+
blocks.epoch,
230+
blocks.slot,
236231
%s,
237-
r.epoch,
238-
r.slot,
239-
r.status,
240-
block,
232+
blocks.status,
233+
exec_block_number,
241234
COALESCE(rb.proposer_fee_recipient, blocks.exec_fee_recipient) AS fee_recipient,
242235
COALESCE(rb.value / 1e18, ep.fee_recipient_reward) AS el_reward,
243236
cp.cl_attestations_reward / 1e9 + cp.cl_sync_aggregate_reward / 1e9 + cp.cl_slashing_inclusion_reward / 1e9 as cl_reward,
244-
r.graffiti_text`, groupIdCol)
245-
query := fmt.Sprintf(`SELECT distinct on (slot)
246-
%s
247-
FROM ( SELECT * FROM (`, selectFields)
248-
// supply scheduled proposals, if any
249-
if len(scheduledProposers) > 0 {
250-
// distinct to filter out duplicates in an edge case (if dutiesInfo didn't update yet after a block was proposed, but the blocks table was)
251-
// might be possible to remove this once the TODO in service_slot_viz.go:startSlotVizDataService is resolved
252-
distinct := "slot"
253-
if !onlyPrimarySort {
254-
distinct = sortColName + ", " + distinct
255-
}
256-
params = append(params, scheduledProposers)
257-
params = append(params, scheduledEpochs)
258-
params = append(params, scheduledSlots)
259-
query = fmt.Sprintf(`SELECT distinct on (%s)
237+
blocks.graffiti_text`, groupIdCol)
238+
cte := fmt.Sprintf(`WITH past_blocks AS (SELECT
260239
%s
261-
FROM ( SELECT * FROM (WITH scheduled_proposals (
262-
proposer,
263-
epoch,
264-
slot,
265-
status,
266-
block,
267-
reward,
268-
graffiti_text
269-
) AS (SELECT
270-
*,
271-
'0',
272-
null::int,
273-
null::int,
274-
''
275-
FROM unnest($%d::int[], $%d::int[], $%d::int[]))
276-
SELECT * FROM scheduled_proposals
277-
UNION
278-
(`, distinct, selectFields, len(params)-2, len(params)-1, len(params))
279-
}
280-
query += fmt.Sprintf(`
281-
SELECT
282-
proposer,
283-
epoch,
284-
blocks.slot,
285-
status,
286-
exec_block_number AS block,
287-
%s,
288-
graffiti_text
289-
FROM blocks
290-
`, reward)
291-
292-
if dashboardId.Validators == nil {
240+
FROM blocks
241+
`, selectFields)
242+
/*if dashboardId.Validators == nil {
293243
query += `
294244
LEFT JOIN cached_proposal_rewards ON cached_proposal_rewards.dashboard_id = $1 AND blocks.slot = cached_proposal_rewards.slot
295245
`
@@ -304,32 +254,97 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
304254
if len(scheduledProposers) > 0 {
305255
query += `)`
306256
}
307-
query += `) as u `
257+
query += `) as u `*/
308258
if dashboardId.Validators == nil {
309-
query += fmt.Sprintf(`
259+
cte += fmt.Sprintf(`
310260
INNER JOIN (%s) validators ON validators.validator_index = proposer
311261
`, filteredValidatorsQuery)
312262
} else {
313-
query += `WHERE proposer = ANY($1) `
263+
if len(where) == 0 {
264+
where += `WHERE `
265+
} else {
266+
where += `AND `
267+
}
268+
where += `proposer = ANY($1) `
314269
}
315270

316271
params = append(params, limit+1)
317272
limitStr := fmt.Sprintf(`
318273
LIMIT $%d
319274
`, len(params))
320-
rewardsStr := `) r
321-
LEFT JOIN consensus_payloads cp on r.slot = cp.slot
322-
LEFT JOIN blocks on r.slot = blocks.slot
275+
// relay bribe deduplication; select most likely (=max) relay bribe value for each block
276+
cte += `
277+
LEFT JOIN consensus_payloads cp on blocks.slot = cp.slot
323278
LEFT JOIN execution_payloads ep ON ep.block_hash = blocks.exec_block_hash
324-
LEFT JOIN relays_blocks rb ON rb.exec_block_hash = blocks.exec_block_hash
279+
LEFT JOIN LATERAL (SELECT exec_block_hash, proposer_fee_recipient, max(value) as value
280+
FROM relays_blocks
281+
WHERE relays_blocks.exec_block_hash = blocks.exec_block_hash
282+
GROUP BY exec_block_hash, proposer_fee_recipient
283+
) rb ON rb.exec_block_hash = blocks.exec_block_hash
284+
)
325285
`
326-
// relay bribe deduplication; select most likely (=max) relay bribe value for each block
327-
relayOrder := ``
328-
if colSort.Column != enums.VDBBlockProposerReward {
329-
relayOrder += `, rb.value ` + secSort
286+
287+
distinct := ""
288+
if !onlyPrimarySort {
289+
distinct = sortColName
290+
}
291+
from := `past_blocks `
292+
selectStr := `SELECT * FROM ` + from
293+
if len(distinct) > 0 {
294+
selectStr = `SELECT DISTINCT ON (` + distinct + `) * FROM ` + from
295+
}
296+
297+
query := selectStr + from + where + orderBy + limitStr
298+
// supply scheduled proposals, if any
299+
if len(scheduledProposers) > 0 {
300+
// distinct to filter out duplicates in an edge case (if dutiesInfo didn't update yet after a block was proposed, but the blocks table was)
301+
// might be possible to remove this once the TODO in service_slot_viz.go:startSlotVizDataService is resolved
302+
params = append(params, scheduledProposers)
303+
params = append(params, scheduledEpochs)
304+
params = append(params, scheduledSlots)
305+
cte += fmt.Sprintf(`,
306+
scheduled_blocks as (
307+
SELECT
308+
prov.proposer,
309+
prov.epoch,
310+
prov.slot,
311+
%s,
312+
'0'::text AS status,
313+
NULL::int AS exec_block_number,
314+
''::bytea AS fee_recipient,
315+
NULL::float AS el_reward,
316+
NULL::float AS cl_reward,
317+
''::text AS graffiti_text
318+
FROM unnest($%d::int[], $%d::int[], $%d::int[]) AS prov(proposer, epoch, slot)
319+
`, groupIdCol, len(params)-2, len(params)-1, len(params))
320+
if dashboardId.Validators == nil {
321+
// add group id
322+
cte += fmt.Sprintf(`INNER JOIN users_val_dashboards_validators validators
323+
ON validators.dashboard_id = $1
324+
AND validators.validator_index = ANY($%d::int[])
325+
`, len(params)-2)
326+
}
327+
cte += `) `
328+
if len(distinct) != 0 {
329+
distinct += ", "
330+
}
331+
// keep all ordering, sorting etc
332+
distinct += "slot"
333+
selectStr = `SELECT DISTINCT ON (` + distinct + `) * FROM `
334+
// encapsulate past blocks query to ensure performance
335+
from = `(
336+
( ` + query + ` )
337+
UNION ALL
338+
SELECT * FROM scheduled_blocks
339+
) as combined
340+
`
341+
// make sure the distinct clause filters out the correct duplicated row (e.g. block=nil)
342+
orderBy += `, exec_block_number NULLS LAST`
343+
query = selectStr + from + where + orderBy + limitStr
330344
}
345+
331346
startTime := time.Now()
332-
err = d.alloyReader.SelectContext(ctx, &proposals, query+where+orderBy+limitStr+rewardsStr+orderBy+relayOrder, params...)
347+
err = d.alloyReader.SelectContext(ctx, &proposals, cte+query, params...)
333348
log.Debugf("=== getting past blocks took %s", time.Since(startTime))
334349
if err != nil {
335350
return nil, nil, err

0 commit comments

Comments
 (0)