Skip to content

Commit abe98bc

Browse files
authored
Merge branch 'master' into leveldb-config
2 parents 367f363 + 29b4e6b commit abe98bc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+220
-85
lines changed

Taskfile.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ tasks:
118118
desc: Generates testing mocks
119119
cmds:
120120
- cmd: grep -lr -E '^// Code generated by MockGen\. DO NOT EDIT\.$' . | xargs -r rm
121-
- cmd: go generate -run "go.uber.org/mock/mockgen" ./...
121+
- cmd: go generate -run "mockgen" ./...
122122

123123
generate-canoto:
124124
desc: Generates canoto
125-
cmd: go generate -run "github.com/StephenButtolph/canoto/canoto" ./...
125+
cmd: go generate -run "canoto" ./...
126126

127127
generate-load-contract-bindings:
128128
desc: Generates load contract bindings

api/metrics/client.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212

1313
"github.com/prometheus/common/expfmt"
1414

15+
"github.com/ava-labs/avalanchego/utils/rpc"
16+
1517
dto "github.com/prometheus/client_model/go"
1618
)
1719

@@ -45,24 +47,18 @@ func (c *Client) GetMetrics(ctx context.Context) (map[string]*dto.MetricFamily,
4547
return nil, fmt.Errorf("failed to create request: %w", err)
4648
}
4749

50+
//nolint:bodyclose // body is closed via rpc.CleanlyCloseBody
4851
resp, err := http.DefaultClient.Do(request)
4952
if err != nil {
5053
return nil, fmt.Errorf("failed to issue request: %w", err)
5154
}
55+
defer rpc.CleanlyCloseBody(resp.Body)
5256

5357
// Return an error for any non successful status code
5458
if resp.StatusCode < 200 || resp.StatusCode > 299 {
55-
// Drop any error during close to report the original error
56-
_ = resp.Body.Close()
5759
return nil, fmt.Errorf("received status code: %d", resp.StatusCode)
5860
}
5961

6062
var parser expfmt.TextParser
61-
metrics, err := parser.TextToMetricFamilies(resp.Body)
62-
if err != nil {
63-
// Drop any error during close to report the original error
64-
_ = resp.Body.Close()
65-
return nil, err
66-
}
67-
return metrics, resp.Body.Close()
63+
return parser.TextToMetricFamilies(resp.Body)
6864
}

chains/atomic/mocks_generate_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
package atomic
55

6-
//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/shared_memory.go -mock_names=SharedMemory=SharedMemory . SharedMemory
6+
//go:generate go tool mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/shared_memory.go -mock_names=SharedMemory=SharedMemory . SharedMemory

codec/mocks_generate_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
package codec
55

6-
//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/manager.go -mock_names=Manager=Manager . Manager
6+
//go:generate go tool mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/manager.go -mock_names=Manager=Manager . Manager

database/mocks_generate_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33

44
package database
55

6-
//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/batch.go -mock_names=Batch=Batch . Batch
7-
//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/iterator.go -mock_names=Iterator=Iterator . Iterator
6+
//go:generate go tool mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/batch.go -mock_names=Batch=Batch . Batch
7+
//go:generate go tool mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/iterator.go -mock_names=Iterator=Iterator . Iterator

