core: move build version reading to its own package (#25806)

This fixes the build with Go 1.17, which does not have BuildInfo.Settings yet.
This commit is contained in:
Felix Lange 2022-09-19 10:04:16 +02:00 committed by GitHub
parent 8e5201551d
commit 468d1844c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 123 additions and 72 deletions

View File

@ -22,6 +22,7 @@ import (
"fmt" "fmt"
"io" "io"
"math/big" "math/big"
"runtime"
"sort" "sort"
"strings" "strings"
"sync" "sync"
@ -40,6 +41,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/internal/syncx" "github.com/ethereum/go-ethereum/internal/syncx"
"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/metrics"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
@ -2378,6 +2380,31 @@ func (bc *BlockChain) reportBlock(block *types.Block, receipts types.Receipts, e
log.Error(summarizeBadBlock(block, receipts, bc.Config(), err)) log.Error(summarizeBadBlock(block, receipts, bc.Config(), err))
} }
// summarizeBadBlock returns a string summarizing the bad block and other
// relevant information.
func summarizeBadBlock(block *types.Block, receipts []*types.Receipt, config *params.ChainConfig, err error) string {
var receiptString string
for i, receipt := range receipts {
receiptString += fmt.Sprintf("\n %d: cumulative: %v gas: %v contract: %v status: %v tx: %v logs: %v bloom: %x state: %x",
i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(),
receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState)
}
version, vcs := version.Info()
platform := fmt.Sprintf("%s %s %s %s", version, runtime.Version(), runtime.GOARCH, runtime.GOOS)
if vcs != "" {
vcs = fmt.Sprintf("\nVCS: %s", vcs)
}
return fmt.Sprintf(`
########## BAD BLOCK #########
Block: %v (%#x)
Error: %v
Platform: %v%v
Chain config: %#v
Receipts: %v
##############################
`, block.Number(), block.Hash(), err, platform, vcs, config, receiptString)
}
// InsertHeaderChain attempts to insert the given header chain in to the local // InsertHeaderChain attempts to insert the given header chain in to the local
// chain, possibly creating a reorg. If an error is returned, it will return the // chain, possibly creating a reorg. If an error is returned, it will return the
// index number of the failing header as well an error describing what went wrong. // index number of the failing header as well an error describing what went wrong.

View File

@ -0,0 +1,28 @@
// Copyright 2022 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build !go1.18
// +build !go1.18
package version
import "runtime/debug"
// In Go versions before 1.18, VCS information is not available.
func vcsInfo(info *debug.BuildInfo) (gitStatus, bool) {
return gitStatus{}, false
}

View File

@ -0,0 +1,48 @@
// Copyright 2022 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
//go:build go1.18
// +build go1.18
package version
import "runtime/debug"
// In go 1.18 and beyond, the go tool embeds VCS information into the build.
// vcsInfo returns VCS information of the build.
func vcsInfo(info *debug.BuildInfo) (s gitStatus, ok bool) {
for _, v := range info.Settings {
switch v.Key {
case "vcs.revision":
if len(v.Value) < 8 {
s.revision = v.Value
} else {
s.revision = v.Value[:8]
}
case "vcs.modified":
if v.Value == "true" {
s.modified = true
}
case "vcs.time":
s.time = v.Value
}
}
if s.revision != "" && s.time != "" {
ok = true
}
return
}

View File

@ -14,58 +14,31 @@
// You should have received a copy of the GNU Lesser General Public License // You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package core // Package version implements reading of build version information.
package version
import ( import (
"fmt" "fmt"
"runtime"
"runtime/debug" "runtime/debug"
"strings" "strings"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
const ourPath = "github.com/ethereum/go-ethereum" // Path to our module const ourPath = "github.com/ethereum/go-ethereum" // Path to our module
// summarizeBadBlock returns a string summarizing the bad block and other
// relevant information.
func summarizeBadBlock(block *types.Block, receipts []*types.Receipt, config *params.ChainConfig, err error) string {
var receiptString string
for i, receipt := range receipts {
receiptString += fmt.Sprintf("\n %d: cumulative: %v gas: %v contract: %v status: %v tx: %v logs: %v bloom: %x state: %x",
i, receipt.CumulativeGasUsed, receipt.GasUsed, receipt.ContractAddress.Hex(),
receipt.Status, receipt.TxHash.Hex(), receipt.Logs, receipt.Bloom, receipt.PostState)
}
version, vcs := runtimeInfo()
platform := fmt.Sprintf("%s %s %s %s", version, runtime.Version(), runtime.GOARCH, runtime.GOOS)
if vcs != "" {
vcs = fmt.Sprintf("\nVCS: %s", vcs)
}
return fmt.Sprintf(`
########## BAD BLOCK #########
Block: %v (%#x)
Error: %v
Platform: %v%v
Chain config: %#v
Receipts: %v
##############################
`, block.Number(), block.Hash(), err, platform, vcs, config, receiptString)
}
// runtimeInfo returns build and platform information about the current binary. // runtimeInfo returns build and platform information about the current binary.
// //
// If the package that is currently executing is a prefixed by our go-ethereum // If the package that is currently executing is a prefixed by our go-ethereum
// module path, it will print out commit and date VCS information. Otherwise, // module path, it will print out commit and date VCS information. Otherwise,
// it will assume it's imported by a third-party and will return the imported // it will assume it's imported by a third-party and will return the imported
// version and whether it was replaced by another module. // version and whether it was replaced by another module.
func runtimeInfo() (string, string) { func Info() (version, vcs string) {
var (
version = params.VersionWithMeta version = params.VersionWithMeta
vcs = "" buildInfo, ok := debug.ReadBuildInfo()
buildInfo, ok = debug.ReadBuildInfo() if !ok {
) return version, ""
if ok { }
version = versionInfo(buildInfo) version = versionInfo(buildInfo)
if status, ok := vcsInfo(buildInfo); ok { if status, ok := vcsInfo(buildInfo); ok {
modified := "" modified := ""
@ -74,10 +47,15 @@ func runtimeInfo() (string, string) {
} }
vcs = status.revision + "-" + status.time + modified vcs = status.revision + "-" + status.time + modified
} }
}
return version, vcs return version, vcs
} }
type gitStatus struct {
revision string
time string
modified bool
}
// versionInfo returns version information for the currently executing // versionInfo returns version information for the currently executing
// implementation. // implementation.
// //
@ -113,36 +91,6 @@ func versionInfo(info *debug.BuildInfo) string {
return version return version
} }
type status struct {
revision string
time string
modified bool
}
// vcsInfo returns VCS information of the build.
func vcsInfo(info *debug.BuildInfo) (s status, ok bool) {
for _, v := range info.Settings {
switch v.Key {
case "vcs.revision":
if len(v.Value) < 8 {
s.revision = v.Value
} else {
s.revision = v.Value[:8]
}
case "vcs.modified":
if v.Value == "true" {
s.modified = true
}
case "vcs.time":
s.time = v.Value
}
}
if s.revision != "" && s.time != "" {
ok = true
}
return
}
// findModule returns the module at path. // findModule returns the module at path.
func findModule(info *debug.BuildInfo, path string) *debug.Module { func findModule(info *debug.BuildInfo, path string) *debug.Module {
if info.Path == ourPath { if info.Path == ourPath {