mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-16 18:37:51 +01:00
Send Announcement instead of ping in case blockchain info was not refreshed within a certain threshold. This helps to keep the global blockchain cache active, with no additional overhead. Close #78
This commit is contained in:
@@ -26,6 +26,26 @@ func (peer *PeerInfo) pingConnection(connection *Connection) {
|
||||
}
|
||||
}
|
||||
|
||||
// pingConnectionAnnouncement sends an empty announcement via a particular connection.
|
||||
// It has the same effect as ping, but returns the blockchain version and height of the other peer in the Response message, which may be useful for keeping the global blockchain cache up to date.
|
||||
func (peer *PeerInfo) pingConnectionAnnouncement(connection *Connection) {
|
||||
_, blockchainHeight, blockchainVersion := UserBlockchain.Header()
|
||||
packets := protocol.EncodeAnnouncement(false, false, nil, nil, nil, FeatureSupport(), blockchainHeight, blockchainVersion, userAgent)
|
||||
if len(packets) != 1 {
|
||||
return
|
||||
}
|
||||
|
||||
raw := &protocol.PacketRaw{Command: protocol.CommandAnnouncement, Payload: packets[0], Sequence: networks.Sequences.NewSequence(peer.PublicKey, &peer.messageSequence, nil).SequenceNumber}
|
||||
Filters.MessageOutAnnouncement(peer.PublicKey, peer, raw, false, nil, nil, nil)
|
||||
|
||||
err := peer.sendConnection(raw, connection)
|
||||
connection.LastPingOut = time.Now()
|
||||
|
||||
if (connection.Status == ConnectionActive || connection.Status == ConnectionRedundant) && IsNetworkErrorFatal(err) {
|
||||
peer.invalidateActiveConnection(connection)
|
||||
}
|
||||
}
|
||||
|
||||
// Ping sends a ping. This function exists only for debugging purposes, it should not be used normally.
|
||||
// This ping is not used for uptime detection and the LastPingOut time in connections is not set.
|
||||
func (peer *PeerInfo) Ping() {
|
||||
|
||||
@@ -180,6 +180,7 @@ func (nets *Networks) packetWorker() {
|
||||
isBlockchainUpdate := peer.BlockchainHeight != announce.BlockchainHeight || peer.BlockchainVersion != announce.BlockchainVersion
|
||||
peer.BlockchainHeight = announce.BlockchainHeight
|
||||
peer.BlockchainVersion = announce.BlockchainVersion
|
||||
peer.blockchainLastRefresh = time.Now()
|
||||
|
||||
Filters.MessageIn(peer, raw, announce)
|
||||
|
||||
@@ -215,6 +216,7 @@ func (nets *Networks) packetWorker() {
|
||||
isBlockchainUpdate := peer.BlockchainHeight != response.BlockchainHeight || peer.BlockchainVersion != response.BlockchainVersion
|
||||
peer.BlockchainHeight = response.BlockchainHeight
|
||||
peer.BlockchainVersion = response.BlockchainVersion
|
||||
peer.blockchainLastRefresh = time.Now()
|
||||
|
||||
Filters.MessageIn(peer, raw, response)
|
||||
|
||||
@@ -235,6 +237,7 @@ func (nets *Networks) packetWorker() {
|
||||
isBlockchainUpdate := peer.BlockchainHeight != announce.BlockchainHeight || peer.BlockchainVersion != announce.BlockchainVersion
|
||||
peer.BlockchainHeight = announce.BlockchainHeight
|
||||
peer.BlockchainVersion = announce.BlockchainVersion
|
||||
peer.blockchainLastRefresh = time.Now()
|
||||
|
||||
Filters.MessageIn(peer, raw, announce)
|
||||
|
||||
|
||||
32
Peer ID.go
32
Peer ID.go
@@ -13,6 +13,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/PeernetOfficial/core/btcec"
|
||||
"github.com/PeernetOfficial/core/dht"
|
||||
@@ -87,21 +88,22 @@ func SelfUserAgent() string {
|
||||
|
||||
// PeerInfo stores information about a single remote peer
|
||||
type PeerInfo struct {
|
||||
PublicKey *btcec.PublicKey // Public key
|
||||
NodeID []byte // Node ID in Kademlia network = blake3(Public Key).
|
||||
connectionActive []*Connection // List of active established connections to the peer.
|
||||
connectionInactive []*Connection // List of former connections that are no longer valid. They may be removed after a while.
|
||||
connectionLatest *Connection // Latest valid connection.
|
||||
sync.RWMutex // Mutex for access to list of connections.
|
||||
messageSequence uint32 // Sequence number. Increased with every message.
|
||||
IsRootPeer bool // Whether the peer is a trusted root peer.
|
||||
UserAgent string // User Agent reported by remote peer. Empty if no Announcement/Response message was yet received.
|
||||
Features uint8 // Feature bit array. 0 = IPv4_LISTEN, 1 = IPv6_LISTEN, 1 = FIREWALL
|
||||
isVirtual bool // Whether it is a virtual peer for establishing a connection.
|
||||
targetAddresses []*peerAddress // Virtual peer: Addresses to send any replies.
|
||||
traversePeer *PeerInfo // Virtual peer: Same field as in connection.
|
||||
BlockchainHeight uint64 // Blockchain height
|
||||
BlockchainVersion uint64 // Blockchain version
|
||||
PublicKey *btcec.PublicKey // Public key
|
||||
NodeID []byte // Node ID in Kademlia network = blake3(Public Key).
|
||||
connectionActive []*Connection // List of active established connections to the peer.
|
||||
connectionInactive []*Connection // List of former connections that are no longer valid. They may be removed after a while.
|
||||
connectionLatest *Connection // Latest valid connection.
|
||||
sync.RWMutex // Mutex for access to list of connections.
|
||||
messageSequence uint32 // Sequence number. Increased with every message.
|
||||
IsRootPeer bool // Whether the peer is a trusted root peer.
|
||||
UserAgent string // User Agent reported by remote peer. Empty if no Announcement/Response message was yet received.
|
||||
Features uint8 // Feature bit array. 0 = IPv4_LISTEN, 1 = IPv6_LISTEN, 1 = FIREWALL
|
||||
isVirtual bool // Whether it is a virtual peer for establishing a connection.
|
||||
targetAddresses []*peerAddress // Virtual peer: Addresses to send any replies.
|
||||
traversePeer *PeerInfo // Virtual peer: Same field as in connection.
|
||||
BlockchainHeight uint64 // Blockchain height
|
||||
BlockchainVersion uint64 // Blockchain version
|
||||
blockchainLastRefresh time.Time // Last refresh of the blockchain info.
|
||||
|
||||
// statistics
|
||||
StatsPacketSent uint64 // Count of packets sent
|
||||
|
||||
16
Ping.go
16
Ping.go
@@ -6,11 +6,17 @@ Author: Peter Kleissner
|
||||
|
||||
package core
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// pingTime is the time in seconds to send out ping messages
|
||||
const pingTime = 10
|
||||
|
||||
// thresholdBlockchainRefresh is the threshold to refresh the blockchain information by sending an Announcement (and expecting the Response message).
|
||||
// This helps for keeping the global blockchain cache up to date.
|
||||
const thresholdBlockchainRefresh = 60 * time.Second
|
||||
|
||||
// connectionInvalidate is the threshold in seconds to invalidate formerly active connections that no longer receive incoming packets.
|
||||
const connectionInvalidate = 22
|
||||
|
||||
@@ -25,6 +31,7 @@ func autoPingAll() {
|
||||
thresholdInvalidate2 := time.Now().Add(-connectionInvalidate * time.Second * 4)
|
||||
thresholdPingOut1 := time.Now().Add(-pingTime * time.Second)
|
||||
thresholdPingOut2 := time.Now().Add(-pingTime * time.Second * 4)
|
||||
thresholdBlockchainRefresh := time.Now().Add(-thresholdBlockchainRefresh)
|
||||
|
||||
for _, peer := range PeerlistGet() {
|
||||
// first handle active connections
|
||||
@@ -43,7 +50,12 @@ func autoPingAll() {
|
||||
}
|
||||
|
||||
if connection.LastPacketIn.Before(thresholdPing) && connection.LastPingOut.Before(thresholdPing) {
|
||||
peer.pingConnection(connection)
|
||||
if connection.Status == ConnectionActive && peer.blockchainLastRefresh.Before(thresholdBlockchainRefresh) {
|
||||
peer.pingConnectionAnnouncement(connection)
|
||||
} else {
|
||||
// just a regular ping otherwise
|
||||
peer.pingConnection(connection)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,8 @@ func DecodeResponse(msg *MessageRaw) (result *MessageResponse, err error) {
|
||||
read += 6
|
||||
|
||||
if countPeerResponses == 0 && countEmbeddedFiles == 0 && countHashesNotFound == 0 {
|
||||
return nil, errors.New("response: empty")
|
||||
// Empty responses are allowed. They can be useful as quasi-pings to get the latest blockchain info of the peer.
|
||||
return
|
||||
}
|
||||
|
||||
data := msg.Payload[read:]
|
||||
|
||||
Reference in New Issue
Block a user