From b5bdfaed45231a3d4954fe547bd45ce12683d6cc Mon Sep 17 00:00:00 2001 From: Patrick Pfeiffer Date: Wed, 24 Jan 2024 13:08:17 +0100 Subject: [PATCH] (BIDS-2879) improve db.GetAddressWithdrawalsTotal --- db/db.go | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/db/db.go b/db/db.go index 56a6e0e249..564a7ea9b9 100644 --- a/db/db.go +++ b/db/db.go @@ -2394,16 +2394,45 @@ func GetValidatorsWithdrawalsByEpoch(validator []uint64, startEpoch uint64, endE func GetAddressWithdrawalsTotal(address []byte) (uint64, error) { var total uint64 - err := ReaderDb.Get(&total, ` - /*+ - BitmapScan(w) - NestLoop(b w) - */ - SELECT - COALESCE(sum(w.amount), 0) as total - FROM blocks_withdrawals w - INNER JOIN blocks b ON b.blockroot = w.block_root AND b.status = '1' - WHERE w.address = $1`, address) + tx, err := ReaderDb.Beginx() + if err != nil { + return total, err + } + defer tx.Rollback() + + maxDay := uint64(0) + err = tx.Get(&maxDay, `SELECT COALESCE(MAX(day), 0) FROM validator_stats`) + if err != nil { + return total, err + } + + if len(address) != 20 { + return 0, fmt.Errorf("invalid address length (!=20): %d", len(address)) + } + + withdrawalCredentials := make([]byte, 32) + withdrawalCredentials[0] = 0x01 + copy(withdrawalCredentials[12:], address) + + slotThreshold := (maxDay + 1) * utils.Config.Chain.ClConfig.SlotsPerEpoch * utils.EpochsPerDay() + + err = tx.Get(&total, ` + WITH + stats AS ( + SELECT coalesce(sum(vs.withdrawals_amount_total),0) AS total + FROM vars, validators v + INNER JOIN validator_stats vs ON v.validatorindex = vs.validatorindex + WHERE v.withdrawalcredentials = $1 AND day = $2 + ), + today AS ( + SELECT COALESCE(sum(w.amount), 0) AS total + FROM vars, blocks_withdrawals w + INNER JOIN blocks b ON b.slot > $4 AND b.blockroot = w.block_root AND b.status = '1' + WHERE w.address = $3 + ) + SELECT stats.total + today.total + FROM stats, today`, + withdrawalCredentials, maxDay, address, slotThreshold) if err != nil { if err == sql.ErrNoRows { return 0, nil