You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
tools/tools.go lives in the main module, so build-tool upgrades propagate into the consensus node's runtime dependency graph via Go's minimal version selection. Tool bumps can raise the floor on golang.org/x/crypto and golang.org/x/net.
The //go:build tools tag keeps these out of the build, but not out of the module graph. MVS resolves one version set for the whole module, so a tool's requirements raise the minimum for everything.
#1397 is a clean illustration. Labelled as a buf bump, it moved these direct, runtime-linked dependencies:
Module
Before
After
golang.org/x/crypto
0.53.0
0.54.0
golang.org/x/net
0.56.0
0.57.0
golang.org/x/text
0.38.0
0.40.0
golang.org/x/sys
0.46.0
0.47.0
A linter release therefore has a path to changing the crypto and networking libraries linked into tenderdash. In practice the effect has been benign — and in #1397 it was actively beneficial, pulling x/text past GO-2026-5970 — but the coupling is unintended and reviewers must audit every tool bump as a runtime change.
Suggested fix
Move tool tracking into its own nested module, e.g. tools/go.mod with module github.com/dashpay/tenderdash/tools. Tool upgrades then resolve independently and cannot move the node's dependency floor.
Trade-offs to weigh before doing this:
Requires a second go.mod/go.sum for Dependabot to watch (add a tools/ entry to .github/dependabot.yml).
Makefile targets invoking go run github.com/bufbuild/buf/cmd/buf ... need to run from tools/ or use -C tools.
Go 1.24's tool directive is the more modern alternative to the tools.go blank-import pattern, but on its own it does not solve the shared-graph problem — it still resolves within one module. A nested module is what actually decouples the graphs.
Summary
tools/tools.golives in the main module, so build-tool upgrades propagate into the consensus node's runtime dependency graph via Go's minimal version selection. Tool bumps can raise the floor ongolang.org/x/cryptoandgolang.org/x/net.Detail
tools/tools.gois in the root module and imports:The
//go:build toolstag keeps these out of the build, but not out of the module graph. MVS resolves one version set for the whole module, so a tool's requirements raise the minimum for everything.#1397 is a clean illustration. Labelled as a
bufbump, it moved these direct, runtime-linked dependencies:golang.org/x/cryptogolang.org/x/netgolang.org/x/textgolang.org/x/sysA linter release therefore has a path to changing the crypto and networking libraries linked into
tenderdash. In practice the effect has been benign — and in #1397 it was actively beneficial, pullingx/textpast GO-2026-5970 — but the coupling is unintended and reviewers must audit every tool bump as a runtime change.Suggested fix
Move tool tracking into its own nested module, e.g.
tools/go.modwithmodule github.com/dashpay/tenderdash/tools. Tool upgrades then resolve independently and cannot move the node's dependency floor.Trade-offs to weigh before doing this:
go.mod/go.sumfor Dependabot to watch (add atools/entry to.github/dependabot.yml).go run github.com/bufbuild/buf/cmd/buf ...need to run fromtools/or use-C tools.tooldirective is the more modern alternative to thetools.goblank-import pattern, but on its own it does not solve the shared-graph problem — it still resolves within one module. A nested module is what actually decouples the graphs.govulncheck -tags tools ./...fix proposed there becomes a separate scan of./tools/...instead.Low priority — a hygiene and reviewability improvement, not a live defect.
Context
Found while auditing #1397 (
bufbuild/buf1.71.0 → 1.72.0).🤖 Reported by Claudius the Magnificent AI Agent