Add metrics for getBlobsV2

This commit is contained in:
Minhyuk Kim 2025-04-13 20:50:35 +09:00 committed by SunnysidedJ
parent 4df10987d2
commit 81daff43ac
No known key found for this signature in database
GPG key ID: 4A3483B2B3B72950
5 changed files with 54 additions and 1 deletions

View file

@ -1338,6 +1338,20 @@ func (p *BlobPool) HasBlobs(vhashes []common.Hash) bool {
return true return true
} }
func (p *BlobPool) GetBlobCounts(vhashes []common.Hash) int {
count := 0
for _, vhash := range vhashes {
// Retrieve the datastore item (in a short lock)
p.lock.RLock()
_, exists := p.lookup.storeidOfBlob(vhash)
p.lock.RUnlock()
if exists {
count += 1
}
}
return count
}
// Add inserts a set of blob transactions into the pool if they pass validation (both // Add inserts a set of blob transactions into the pool if they pass validation (both
// consensus validity and pool restrictions). // consensus validity and pool restrictions).
// //

View file

@ -1074,6 +1074,12 @@ func (pool *LegacyPool) HasBlobs(vhashes []common.Hash) bool {
return false return false
} }
// GetBlobCounts returns number of blobs in the subpool that matches the given
// versioned hashes, without performing db read.
func (pool *LegacyPool) GetBlobCounts(vhashes []common.Hash) int {
return 0
}
// Has returns an indicator whether txpool has a transaction cached with the // Has returns an indicator whether txpool has a transaction cached with the
// given hash. // given hash.
func (pool *LegacyPool) Has(hash common.Hash) bool { func (pool *LegacyPool) Has(hash common.Hash) bool {

View file

@ -141,6 +141,10 @@ type SubPool interface {
// are in the sub pool. // are in the sub pool.
HasBlobs(vhashes []common.Hash) bool HasBlobs(vhashes []common.Hash) bool
// GetBlobCounts returns number of blobs in the subpool that matches the given
// versioned hashes, without performing db read.
GetBlobCounts(vhashes []common.Hash) int
// ValidateTxBasics checks whether a transaction is valid according to the consensus // ValidateTxBasics checks whether a transaction is valid according to the consensus
// rules, but does not check state-dependent validation such as sufficient balance. // rules, but does not check state-dependent validation such as sufficient balance.
// This check is meant as a static check which can be performed without holding the // This check is meant as a static check which can be performed without holding the

View file

@ -323,6 +323,17 @@ func (p *TxPool) GetBlobs(vhashes []common.Hash) []*types.BlobTxSidecar {
return nil return nil
} }
// GetBlobCounts returns a number of blobs that are present in the txpool for
// the given versioned hashes.
func (p *TxPool) GetBlobCounts(vhashes []common.Hash) int {
for _, subpool := range p.subpools {
if count := subpool.GetBlobCounts(vhashes); count != 0 {
return count
}
}
return 0
}
// HasBlobs will return true if all the vhashes are available in the same subpool. // HasBlobs will return true if all the vhashes are available in the same subpool.
func (p *TxPool) HasBlobs(vhashes []common.Hash) bool { func (p *TxPool) HasBlobs(vhashes []common.Hash) bool {
for _, subpool := range p.subpools { for _, subpool := range p.subpools {

View file

@ -38,6 +38,7 @@ import (
"github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/internal/version" "github.com/ethereum/go-ethereum/internal/version"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params/forks" "github.com/ethereum/go-ethereum/params/forks"
@ -160,6 +161,12 @@ type ConsensusAPI struct {
newPayloadLock sync.Mutex // Lock for the NewPayload method newPayloadLock sync.Mutex // Lock for the NewPayload method
} }
var (
getBlobsV2RequestedTotal = metrics.NewRegisteredCounter("execution_get_blobs_requested_from_cl_total", nil)
getBlobsV2RequestedHit = metrics.NewRegisteredCounter("execution_get_blobs_requested_from_cl_hit", nil)
getBlobsV2RequestDuration = metrics.NewRegisteredHistogram("execution_get_blobs_request_duration_milliseconds", nil, metrics.NewExpDecaySample(1028, 0.015))
)
// NewConsensusAPI creates a new consensus api for the given backend. // NewConsensusAPI creates a new consensus api for the given backend.
// The underlying blockchain needs to have a valid terminal total difficulty set. // The underlying blockchain needs to have a valid terminal total difficulty set.
func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI { func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI {
@ -582,8 +589,19 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo
return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes))) return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes)))
} }
start := time.Now()
defer func() {
duration := time.Since(start)
getBlobsV2RequestDuration.Update(duration.Milliseconds())
}()
getBlobsV2RequestedTotal.Inc(int64(len(hashes)))
// Optimization: check first if all blobs are available, if not, return empty response // Optimization: check first if all blobs are available, if not, return empty response
if !api.eth.TxPool().HasBlobs(hashes) { blobCounts := api.eth.TxPool().GetBlobCounts(hashes)
getBlobsV2RequestedHit.Inc(int64(blobCounts))
if blobCounts != len(hashes) {
return nil, nil return nil, nil
} }