Files
zeekay ede37547f6 refactor(platformvm): consolidate block code, drop atomic_block, add v0 lift
- Drop atomic_block.go + legacy *_block_test.go (consolidated)
- Add block/v0/ subdir + lift_v0.go for old version handling
- Copyright header: 'Lux Industries, Inc.' → 'Lux Industries Inc' (no comma)
- block_adapter.go: new adapter layer
2026-06-01 15:22:27 -07:00

248 lines
7.0 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package metrics
import (
"errors"
"time"
"github.com/luxfi/metric"
"github.com/luxfi/ids"
utilmetric "github.com/luxfi/node/utils/metric"
"github.com/luxfi/codec/wrappers"
"github.com/luxfi/node/vms/components/gas"
"github.com/luxfi/node/vms/platformvm/block"
)
const (
ResourceLabel = "resource"
GasLabel = "gas"
ValidatorsLabel = "validators"
)
var (
gasLabels = metric.Labels{
ResourceLabel: GasLabel,
}
validatorsLabels = metric.Labels{
ResourceLabel: ValidatorsLabel,
}
)
var _ Metrics = (*metricsImpl)(nil)
type Block struct {
Block block.Block
GasConsumed gas.Gas
GasState gas.State
GasPrice gas.Price
ActiveL1Validators int
ValidatorExcess gas.Gas
ValidatorPrice gas.Price
AccruedValidatorFees uint64
}
type Metrics interface {
utilmetric.APIInterceptor
// Mark that the given block was accepted.
MarkAccepted(Block) error
// Mark that a validator set was created.
IncValidatorSetsCreated()
// Mark that a validator set was cached.
IncValidatorSetsCached()
// Mark that we spent the given time computing validator diffs.
AddValidatorSetsDuration(time.Duration)
// Mark that we computed a validator diff at a height with the given
// difference from the top.
AddValidatorSetsHeightDiff(uint64)
// Mark that this much stake is staked on the node.
SetLocalStake(uint64)
// Mark that this much stake is staked in the network.
SetTotalStake(uint64)
// Mark when this node will unstake from the Primary Network.
SetTimeUntilUnstake(time.Duration)
// Mark when this node will unstake from a net.
SetTimeUntilNetUnstake(netID ids.ID, timeUntilUnstake time.Duration)
}
func New(registerer metric.Registerer) (Metrics, error) {
blockMetrics, err := newBlockMetrics(registerer)
m := &metricsImpl{
blockMetrics: blockMetrics,
timeUntilUnstake: metric.NewGauge(metric.GaugeOpts{
Name: "time_until_unstake",
Help: "Time (in ns) until this node leaves the Primary Network's validator set",
}),
timeUntilNetUnstake: metric.NewGaugeVec(
metric.GaugeOpts{
Name: "time_until_unstake_net",
Help: "Time (in ns) until this node leaves the net's validator set",
},
[]string{"netID"},
),
localStake: metric.NewGauge(metric.GaugeOpts{
Name: "local_staked",
Help: "Amount (in nLUX) of LUX staked on this node",
}),
totalStake: metric.NewGauge(metric.GaugeOpts{
Name: "total_staked",
Help: "Amount (in nLUX) of LUX staked on the Primary Network",
}),
gasConsumed: metric.NewCounter(metric.CounterOpts{
Name: "gas_consumed",
Help: "Cumulative amount of gas consumed by transactions",
}),
gasCapacity: metric.NewGauge(metric.GaugeOpts{
Name: "gas_capacity",
Help: "Minimum amount of gas that can be consumed in the next block",
}),
activeL1Validators: metric.NewGauge(metric.GaugeOpts{
Name: "active_l1_validators",
Help: "Number of active L1 validators",
}),
excess: metric.NewGaugeVec(
metric.GaugeOpts{
Name: "excess",
Help: "Excess usage of a resource over the target usage",
},
[]string{ResourceLabel},
),
price: metric.NewGaugeVec(
metric.GaugeOpts{
Name: "price",
Help: "Price (in nLUX) of a resource",
},
[]string{ResourceLabel},
),
accruedValidatorFees: metric.NewGauge(metric.GaugeOpts{
Name: "accrued_validator_fees",
Help: "The total cost of running an active L1 validator since L1-validator feature launch",
}),
validatorSetsCached: metric.NewCounter(metric.CounterOpts{
Name: "validator_sets_cached",
Help: "Total number of validator sets cached",
}),
validatorSetsCreated: metric.NewCounter(metric.CounterOpts{
Name: "validator_sets_created",
Help: "Total number of validator sets created from applying difflayers",
}),
validatorSetsHeightDiff: metric.NewGauge(metric.GaugeOpts{
Name: "validator_sets_height_diff_sum",
Help: "Total number of validator sets diffs applied for generating validator sets",
}),
validatorSetsDuration: metric.NewGauge(metric.GaugeOpts{
Name: "validator_sets_duration_sum",
Help: "Total amount of time generating validator sets in nanoseconds",
}),
}
errs := wrappers.Errs{Err: err}
registry, ok := registerer.(metric.Registry)
if !ok {
return nil, errors.New("registerer must be a Registry")
}
apiRequestMetrics, err := utilmetric.NewAPIInterceptor(registry)
errs.Add(err)
m.APIInterceptor = apiRequestMetrics
errs.Add(
registerer.Register(m.timeUntilUnstake),
registerer.Register(m.timeUntilNetUnstake),
registerer.Register(m.localStake),
registerer.Register(m.totalStake),
registerer.Register(m.gasConsumed),
registerer.Register(m.gasCapacity),
registerer.Register(m.activeL1Validators),
registerer.Register(m.excess),
registerer.Register(m.price),
registerer.Register(m.accruedValidatorFees),
registerer.Register(m.validatorSetsCreated),
registerer.Register(m.validatorSetsCached),
registerer.Register(m.validatorSetsHeightDiff),
registerer.Register(m.validatorSetsDuration),
)
return m, errs.Err
}
type metricsImpl struct {
utilmetric.APIInterceptor
blockMetrics *blockMetrics
// Staking metrics
timeUntilUnstake metric.Gauge
timeUntilNetUnstake metric.GaugeVec
localStake metric.Gauge
totalStake metric.Gauge
gasConsumed metric.Counter
gasCapacity metric.Gauge
activeL1Validators metric.Gauge
excess metric.GaugeVec
price metric.GaugeVec
accruedValidatorFees metric.Gauge
// Validator set diff metrics
validatorSetsCached metric.Counter
validatorSetsCreated metric.Counter
validatorSetsHeightDiff metric.Gauge
validatorSetsDuration metric.Gauge
}
func (m *metricsImpl) MarkAccepted(b Block) error {
m.gasConsumed.Add(float64(b.GasConsumed))
m.gasCapacity.Set(float64(b.GasState.Capacity))
m.excess.With(gasLabels).Set(float64(b.GasState.Excess))
m.price.With(gasLabels).Set(float64(b.GasPrice))
m.activeL1Validators.Set(float64(b.ActiveL1Validators))
m.excess.With(validatorsLabels).Set(float64(b.ValidatorExcess))
m.price.With(validatorsLabels).Set(float64(b.ValidatorPrice))
m.accruedValidatorFees.Set(float64(b.AccruedValidatorFees))
return b.Block.Visit(m.blockMetrics)
}
func (m *metricsImpl) IncValidatorSetsCreated() {
m.validatorSetsCreated.Inc()
}
func (m *metricsImpl) IncValidatorSetsCached() {
m.validatorSetsCached.Inc()
}
func (m *metricsImpl) AddValidatorSetsDuration(d time.Duration) {
m.validatorSetsDuration.Add(float64(d))
}
func (m *metricsImpl) AddValidatorSetsHeightDiff(d uint64) {
m.validatorSetsHeightDiff.Add(float64(d))
}
func (m *metricsImpl) SetLocalStake(s uint64) {
m.localStake.Set(float64(s))
}
func (m *metricsImpl) SetTotalStake(s uint64) {
m.totalStake.Set(float64(s))
}
func (m *metricsImpl) SetTimeUntilUnstake(timeUntilUnstake time.Duration) {
m.timeUntilUnstake.Set(float64(timeUntilUnstake))
}
func (m *metricsImpl) SetTimeUntilNetUnstake(netID ids.ID, timeUntilUnstake time.Duration) {
m.timeUntilNetUnstake.WithLabelValues(netID.String()).Set(float64(timeUntilUnstake))
}