Check capabilities of own server before sending anything that requires it
This commit is contained in:
parent
d52710eea4
commit
f49f52a853
|
@ -472,7 +472,7 @@ func (c *Client) OnConnection() {
|
|||
}
|
||||
}
|
||||
|
||||
if block != nil && c.VersionInformation.SupportsFeature(p2pooltypes.FeatureBlockNotify) {
|
||||
if block != nil && c.Owner.VersionInformation().SupportsFeature(p2pooltypes.FeatureBlockNotify) && c.VersionInformation.SupportsFeature(p2pooltypes.FeatureBlockNotify) {
|
||||
c.SendBlockNotify(block.Side.Parent)
|
||||
for _, uncleId := range block.Side.Uncles {
|
||||
c.SendBlockNotify(uncleId)
|
||||
|
@ -694,12 +694,13 @@ func (c *Client) OnConnection() {
|
|||
}
|
||||
}
|
||||
|
||||
if c.LastIncomingPeerListRequestTime.IsZero() {
|
||||
// Check whether to send version to target or not
|
||||
if c.LastIncomingPeerListRequestTime.IsZero() && c.Owner.VersionInformation().SupportsFeature(p2pooltypes.FeaturePeerInformationExchange) && c.VersionInformation.SupportsFeature(p2pooltypes.FeaturePeerInformationReceive) {
|
||||
//first, send version / protocol information
|
||||
if len(entriesToSend) == 0 {
|
||||
entriesToSend = append(entriesToSend, c.Owner.versionInformation.ToAddrPort())
|
||||
entriesToSend = append(entriesToSend, c.Owner.VersionInformation().ToAddrPort())
|
||||
} else {
|
||||
entriesToSend[0] = c.Owner.versionInformation.ToAddrPort()
|
||||
entriesToSend[0] = c.Owner.VersionInformation().ToAddrPort()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -796,28 +796,39 @@ func (s *Server) MainChain() *mainchain.MainChain {
|
|||
func (s *Server) Broadcast(block *sidechain.PoolBlock) {
|
||||
var message, prunedMessage, compactMessage *ClientMessage
|
||||
if block != nil {
|
||||
blockData, err := block.AppendBinaryFlags(make([]byte, 0, block.BufferLength()), false, false)
|
||||
// Full block broadcast
|
||||
buffer := make([]byte, 4, block.BufferLength()+4)
|
||||
blockData, err := block.AppendBinaryFlags(buffer, false, false)
|
||||
if err != nil {
|
||||
log.Panicf("[P2PServer] Tried to broadcast block %s at height %d but received error: %s", block.SideTemplateId(s.Consensus()), block.Side.Height, err)
|
||||
return
|
||||
}
|
||||
binary.LittleEndian.PutUint32(blockData, uint32(len(blockData)-4))
|
||||
message = &ClientMessage{
|
||||
MessageId: MessageBlockBroadcast,
|
||||
Buffer: append(binary.LittleEndian.AppendUint32(make([]byte, 0, len(blockData)+4), uint32(len(blockData))), blockData...),
|
||||
Buffer: blockData,
|
||||
}
|
||||
prunedBlockData, _ := block.AppendBinaryFlags(make([]byte, 0, block.BufferLength()), true, false)
|
||||
|
||||
// Pruned block broadcast
|
||||
prunedBuffer := make([]byte, 4, block.BufferLength()+4)
|
||||
prunedBlockData, _ := block.AppendBinaryFlags(prunedBuffer, true, false)
|
||||
binary.LittleEndian.PutUint32(prunedBlockData, uint32(len(prunedBlockData)-4))
|
||||
prunedMessage = &ClientMessage{
|
||||
MessageId: MessageBlockBroadcast,
|
||||
Buffer: append(binary.LittleEndian.AppendUint32(make([]byte, 0, len(prunedBlockData)+4), uint32(len(prunedBlockData))), prunedBlockData...),
|
||||
Buffer: prunedBlockData,
|
||||
}
|
||||
compactBlockData, _ := block.AppendBinaryFlags(make([]byte, 0, block.BufferLength()), true, true)
|
||||
|
||||
// Compact block broadcast
|
||||
compactBuffer := make([]byte, 4, block.BufferLength()+4)
|
||||
compactBlockData, _ := block.AppendBinaryFlags(compactBuffer, true, true)
|
||||
binary.LittleEndian.PutUint32(compactBlockData, uint32(len(compactBlockData)-4))
|
||||
if len(compactBlockData) >= len(prunedBlockData) {
|
||||
//do not send compact if it ends up larger due to some reason, like parent missing or mismatch in transactions
|
||||
compactMessage = prunedMessage
|
||||
} else {
|
||||
compactMessage = &ClientMessage{
|
||||
prunedMessage = &ClientMessage{
|
||||
MessageId: MessageBlockBroadcastCompact,
|
||||
Buffer: append(binary.LittleEndian.AppendUint32(make([]byte, 0, len(compactBlockData)+4), uint32(len(compactBlockData))), compactBlockData...),
|
||||
Buffer: compactBlockData,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -828,6 +839,16 @@ func (s *Server) Broadcast(block *sidechain.PoolBlock) {
|
|||
prunedMessage, compactMessage = message, message
|
||||
}
|
||||
|
||||
if !s.versionInformation.SupportsFeature(p2pooltypes.FeaturePrunedBroadcast) {
|
||||
prunedMessage = message
|
||||
}
|
||||
|
||||
if !s.versionInformation.SupportsFeature(p2pooltypes.FeatureCompactBroadcast) {
|
||||
compactMessage = prunedMessage
|
||||
}
|
||||
|
||||
supportsNotify := s.versionInformation.SupportsFeature(p2pooltypes.FeatureBlockNotify)
|
||||
|
||||
blockTemplateId := block.SideTemplateId(s.Consensus())
|
||||
|
||||
go func() {
|
||||
|
@ -849,17 +870,19 @@ func (s *Server) Broadcast(block *sidechain.PoolBlock) {
|
|||
|
||||
// has peer broadcasted this block to us?
|
||||
if slices.Index(broadcastedHashes, blockTemplateId) != -1 &&
|
||||
c.VersionInformation.SupportsFeature(p2pooltypes.FeatureBlockNotify) {
|
||||
supportsNotify && c.VersionInformation.SupportsFeature(p2pooltypes.FeatureBlockNotify) {
|
||||
c.SendBlockNotify(blockTemplateId)
|
||||
return true
|
||||
}
|
||||
|
||||
if c.VersionInformation.SupportsFeature(p2pooltypes.FeatureCompactBroadcast) {
|
||||
c.SendMessage(compactMessage)
|
||||
} else {
|
||||
return true
|
||||
} else if c.VersionInformation.SupportsFeature(p2pooltypes.FeaturePrunedBroadcast) {
|
||||
c.SendMessage(prunedMessage)
|
||||
return true
|
||||
}
|
||||
return true
|
||||
return false
|
||||
}() {
|
||||
//fallback
|
||||
c.SendMessage(message)
|
||||
|
|
|
@ -3,6 +3,7 @@ package types
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
)
|
||||
|
@ -15,10 +16,16 @@ func IsPeerVersionInformation(addr netip.AddrPort) bool {
|
|||
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 (
|
||||
FeatureCompactBroadcast = ProtocolFeature(iota)
|
||||
// FeaturePeerInformationReceive Backwards compatible, can be sent to all clients
|
||||
FeaturePeerInformationReceive = ProtocolFeature(iota)
|
||||
FeaturePeerInformationExchange
|
||||
FeaturePrunedBroadcast
|
||||
FeatureCompactBroadcast
|
||||
FeatureBlockNotify
|
||||
)
|
||||
|
||||
|
@ -30,6 +37,12 @@ type PeerVersionInformation struct {
|
|||
|
||||
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:
|
||||
|
@ -40,6 +53,11 @@ func (i *PeerVersionInformation) SupportsFeature(feature ProtocolFeature) bool {
|
|||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
|
@ -100,7 +118,11 @@ func (c SoftwareId) String() string {
|
|||
case SoftwareIdGoObserver:
|
||||
return "GoObserver"
|
||||
default:
|
||||
return fmt.Sprintf("Unknown(%08x)", uint32(c))
|
||||
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))
|
||||
hex.Encode(buf[8:], intBuf[:])
|
||||
return string(buf[:])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue