github.com/ethersphere/bee/v2@v2.2.0/pkg/p2p/libp2p/version.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package libp2p 6 7 import ( 8 "errors" 9 "strings" 10 11 "github.com/coreos/go-semver/semver" 12 protocol "github.com/libp2p/go-libp2p/core/protocol" 13 ) 14 15 // protocolSemverMatcher returns a matcher function for a given base protocol. 16 // Protocol ID must be constructed according to the Swarm protocol ID 17 // specification, where the second to last part is the version is semver format. 18 // The matcher function will return a boolean indicating whether a protocol ID 19 // matches the base protocol. A given protocol ID matches the base protocol if 20 // the IDs are the same and if the semantic version of the base protocol is the 21 // same or higher than that of the protocol ID provided. 22 func (s *Service) protocolSemverMatcher(base protocol.ID) (func(protocol.ID) bool, error) { 23 parts := strings.Split(string(base), "/") 24 partsLen := len(parts) 25 if partsLen < 2 { 26 return nil, errors.New("invalid protocol id") 27 } 28 vers, err := semver.NewVersion(parts[partsLen-2]) 29 if err != nil { 30 return nil, err 31 } 32 33 return func(check protocol.ID) bool { 34 chparts := strings.Split(string(check), "/") 35 chpartsLen := len(chparts) 36 if chpartsLen != partsLen { 37 return false 38 } 39 40 for i, v := range chparts { 41 if i == chpartsLen-2 { 42 continue 43 } 44 if parts[i] != v { 45 return false 46 } 47 } 48 49 chvers, err := semver.NewVersion(chparts[chpartsLen-2]) 50 if err != nil { 51 s.logger.Debug("invalid protocol version", "version", check, "error", err) 52 return false 53 } 54 55 return vers.Major == chvers.Major && vers.Minor >= chvers.Minor 56 }, nil 57 }