diff --git a/core/blockchain.go b/core/blockchain.go
index eec9c77212..fe127b5ea8 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -22,6 +22,7 @@ import (
"fmt"
"io"
"math/big"
+ "runtime"
"sort"
"strings"
"sync"
@@ -40,6 +41,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"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/metrics"
"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))
}
+// 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
// 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.
diff --git a/internal/version/vcs_fallback.go b/internal/version/vcs_fallback.go
new file mode 100644
index 0000000000..6d7f32e735
--- /dev/null
+++ b/internal/version/vcs_fallback.go
@@ -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 .
+
+//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
+}
diff --git a/internal/version/vcs_go1.18.go b/internal/version/vcs_go1.18.go
new file mode 100644
index 0000000000..d5b9c97a16
--- /dev/null
+++ b/internal/version/vcs_go1.18.go
@@ -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 .
+
+//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
+}
diff --git a/core/badblock.go b/internal/version/version.go
similarity index 61%
rename from core/badblock.go
rename to internal/version/version.go
index a2fdfac714..e4b9ee4907 100644
--- a/core/badblock.go
+++ b/internal/version/version.go
@@ -14,70 +14,48 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-package core
+// Package version implements reading of build version information.
+package version
import (
"fmt"
- "runtime"
"runtime/debug"
"strings"
- "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
)
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.
//
// 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,
// it will assume it's imported by a third-party and will return the imported
// version and whether it was replaced by another module.
-func runtimeInfo() (string, string) {
- var (
- version = params.VersionWithMeta
- vcs = ""
- buildInfo, ok = debug.ReadBuildInfo()
- )
- if ok {
- version = versionInfo(buildInfo)
- if status, ok := vcsInfo(buildInfo); ok {
- modified := ""
- if status.modified {
- modified = " (dirty)"
- }
- vcs = status.revision + "-" + status.time + modified
+func Info() (version, vcs string) {
+ version = params.VersionWithMeta
+ buildInfo, ok := debug.ReadBuildInfo()
+ if !ok {
+ return version, ""
+ }
+ version = versionInfo(buildInfo)
+ if status, ok := vcsInfo(buildInfo); ok {
+ modified := ""
+ if status.modified {
+ modified = " (dirty)"
}
+ vcs = status.revision + "-" + status.time + modified
}
return version, vcs
}
+type gitStatus struct {
+ revision string
+ time string
+ modified bool
+}
+
// versionInfo returns version information for the currently executing
// implementation.
//
@@ -113,36 +91,6 @@ func versionInfo(info *debug.BuildInfo) string {
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.
func findModule(info *debug.BuildInfo, path string) *debug.Module {
if info.Path == ourPath {