137 lines
3.7 KiB
Go
137 lines
3.7 KiB
Go
package types
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"fmt"
|
|
fasthex "github.com/tmthrgd/go-hex"
|
|
"net/netip"
|
|
)
|
|
|
|
func IsPeerVersionInformation(addr netip.AddrPort) bool {
|
|
if addr.Port() != 0xFFFF {
|
|
return false
|
|
}
|
|
rawIp := addr.Addr().As16()
|
|
return bytes.Compare(rawIp[12:], []byte{0xFF, 0xFF, 0xFF, 0xFF}) == 0
|
|
}
|
|
|
|
// ProtocolFeature List of features to check to not depend on hardcoded protocol versions.
|
|
// Use PeerVersionInformation.SupportsFeature() to query these.
|
|
type ProtocolFeature int
|
|
|
|
const (
|
|
// FeaturePeerInformationReceive Backwards compatible, can be sent to all clients
|
|
FeaturePeerInformationReceive = ProtocolFeature(iota)
|
|
FeaturePeerInformationExchange
|
|
FeaturePrunedBroadcast
|
|
FeatureCompactBroadcast
|
|
FeatureBlockNotify
|
|
)
|
|
|
|
type PeerVersionInformation struct {
|
|
Protocol ProtocolVersion
|
|
SoftwareVersion SoftwareVersion
|
|
SoftwareId SoftwareId
|
|
}
|
|
|
|
func (i *PeerVersionInformation) SupportsFeature(feature ProtocolFeature) bool {
|
|
switch feature {
|
|
case FeaturePeerInformationReceive:
|
|
return i.Protocol == ProtocolVersion_0_0 || i.Protocol >= ProtocolVersion_1_0
|
|
case FeaturePeerInformationExchange:
|
|
return i.Protocol >= ProtocolVersion_1_0
|
|
case FeaturePrunedBroadcast:
|
|
return i.Protocol == ProtocolVersion_0_0 || i.Protocol >= ProtocolVersion_1_0
|
|
case FeatureCompactBroadcast:
|
|
return i.Protocol >= ProtocolVersion_1_1
|
|
case FeatureBlockNotify:
|
|
return i.Protocol >= ProtocolVersion_1_2
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (i *PeerVersionInformation) String() string {
|
|
// Empty information
|
|
if i.Protocol == 0 && i.SoftwareVersion == 0 && i.SoftwareId == 0 {
|
|
return "Unknown"
|
|
}
|
|
|
|
return fmt.Sprintf("%s %s (protocol %s)", i.SoftwareId.String(), i.SoftwareVersion.String(), i.Protocol.String())
|
|
}
|
|
|
|
func (i *PeerVersionInformation) ToAddrPort() netip.AddrPort {
|
|
var addr [16]byte
|
|
|
|
binary.LittleEndian.PutUint32(addr[:], uint32(i.Protocol))
|
|
binary.LittleEndian.PutUint32(addr[4:], uint32(i.SoftwareVersion))
|
|
binary.LittleEndian.PutUint32(addr[8:], uint32(i.SoftwareId))
|
|
binary.LittleEndian.PutUint32(addr[12:], 0xFFFFFFFF)
|
|
|
|
return netip.AddrPortFrom(netip.AddrFrom16(addr), 0xFFFF)
|
|
}
|
|
|
|
type ProtocolVersion SemanticVersion
|
|
|
|
func (v ProtocolVersion) Major() uint16 {
|
|
return SemanticVersion(v).Major()
|
|
}
|
|
func (v ProtocolVersion) Minor() uint16 {
|
|
return SemanticVersion(v).Minor()
|
|
}
|
|
|
|
func (v ProtocolVersion) String() string {
|
|
return SemanticVersion(v).String()
|
|
}
|
|
|
|
const (
|
|
ProtocolVersion_0_0 ProtocolVersion = (0 << 16) | 0
|
|
ProtocolVersion_1_0 ProtocolVersion = (1 << 16) | 0
|
|
ProtocolVersion_1_1 ProtocolVersion = (1 << 16) | 1
|
|
ProtocolVersion_1_2 ProtocolVersion = (1 << 16) | 2
|
|
)
|
|
|
|
type SoftwareVersion SemanticVersion
|
|
|
|
func (v SoftwareVersion) Major() uint16 {
|
|
return SemanticVersion(v).Major()
|
|
}
|
|
func (v SoftwareVersion) Minor() uint16 {
|
|
return SemanticVersion(v).Minor()
|
|
}
|
|
|
|
func (v SoftwareVersion) String() string {
|
|
return SemanticVersion(v).String()
|
|
}
|
|
|
|
const SupportedProtocolVersion = ProtocolVersion_1_2
|
|
|
|
const CurrentSoftwareVersionMajor = 3 & 0xFFFF
|
|
const CurrentSoftwareVersionMinor = 6 & 0xFFFF
|
|
|
|
const CurrentSoftwareVersion SoftwareVersion = (CurrentSoftwareVersionMajor << 16) | CurrentSoftwareVersionMinor
|
|
const CurrentSoftwareId = SoftwareIdGoObserver
|
|
|
|
type SoftwareId uint32
|
|
|
|
func (c SoftwareId) String() string {
|
|
switch c {
|
|
case SoftwareIdP2Pool:
|
|
return "P2Pool"
|
|
case SoftwareIdGoObserver:
|
|
return "GoObserver"
|
|
default:
|
|
var buf = [17]byte{'U', 'n', 'k', 'n', 'o', 'w', 'n', '(', 0, 0, 0, 0, 0, 0, 0, 0, ')'}
|
|
var intBuf [4]byte
|
|
binary.LittleEndian.PutUint32(intBuf[:], uint32(c))
|
|
fasthex.Encode(buf[8:], intBuf[:])
|
|
return string(buf[:])
|
|
}
|
|
}
|
|
|
|
const (
|
|
SoftwareIdP2Pool SoftwareId = 0x00000000
|
|
SoftwareIdGoObserver SoftwareId = 0x624F6F47 //GoOb, little endian
|
|
)
|