diff --git a/cli/flags.go b/cli/flags.go index 96d55817..29d5c64e 100644 --- a/cli/flags.go +++ b/cli/flags.go @@ -10,7 +10,6 @@ import ( "github.com/bitcoin-sv/block-headers-service/config" "github.com/bitcoin-sv/block-headers-service/database" "github.com/bitcoin-sv/block-headers-service/logging" - "github.com/bitcoin-sv/block-headers-service/version" ) type cliFlags struct { @@ -68,7 +67,7 @@ func parseCliFlags(cli *cliFlags, cfg *config.AppConfig, appFlags *pflag.FlagSet } if cli.showVersion { - log.Info().Msgf("block headers service version %s", version.String()) + fmt.Println(config.ApplicationName, config.Version()) os.Exit(0) } diff --git a/cmd/main.go b/cmd/main.go index 82f0d001..e10a643a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -31,11 +31,14 @@ import ( httpserver "github.com/bitcoin-sv/block-headers-service/transports/http/server" "github.com/bitcoin-sv/block-headers-service/transports/p2p" peerpkg "github.com/bitcoin-sv/block-headers-service/transports/p2p/peer" - "github.com/bitcoin-sv/block-headers-service/version" sqlrepository "github.com/bitcoin-sv/block-headers-service/database/repository" ) +// version version of the application that can be overridden with ldflags during build +// (e.g. go build -ldflags "-X main.version=1.2.3"). +var version = "development" + // nolint: godot // @securityDefinitions.apikey Bearer // @in header @@ -43,7 +46,7 @@ import ( func main() { defaultLog := logging.GetDefaultLogger() - if err := config.SetDefaults(defaultLog); err != nil { + if err := config.SetDefaults(version, defaultLog); err != nil { defaultLog.Error().Msgf("cannot set config default values: %v", err) } @@ -89,7 +92,7 @@ func main() { wire.SetLimits(config.ExcessiveBlockSize) // Show version at startup. - log.Info().Msgf("Version %s", version.String()) + log.Info().Msgf("Version %s", config.Version()) peers := make(map[*peerpkg.Peer]*peerpkg.PeerSyncState) diff --git a/config/config.go b/config/config.go index e610d205..fea2bba3 100644 --- a/config/config.go +++ b/config/config.go @@ -11,14 +11,14 @@ import ( ) const ( - ApplicationName = "Block Headers Service" - APIVersion = "v1" - Version = "v0.6.0" + ApplicationName = "block-headers-service" ConfigFilePathKey = "config_file" DefaultConfigFilePath = "config.yaml" ConfigEnvPrefix = "bhs" ) +var version = "should-be-overridden-by-setDefaults" + var Lookup func(string) ([]net.IP, error) var Dial func(string, string, time.Duration) (net.Conn, error) var Checkpoints []chaincfg.Checkpoint @@ -32,6 +32,10 @@ const ( DBPostgreSql DbEngine = "postgres" ) +func Version() string { + return version +} + // AppConfig returns strongly typed config values. type AppConfig struct { Db *DbConfig `mapstructure:"db"` @@ -119,6 +123,8 @@ type P2PConfig struct { BlocksForForkConfirmation int `mapstructure:"blocks_for_confirmation" description:"Minimum number of blocks to consider a block confirmed"` // DefaultConnectTimeout is the default connection timeout. DefaultConnectTimeout time.Duration `mapstructure:"default_connect_timeout" description:"The default connection timeout"` + UserAgentName string `mapstructure:"user_agent_name" description:"The name that should be used during announcement of the client on the p2p network"` + UserAgentVersion string `mapstructure:"user_agent_version" description:"By default will be equal to application version, but can be overridden for development purposes"` } // LoggingConfig represents a logging config. diff --git a/config/defaults.go b/config/defaults.go index 98dcf3f7..d8720352 100644 --- a/config/defaults.go +++ b/config/defaults.go @@ -65,6 +65,8 @@ func getP2PDefaults() *P2PConfig { BlocksForForkConfirmation: 10, DefaultConnectTimeout: 30 * time.Second, DisableCheckpoints: false, + UserAgentName: ApplicationName, + UserAgentVersion: Version(), } } @@ -72,7 +74,7 @@ func getLoggingDefaults() *LoggingConfig { return &LoggingConfig{ Level: "debug", Format: "console", - InstanceName: "block-headers-service", + InstanceName: ApplicationName, LogOrigin: true, } } diff --git a/config/load.go b/config/load.go index 9c715a92..2ef96410 100644 --- a/config/load.go +++ b/config/load.go @@ -3,14 +3,13 @@ package config import ( "fmt" "net" + "os" "strings" "sync" "github.com/bitcoin-sv/block-headers-service/logging" "github.com/rs/zerolog" - "os" - "github.com/mitchellh/mapstructure" "github.com/spf13/viper" ) @@ -40,9 +39,11 @@ func Load(cfg *AppConfig) (*AppConfig, *zerolog.Logger, error) { return cfg, logger, nil } -func SetDefaults(log *zerolog.Logger) error { +func SetDefaults(defaultVersion string, log *zerolog.Logger) error { + viperLock.Lock() + defer viperLock.Unlock() viper.SetDefault(ConfigFilePathKey, DefaultConfigFilePath) - + version = defaultVersion defaultsMap := make(map[string]interface{}) if err := mapstructure.Decode(GetDefaultAppConfig(), &defaultsMap); err != nil { return err diff --git a/docs/docs.go b/docs/docs.go index 05b315ec..fb283f8a 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -1,4 +1,5 @@ -// Package docs Code generated by swaggo/swag. DO NOT EDIT +// Code generated by swaggo/swag. DO NOT EDIT. + package docs import "github.com/swaggo/swag" diff --git a/internal/tests/testapp/test_bhs.go b/internal/tests/testapp/test_bhs.go index fd19bdcd..96e00163 100644 --- a/internal/tests/testapp/test_bhs.go +++ b/internal/tests/testapp/test_bhs.go @@ -70,7 +70,7 @@ func NewTestBlockHeaderService(t *testing.T, ops ...bhsOpt) (*TestBlockHeaderSer viper.Reset() testLog := zerolog.Nop() - if err := config.SetDefaults(&testLog); err != nil { + if err := config.SetDefaults("unittest", &testLog); err != nil { panic(fmt.Sprintf("cannot set config default values: %v", err)) } defaultConfig := config.GetDefaultAppConfig() diff --git a/transports/http/endpoints/swagger/endpoints.go b/transports/http/endpoints/swagger/endpoints.go index aaf17710..9c2177e4 100644 --- a/transports/http/endpoints/swagger/endpoints.go +++ b/transports/http/endpoints/swagger/endpoints.go @@ -1,6 +1,7 @@ package swagger import ( + "github.com/bitcoin-sv/block-headers-service/config" "github.com/bitcoin-sv/block-headers-service/docs" "github.com/bitcoin-sv/block-headers-service/service" router "github.com/bitcoin-sv/block-headers-service/transports/http/endpoints/routes" @@ -10,9 +11,10 @@ import ( ) // NewHandler creates new endpoint handler. -func NewHandler(s *service.Services, apiUrlPrefix string) router.RootEndpoints { +func NewHandler(_ *service.Services, apiUrlPrefix string) router.RootEndpoints { return router.RootEndpointsFunc(func(router *gin.RouterGroup) { docs.SwaggerInfo.BasePath = apiUrlPrefix + docs.SwaggerInfo.Version = config.Version() router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) }) } diff --git a/transports/p2p/server.go b/transports/p2p/server.go index 41b36a25..49a54a22 100644 --- a/transports/p2p/server.go +++ b/transports/p2p/server.go @@ -191,9 +191,9 @@ func (ps *peerState) forAllPeers(closure func(sp *serverPeer)) { // server provides a bitcoin server for handling communications to and from // bitcoin peers. type server struct { - started int32 - shutdown int32 - startupTime int64 + started int32 + shutdown int32 + startupTime int64 chainParams *chaincfg.Params addrManager *addrmgr.AddrManager @@ -882,8 +882,8 @@ func newPeerConfig(sp *serverPeer) *peer.Config { AddrMe: addrMe, NewestBlock: sp.newestBlock, HostToNetAddress: sp.server.addrManager.HostToNetAddress, - UserAgentName: userAgentName, - UserAgentVersion: userAgentVersion, + UserAgentName: sp.server.p2pConfig.UserAgentName, + UserAgentVersion: sp.server.p2pConfig.UserAgentVersion, UserAgentComments: initUserAgentComments(config.ExcessiveBlockSize), ChainParams: sp.server.chainParams, Services: sp.server.wireServices, diff --git a/version/version.go b/version/version.go deleted file mode 100644 index 70dc4462..00000000 --- a/version/version.go +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2013-2014 The btcsuite developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -package version - -import ( - "bytes" - "fmt" - "strings" -) - -// semanticAlphabet. -const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" - -// These constants define the application version and follow the semantic -// versioning 2.0.0 spec (http://semver.org/). -const ( - AppMajor uint = 0 - AppMinor uint = 13 - AppPatch uint = 0 - - // AppPreRelease MUST only contain characters from semanticAlphabet - // per the semantic versioning spec. - AppPreRelease = "beta" -) - -// appBuild is defined as a variable so it can be overridden during the build -// process with '-ldflags "-X main.appBuild foo' if needed. It MUST only -// contain characters from semanticAlphabet per the semantic versioning spec. -var appBuild string - -// String returns the application version as a properly formed string per the -// semantic versioning 2.0.0 spec (http://semver.org/). -func String() string { - // Start with the major, minor, and patch versions. - version := fmt.Sprintf("%d.%d.%d", AppMajor, AppMinor, AppPatch) - - // Append pre-release version if there is one. The hyphen called for - // by the semantic versioning spec is automatically appended and should - // not be contained in the pre-release string. The pre-release version - // is not appended if it contains invalid characters. - if AppPreRelease != "" { - preRelease := normalizeVerString(AppPreRelease) - if preRelease == AppPreRelease { - version = fmt.Sprintf("%s-%s", version, preRelease) - } - } - - // Append build metadata if there is any. The plus called for - // by the semantic versioning spec is automatically appended and should - // not be contained in the build metadata string. The build metadata - // string is not appended if it contains invalid characters. - if appBuild != "" { - build := normalizeVerString(appBuild) - if build == appBuild { - version = fmt.Sprintf("%s+%s", version, build) - } - } - - return version -} - -// normalizeVerString returns the passed string stripped of all characters which -// are not valid according to the semantic versioning guidelines for pre-release -// version and build metadata strings. In particular they MUST only contain -// characters in semanticAlphabet. -func normalizeVerString(str string) string { - var result bytes.Buffer - for _, r := range str { - if strings.ContainsRune(semanticAlphabet, r) { - result.WriteRune(r) - } - } - return result.String() -} diff --git a/version/version_test.go b/version/version_test.go deleted file mode 100644 index 2a07b56c..00000000 --- a/version/version_test.go +++ /dev/null @@ -1,38 +0,0 @@ -package version - -import ( - "fmt" - "testing" -) - -func TestString(t *testing.T) { - base := fmt.Sprintf("%d.%d.%d-%s", AppMajor, AppMinor, AppPatch, AppPreRelease) - - testCases := []struct { - name string - build string - expected string - }{ - { - name: "standard-release", - build: "", - expected: base, - }, { - name: "with-build", - build: "012-abc", - expected: base + "+012-abc", - }, { - name: "with-out-of-spec-build", - build: "012_abc", - expected: base, - }, - } - - for _, tc := range testCases { - appBuild = tc.build - v := String() - if v != tc.expected { - t.Fatalf("%s: expected %s, got %s", tc.name, tc.expected, v) - } - } -}