Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions tests/reexecute/c/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package vm

import (
"fmt"
"testing"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
)

var (
gasMetric = topLevelMetric{
name: "gas",
query: "avalanche_evm_eth_chain_block_gas_used_processed",
}
meterVMMetrics = []topLevelMetric{
{
name: "block_parse",
query: "avalanche_meterchainvm_C_parse_block_sum",
},
{
name: "block_verify",
query: "avalanche_meterchainvm_C_verify_sum",
},
{
name: "block_accept",
query: "avalanche_meterchainvm_C_accept_sum",
},
}
)

func getCounterMetricValue(registry prometheus.Gatherer, query string) (float64, error) {
metricFamilies, err := registry.Gather()
if err != nil {
return 0, fmt.Errorf("failed to gather metrics: %w", err)
}

for _, mf := range metricFamilies {
if mf.GetName() == query {
return mf.GetMetric()[0].Counter.GetValue(), nil
}
}

return 0, fmt.Errorf("metric %s not found", query)
}

func getGaugeMetricValue(registry prometheus.Gatherer, query string) (float64, error) {
metricFamilies, err := registry.Gather()
if err != nil {
return 0, fmt.Errorf("failed to gather metrics: %w", err)
}

for _, mf := range metricFamilies {
if mf.GetName() == query {
return mf.GetMetric()[0].Gauge.GetValue(), nil
}
}

return 0, fmt.Errorf("metric %s not found", query)
}

type topLevelMetric struct {
name string
query string
}

func getTopLevelMetrics(b *testing.B, registry prometheus.Gatherer, elapsed time.Duration) {
r := require.New(b)

totalGas, err := getCounterMetricValue(registry, gasMetric.query)
r.NoError(err)
r.NotZero(totalGas, "denominator metric %q has value 0", gasMetric.name)

var (
mGas float64 = 1_000_000
gGas float64 = 1_000_000_000
nsPerMs float64 = 1_000_000
)

mGasPerSecond := (totalGas / mGas) / elapsed.Seconds()
b.ReportMetric(mGasPerSecond, "mGas/s")

totalGGas := totalGas / gGas
msPerGGas := (float64(elapsed) / nsPerMs) / totalGGas
b.ReportMetric(msPerGGas, "ms/gGas")

totalMSTrackedPerGGas := float64(0)
for _, metric := range meterVMMetrics {
metricVal, err := getGaugeMetricValue(registry, metric.query)
r.NoError(err)

metricValMS := (metricVal / nsPerMs) / totalGGas
totalMSTrackedPerGGas += metricValMS
b.ReportMetric(metricValMS, metric.name+"_ms/gGas")
}

b.ReportMetric(totalMSTrackedPerGGas, "tracked_ms/gGas")
}
36 changes: 10 additions & 26 deletions tests/reexecute/c/vm_reexecute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/ava-labs/avalanchego/utils/logging"
"github.com/ava-labs/avalanchego/utils/timer"
"github.com/ava-labs/avalanchego/utils/units"
"github.com/ava-labs/avalanchego/vms/metervm"
"github.com/ava-labs/avalanchego/vms/platformvm/warp"
)

Expand Down Expand Up @@ -168,6 +169,9 @@ func benchmarkReexecuteRange(
vmMultiGatherer := metrics.NewPrefixGatherer()
r.NoError(prefixGatherer.Register("avalanche_evm", vmMultiGatherer))

meterVMRegistry := prometheus.NewRegistry()
r.NoError(prefixGatherer.Register("avalanche_meterchainvm_C", meterVMRegistry))

// consensusRegistry includes the chain="C" label and the prefix "avalanche_snowman".
// The consensus registry is passed to the executor to mimic a subset of consensus metrics.
consensusRegistry := prometheus.NewRegistry()
Expand Down Expand Up @@ -211,6 +215,7 @@ func benchmarkReexecuteRange(
chainDataDir,
configBytes,
vmMultiGatherer,
meterVMRegistry,
)
r.NoError(err)
defer func() {
Expand Down Expand Up @@ -241,7 +246,8 @@ func newMainnetCChainVM(
vmAndSharedMemoryDB database.Database,
chainDataDir string,
configBytes []byte,
metricsGatherer metrics.MultiGatherer,
vmMultiGatherer metrics.MultiGatherer,
meterVMRegistry prometheus.Registerer,
) (block.ChainVM, error) {
factory := factory.Factory{}
vmIntf, err := factory.New(logging.NoLog{})
Expand Down Expand Up @@ -269,6 +275,8 @@ func newMainnetCChainVM(
ids.Empty: constants.PrimaryNetworkID,
}

vm = metervm.NewBlockVM(vm, meterVMRegistry)

if err := vm.Initialize(
ctx,
&snow.Context{
Expand All @@ -286,7 +294,7 @@ func newMainnetCChainVM(
Log: tests.NewDefaultLogger("mainnet-vm-reexecution"),
SharedMemory: atomicMemory.NewSharedMemory(mainnetCChainID),
BCLookup: ids.NewAliaser(),
Metrics: metricsGatherer,
Metrics: vmMultiGatherer,

WarpSigner: warpSigner,

Expand Down Expand Up @@ -592,27 +600,3 @@ func parseCustomLabels(labelsStr string) (map[string]string, error) {
}
return labels, nil
}

func getTopLevelMetrics(b *testing.B, registry prometheus.Gatherer, elapsed time.Duration) {
r := require.New(b)

gasUsed, err := getCounterMetricValue(registry, "avalanche_evm_eth_chain_block_gas_used_processed")
r.NoError(err)
mgasPerSecond := gasUsed / 1_000_000 / elapsed.Seconds()
b.ReportMetric(mgasPerSecond, "mgas/s")
}

func getCounterMetricValue(registry prometheus.Gatherer, query string) (float64, error) {
metricFamilies, err := registry.Gather()
if err != nil {
return 0, fmt.Errorf("failed to gather metrics: %w", err)
}

for _, mf := range metricFamilies {
if mf.GetName() == query {
return mf.GetMetric()[0].Counter.GetValue(), nil
}
}

return 0, fmt.Errorf("metric %s not found", query)
}