diff --git a/rpc/dcrd.go b/rpc/dcrd.go index 6c7e2c3..ba598ea 100644 --- a/rpc/dcrd.go +++ b/rpc/dcrd.go @@ -14,8 +14,8 @@ import ( "github.com/jrick/wsrpc/v2" ) -const ( - requiredDcrdVersion = "6.1.2" +var ( + requiredDcrdVersion = semver{Major: 6, Minor: 1, Patch: 2} ) // These error codes are defined in dcrd/dcrjson. They are copied here so we @@ -60,13 +60,16 @@ func (d *DcrdConnect) Client(ctx context.Context, netParams *chaincfg.Params) (* if err != nil { return nil, fmt.Errorf("dcrd version check failed: %v", err) } - dcrdVersion, exists := verMap["dcrdjsonrpcapi"] + + ver, exists := verMap["dcrdjsonrpcapi"] if !exists { return nil, fmt.Errorf("dcrd version response missing 'dcrdjsonrpcapi'") } - if dcrdVersion.VersionString != requiredDcrdVersion { - return nil, fmt.Errorf("wrong dcrd RPC version: got %s, expected %s", - dcrdVersion.VersionString, requiredDcrdVersion) + + sVer := semver{ver.Major, ver.Minor, ver.Patch} + if !semverCompatible(requiredDcrdVersion, sVer) { + return nil, fmt.Errorf("dcrd has incompatible JSON-RPC version: got %s, expected %s", + sVer, requiredDcrdVersion) } // Verify dcrd is on the correct network. diff --git a/rpc/dcrwallet.go b/rpc/dcrwallet.go index 7f18a94..07c9399 100644 --- a/rpc/dcrwallet.go +++ b/rpc/dcrwallet.go @@ -10,8 +10,8 @@ import ( "github.com/decred/dcrd/wire" ) -const ( - requiredWalletVersion = "8.1.0" +var ( + requiredWalletVersion = semver{Major: 8, Minor: 1, Patch: 0} ) // WalletRPC provides methods for calling dcrwallet JSON-RPCs without exposing the details @@ -70,16 +70,19 @@ func (w *WalletConnect) Clients(ctx context.Context, netParams *chaincfg.Params) failedConnections = append(failedConnections, connect.addr) continue } - walletVersion, exists := verMap["dcrwalletjsonrpcapi"] + + ver, exists := verMap["dcrwalletjsonrpcapi"] if !exists { log.Errorf("dcrwallet.Version response missing 'dcrwalletjsonrpcapi' (wallet=%s)", c.String()) failedConnections = append(failedConnections, connect.addr) continue } - if walletVersion.VersionString != requiredWalletVersion { - log.Errorf("dcrwallet has wrong RPC version (wallet=%s): got %s, expected %s", - c.String(), walletVersion.VersionString, requiredWalletVersion) + + sVer := semver{ver.Major, ver.Minor, ver.Patch} + if !semverCompatible(requiredWalletVersion, sVer) { + log.Errorf("dcrwallet has incompatible JSON-RPC version (wallet=%s): got %s, expected %s", + c.String(), sVer, requiredWalletVersion) failedConnections = append(failedConnections, connect.addr) continue } diff --git a/rpc/semver.go b/rpc/semver.go new file mode 100644 index 0000000..153f73a --- /dev/null +++ b/rpc/semver.go @@ -0,0 +1,30 @@ +// Copyright (c) 2020 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package rpc + +import "fmt" + +type semver struct { + Major uint32 + Minor uint32 + Patch uint32 +} + +func semverCompatible(required, actual semver) bool { + switch { + case required.Major != actual.Major: + return false + case required.Minor > actual.Minor: + return false + case required.Minor == actual.Minor && required.Patch > actual.Patch: + return false + default: + return true + } +} + +func (s semver) String() string { + return fmt.Sprintf("%d.%d.%d", s.Major, s.Minor, s.Patch) +}