go.mod

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ require (
6969
go.uber.org/zap v1.27.0
7070
golang.org/x/crypto v0.43.0
7171
golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e
72-
golang.org/x/mod v0.29.0
7372
golang.org/x/net v0.46.0
7473
golang.org/x/sync v0.17.0
7574
golang.org/x/term v0.36.0
@@ -186,6 +185,7 @@ require (
186185
go.opentelemetry.io/otel/metric v1.37.0 // indirect
187186
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
188187
go.uber.org/multierr v1.11.0 // indirect
188+
golang.org/x/mod v0.29.0 // indirect
189189
golang.org/x/oauth2 v0.30.0 // indirect
190190
golang.org/x/sys v0.37.0 // indirect
191191
golang.org/x/text v0.30.0 // indirect
@@ -199,4 +199,8 @@ require (
199199
sigs.k8s.io/yaml v1.3.0 // indirect
200200
)
201201

202-
tool github.com/onsi/ginkgo/v2/ginkgo
202+
tool (
203+
github.com/StephenButtolph/canoto/canoto
204+
github.com/onsi/ginkgo/v2/ginkgo
205+
go.uber.org/mock/mockgen
206+
)

message/mocks_generate_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33

44
package message
55

6-
//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/outbound_message.go -mock_names=OutboundMessage=OutboundMessage . OutboundMessage
7-
//go:generate go run go.uber.org/mock/mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/outbound_message_builder.go -mock_names=OutboundMsgBuilder=OutboundMsgBuilder . OutboundMsgBuilder
6+
//go:generate go tool mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/outbound_message.go -mock_names=OutboundMessage=OutboundMessage . OutboundMessage
7+
//go:generate go tool mockgen -package=${GOPACKAGE}mock -destination=${GOPACKAGE}mock/outbound_message_builder.go -mock_names=OutboundMsgBuilder=OutboundMsgBuilder . OutboundMsgBuilder

node/node.go

Lines changed: 129 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"fmt"
1414
"io"
1515
"io/fs"
16+
"math"
1617
"net"
1718
"net/netip"
1819
"os"
@@ -25,6 +26,7 @@ import (
2526
"github.com/prometheus/client_golang/prometheus/collectors"
2627
"github.com/prometheus/client_golang/prometheus/promhttp"
2728
"go.uber.org/zap"
29+
"golang.org/x/exp/maps"
2830

2931
"github.com/ava-labs/avalanchego/api/admin"
3032
"github.com/ava-labs/avalanchego/api/health"
@@ -105,6 +107,7 @@ const (
105107
responsesNamespace = constants.PlatformName + metric.NamespaceSeparator + "responses"
106108
rpcchainvmNamespace = constants.PlatformName + metric.NamespaceSeparator + "rpcchainvm"
107109
systemResourcesNamespace = constants.PlatformName + metric.NamespaceSeparator + "system_resources"
110+
upgradeNamespace = constants.PlatformName + metric.NamespaceSeparator + "upgrade"
108111
)
109112

110113
var (
@@ -113,8 +116,12 @@ var (
113116

114117
indexerDBPrefix = []byte{0x00}
115118

116-
errInvalidTLSKey = errors.New("invalid TLS key")
117-
errShuttingDown = errors.New("server shutting down")
119+
errInvalidTLSKey = errors.New("invalid TLS key")
120+
errShuttingDown = errors.New("server shutting down")
121+
errNoValidators = errors.New("no validators in the current validator set")
122+
errUpgradeNeeded = errors.New("unknown network upgrade detected")
123+
errUpgradeWithinTheDay = errors.New("unknown network upgrade detected - update as soon as possible")
124+
errUpgradeWithinTheHour = errors.New("imminent network upgrade detected - update immediately")
118125
)
119126

120127
// New returns an instance of Node
@@ -1499,6 +1506,126 @@ func (n *Node) initHealthAPI() error {
14991506
return fmt.Errorf("couldn't register bls health check: %w", err)
15001507
}
15011508

1509+
upgradeReg, err := metrics.MakeAndRegister(
1510+
n.MetricsGatherer,
1511+
upgradeNamespace,
1512+
)
1513+
if err != nil {
1514+
return fmt.Errorf("couldn't create upgrade metrics register: %w", err)
1515+
}
1516+
1517+
timeUntilUpgradeMetric := prometheus.NewGauge(prometheus.GaugeOpts{
1518+
Name: "time_until",
1519+
Help: "Time until an upcoming network upgrade (ns). +Inf means the upgrade is unscheduled.",
1520+
})
1521+
infinity := math.Inf(1)
1522+
timeUntilUpgradeMetric.Set(infinity)
1523+
if err := upgradeReg.Register(timeUntilUpgradeMetric); err != nil {
1524+
return fmt.Errorf("couldn't register time until upgrade metric: %w", err)
1525+
}
1526+
1527+
// TODO: This healthcheck calls both n.vdrs.GetMap and n.Net.PeerInfo which
1528+
// are expensive calls. This could be rewritten as an event based monitor to
1529+
// avoid expensive iteration.
1530+
var (
1531+
localUpgradeTime = n.Config.UpgradeConfig.GraniteTime
1532+
localUpgradeTimeUnix = uint64(localUpgradeTime.Unix())
1533+
lastLogTime time.Time
1534+
)
1535+
futureUpgradeCheck := health.CheckerFunc(func(context.Context) (interface{}, error) {
1536+
var (
1537+
currentValidators = n.vdrs.GetMap(constants.PrimaryNetworkID)
1538+
totalWeight uint64
1539+
)
1540+
for _, vdr := range currentValidators {
1541+
totalWeight += vdr.Weight
1542+
}
1543+
if totalWeight == 0 {
1544+
return nil, errNoValidators
1545+
}
1546+
1547+
var (
1548+
peers = n.Net.PeerInfo(maps.Keys(currentValidators))
1549+
upgradeTimes = make(map[uint64]uint64) // upgrade time -> stake weight
1550+
modeUpgradeTimeUnix uint64
1551+
modeUpgradeWeight uint64
1552+
)
1553+
for _, peer := range peers {
1554+
vdr := currentValidators[peer.ID]
1555+
upgradeWeight := upgradeTimes[peer.UpgradeTime]
1556+
upgradeWeight += vdr.Weight
1557+
upgradeTimes[peer.UpgradeTime] = upgradeWeight
1558+
1559+
if upgradeWeight > modeUpgradeWeight {
1560+
modeUpgradeTimeUnix = peer.UpgradeTime
1561+
modeUpgradeWeight = upgradeWeight
1562+
}
1563+
}
1564+
1565+
modeUpgradeWeightPortion := float64(modeUpgradeWeight) / float64(totalWeight)
1566+
result := map[string]interface{}{
1567+
"localUpgradeTime": localUpgradeTime,
1568+
"modeUpgradeTime": time.Unix(int64(modeUpgradeTimeUnix), 0).UTC(),
1569+
"modeUpgradeWeightPercentage": 100 * modeUpgradeWeightPortion,
1570+
"numUpgradeTimes": len(upgradeTimes),
1571+
}
1572+
if localUpgradeTimeUnix >= modeUpgradeTimeUnix || modeUpgradeWeightPortion < .5 {
1573+
timeUntilUpgradeMetric.Set(infinity)
1574+
return result, nil
1575+
}
1576+
1577+
const (
1578+
day = 24 * time.Hour
1579+
week = 7 * day
1580+
)
1581+
modeUpgradeTime := time.Unix(int64(modeUpgradeTimeUnix), 0)
1582+
timeUntilUpgrade := time.Until(modeUpgradeTime)
1583+
timeUntilUpgradeMetric.Set(float64(timeUntilUpgrade))
1584+
result["timeUntilUpgrade"] = timeUntilUpgrade.String()
1585+
1586+
var (
1587+
logFrequency time.Duration
1588+
log func(msg string, fields ...zap.Field)
1589+
err error
1590+
)
1591+
switch {
1592+
case timeUntilUpgrade > week:
1593+
logFrequency = 12 * time.Hour
1594+
log = n.Log.Info
1595+
case timeUntilUpgrade > 3*day:
1596+
logFrequency = 12 * time.Hour
1597+
log = n.Log.Warn
1598+
case timeUntilUpgrade > day:
1599+
logFrequency = time.Hour
1600+
log = n.Log.Warn
1601+
err = errUpgradeNeeded
1602+
case timeUntilUpgrade > time.Hour:
1603+
logFrequency = time.Hour
1604+
log = n.Log.Error
1605+
err = errUpgradeWithinTheDay
1606+
default:
1607+
logFrequency = 0 // log at the rate of the health check
1608+
log = n.Log.Error
1609+
err = errUpgradeWithinTheHour
1610+
}
1611+
1612+
if time.Since(lastLogTime) >= logFrequency {
1613+
log("unknown upgrade detected - this node should be updated to a compatible version",
1614+
zap.String("latestReleaseURL", "https://github.com/ava-labs/avalanchego/releases/latest"),
1615+
zap.Time("upgradeTime", modeUpgradeTime),
1616+
zap.Duration("timeUntilUpgrade", timeUntilUpgrade),
1617+
zap.Error(err),
1618+
)
1619+
lastLogTime = time.Now()
1620+
}
1621+
return result, err
1622+
})
1623+
1624+
err = n.health.RegisterHealthCheck("futureupgrade", futureUpgradeCheck, health.ApplicationTag)
1625+
if err != nil {
1626+
return fmt.Errorf("couldn't register future upgrade health check: %w", err)
1627+
}
1628+
15021629
handler, err := health.NewGetAndPostHandler(n.Log, n.health)
15031630
if err != nil {
15041631
return err

simplex/block.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
package simplex
55

6-
//go:generate go run github.com/StephenButtolph/canoto/canoto $GOFILE
6+
//go:generate go tool canoto $GOFILE
77

88
import (
99
"context"

simplex/qc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
package simplex
55

6-
//go:generate go run github.com/StephenButtolph/canoto/canoto $GOFILE
6+
//go:generate go tool canoto $GOFILE
77

88
import (
99
"bytes"

0 commit comments

Comments
 (0)