Refactor message encoding into protocol package. User Agent must be now provided in the Init function.

This commit is contained in:
Kleissner
2021-10-18 04:37:02 +02:00
parent f1e8e0cab8
commit c9d9be2972
15 changed files with 149 additions and 142 deletions

View File

@@ -208,7 +208,7 @@ func (nets *Networks) autoMulticastBroadcast() {
func contactArbitraryPeer(publicKey *btcec.PublicKey, address *net.UDPAddr, receiverPortInternal uint16) (contacted bool) {
findSelf := ShouldSendFindSelf()
_, blockchainHeight, blockchainVersion := UserBlockchain.Header()
packets := EncodeAnnouncement(true, findSelf, nil, nil, nil, FeatureSupport(), blockchainHeight, blockchainVersion)
packets := protocol.EncodeAnnouncement(true, findSelf, nil, nil, nil, FeatureSupport(), blockchainHeight, blockchainVersion, userAgent)
if len(packets) == 0 {
return false
}
@@ -230,13 +230,13 @@ type bootstrapFindSelf struct {
const bootstrapAcceptContacts = 5
// cmdResponseBootstrapFindSelf processes FIND_SELF responses
func (peer *PeerInfo) cmdResponseBootstrapFindSelf(msg *MessageResponse, closest []PeerRecord) {
func (peer *PeerInfo) cmdResponseBootstrapFindSelf(msg *protocol.MessageResponse, closest []protocol.PeerRecord) {
if len(closest) > bootstrapAcceptContacts {
closest = closest[:bootstrapAcceptContacts]
}
for _, closePeer := range closest {
if IsReturnedPeerBadQuality(&closePeer) {
if isReturnedPeerBadQuality(&closePeer) {
continue
}
@@ -246,12 +246,12 @@ func (peer *PeerInfo) cmdResponseBootstrapFindSelf(msg *MessageResponse, closest
}
// Check if the reported peer was recently contacted (in connection with the origin peer) for bootstrapping. This makes sure inactive peers are not contacted over and over again.
recent, blacklisted := closePeer.IsRecent(peer.NodeID)
recent, blacklisted := isReturnedPeerRecent(&closePeer, peer.NodeID)
if blacklisted {
continue
}
for _, address := range closePeer.ToAddresses() {
for _, address := range peerRecordToAddresses(&closePeer) {
// Check if the specific IP:Port was already contacted in the last 5-10 minutes.
if recent.IsAddressContacted(address) {
continue
@@ -269,8 +269,8 @@ func ShouldSendFindSelf() bool {
return true
}
// IsReturnedPeerBadQuality checks if the returned peer record is bad quality and should be discarded
func IsReturnedPeerBadQuality(record *PeerRecord) bool {
// isReturnedPeerBadQuality checks if the returned peer record is bad quality and should be discarded
func isReturnedPeerBadQuality(record *protocol.PeerRecord) bool {
isIPv4 := record.IPv4 != nil && !record.IPv4.IsUnspecified()
isIPv6 := record.IPv6 != nil && !record.IPv6.IsUnspecified()
@@ -294,8 +294,8 @@ func IsReturnedPeerBadQuality(record *PeerRecord) bool {
return false
}
// ToAddresses returns the addresses in a usable way
func (record *PeerRecord) ToAddresses() (addresses []*peerAddress) {
// peerRecordToAddresses returns the addresses in a usable way
func peerRecordToAddresses(record *protocol.PeerRecord) (addresses []*peerAddress) {
// IPv4
ipv4Port := record.IPv4Port
if record.IPv4PortReportedExternal > 0 { // Use the external port if available
@@ -352,8 +352,8 @@ func resetRecentContacts() {
}
}
// IsRecent checks if the peer is blacklisted related to the origin peer due to recent contact. It will create a "recent contact" if none exists.
func (record *PeerRecord) IsRecent(originNodeID []byte) (recent *recentContactInfo, blacklisted bool) {
// isReturnedPeerRecent checks if the peer is blacklisted related to the origin peer due to recent contact. It will create a "recent contact" if none exists.
func isReturnedPeerRecent(record *protocol.PeerRecord, originNodeID []byte) (recent *recentContactInfo, blacklisted bool) {
key := publicKey2Compressed(record.PublicKey)
recentContactsMutex.Lock()

View File

@@ -15,7 +15,7 @@ import (
)
// cmdTraverseForward handles an incoming traverse message that should be forwarded to another peer
func (peer *PeerInfo) cmdTraverseForward(msg *MessageTraverse) {
func (peer *PeerInfo) cmdTraverseForward(msg *protocol.MessageTraverse) {
// Verify the signature. This makes sure that a fowarded message cannot be replayed by others.
if !msg.SignerPublicKey.IsEqual(peer.PublicKey) || !msg.SignerPublicKey.IsEqual(msg.SenderPublicKey) {
return
@@ -35,8 +35,8 @@ func (peer *PeerInfo) cmdTraverseForward(msg *MessageTraverse) {
}
// Get the right IP:Port of the original sender to share to the target peer.
allowIPv4 := peerTarget.Features&(1<<FeatureIPv4Listen) > 0
allowIPv6 := peerTarget.Features&(1<<FeatureIPv6Listen) > 0
allowIPv4 := peerTarget.Features&(1<<protocol.FeatureIPv4Listen) > 0
allowIPv6 := peerTarget.Features&(1<<protocol.FeatureIPv6Listen) > 0
connectionIPv4 := peer.GetConnection2Share(false, allowIPv4, false)
connectionIPv6 := peer.GetConnection2Share(false, false, allowIPv6)
@@ -58,14 +58,14 @@ func (peer *PeerInfo) cmdTraverseForward(msg *MessageTraverse) {
PortIPv6ReportedExternal = connectionIPv6.PortExternal
}
if err := msgEncodeTraverseSetAddress(msg.Payload, IPv4, PortIPv4, PortIPv4ReportedExternal, IPv6, PortIPv6, PortIPv6ReportedExternal); err != nil {
if err := protocol.EncodeTraverseSetAddress(msg.Payload, IPv4, PortIPv4, PortIPv4ReportedExternal, IPv6, PortIPv6, PortIPv6ReportedExternal); err != nil {
return
}
peerTarget.send(&protocol.PacketRaw{Command: protocol.CommandTraverse, Payload: msg.Payload})
}
func (peer *PeerInfo) cmdTraverseReceive(msg *MessageTraverse) {
func (peer *PeerInfo) cmdTraverseReceive(msg *protocol.MessageTraverse) {
if msg.Expires.Before(time.Now()) {
return
}
@@ -114,13 +114,13 @@ func (peer *PeerInfo) cmdTraverseReceive(msg *MessageTraverse) {
}
// process the packet and create a virtual peer
raw := &MessageRaw{SenderPublicKey: senderPublicKey, PacketRaw: *decoded}
raw := &protocol.MessageRaw{SenderPublicKey: senderPublicKey, PacketRaw: *decoded}
peerV := &PeerInfo{PublicKey: senderPublicKey, connectionActive: nil, connectionLatest: nil, NodeID: protocol.PublicKey2NodeID(senderPublicKey), messageSequence: rand.Uint32(), isVirtual: true, targetAddresses: addresses}
// process it!
switch decoded.Command {
case protocol.CommandAnnouncement: // Announce
if announce, _ := msgDecodeAnnouncement(raw); announce != nil {
if announce, _ := protocol.DecodeAnnouncement(raw); announce != nil {
if len(announce.UserAgent) > 0 {
peerV.UserAgent = announce.UserAgent
}

View File

@@ -20,7 +20,7 @@ import (
const respondClosesContactsCount = 5
// cmdAnouncement handles an incoming announcement. Connection may be nil for traverse relayed messages.
func (peer *PeerInfo) cmdAnouncement(msg *MessageAnnouncement, connection *Connection) {
func (peer *PeerInfo) cmdAnouncement(msg *protocol.MessageAnnouncement, connection *Connection) {
// Filter function to only share peers that are "connectable" to the remote one. It checks IPv4, IPv6, and local connection.
filterFunc := func(allowLocal, allowIPv4, allowIPv6 bool) dht.NodeFilterFunc {
return func(node *dht.Node) (accept bool) {
@@ -28,18 +28,18 @@ func (peer *PeerInfo) cmdAnouncement(msg *MessageAnnouncement, connection *Conne
}
}
allowIPv4 := msg.Features&(1<<FeatureIPv4Listen) > 0
allowIPv6 := msg.Features&(1<<FeatureIPv6Listen) > 0
allowIPv4 := msg.Features&(1<<protocol.FeatureIPv4Listen) > 0
allowIPv6 := msg.Features&(1<<protocol.FeatureIPv6Listen) > 0
var hash2Peers []Hash2Peer
var hash2Peers []protocol.Hash2Peer
var hashesNotFound [][]byte
var filesEmbed []EmbeddedFileData
var filesEmbed []protocol.EmbeddedFileData
// FIND_SELF: Requesting peers close to the sender?
if msg.Actions&(1<<ActionFindSelf) > 0 {
Filters.IncomingRequest(peer, ActionFindSelf, peer.NodeID, nil)
if msg.Actions&(1<<protocol.ActionFindSelf) > 0 {
Filters.IncomingRequest(peer, protocol.ActionFindSelf, peer.NodeID, nil)
selfD := Hash2Peer{ID: KeyHash{peer.NodeID}}
selfD := protocol.Hash2Peer{ID: protocol.KeyHash{Hash: peer.NodeID}}
// do not respond the caller's own peer (add to ignore list)
for _, node := range nodesDHT.GetClosestContacts(respondClosesContactsCount, peer.NodeID, filterFunc(connection.IsLocal(), allowIPv4, allowIPv6), peer.NodeID) {
@@ -56,11 +56,11 @@ func (peer *PeerInfo) cmdAnouncement(msg *MessageAnnouncement, connection *Conne
}
// FIND_PEER: Find a different peer?
if msg.Actions&(1<<ActionFindPeer) > 0 && len(msg.FindPeerKeys) > 0 {
if msg.Actions&(1<<protocol.ActionFindPeer) > 0 && len(msg.FindPeerKeys) > 0 {
for _, findPeer := range msg.FindPeerKeys {
Filters.IncomingRequest(peer, ActionFindPeer, findPeer.Hash, nil)
Filters.IncomingRequest(peer, protocol.ActionFindPeer, findPeer.Hash, nil)
details := Hash2Peer{ID: findPeer}
details := protocol.Hash2Peer{ID: findPeer}
// Same as before, put self as ignoredNodes.
for _, node := range nodesDHT.GetClosestContacts(respondClosesContactsCount, findPeer.Hash, filterFunc(connection.IsLocal(), allowIPv4, allowIPv6), peer.NodeID) {
@@ -78,16 +78,16 @@ func (peer *PeerInfo) cmdAnouncement(msg *MessageAnnouncement, connection *Conne
}
// Find a value?
if msg.Actions&(1<<ActionFindValue) > 0 {
if msg.Actions&(1<<protocol.ActionFindValue) > 0 {
for _, findHash := range msg.FindDataKeys {
Filters.IncomingRequest(peer, ActionFindValue, findHash.Hash, nil)
Filters.IncomingRequest(peer, protocol.ActionFindValue, findHash.Hash, nil)
stored, data := announcementGetData(findHash.Hash)
if stored && len(data) > 0 {
filesEmbed = append(filesEmbed, EmbeddedFileData{ID: findHash, Data: data})
filesEmbed = append(filesEmbed, protocol.EmbeddedFileData{ID: findHash, Data: data})
} else if stored {
selfRecord := selfPeerRecord()
hash2Peers = append(hash2Peers, Hash2Peer{ID: findHash, Storing: []PeerRecord{selfRecord}})
hash2Peers = append(hash2Peers, protocol.Hash2Peer{ID: findHash, Storing: []protocol.PeerRecord{selfRecord}})
} else {
hashesNotFound = append(hashesNotFound, findHash.Hash)
}
@@ -95,9 +95,9 @@ func (peer *PeerInfo) cmdAnouncement(msg *MessageAnnouncement, connection *Conne
}
// Information about files stored by the sender?
if msg.Actions&(1<<ActionInfoStore) > 0 && len(msg.InfoStoreFiles) > 0 {
if msg.Actions&(1<<protocol.ActionInfoStore) > 0 && len(msg.InfoStoreFiles) > 0 {
for n := range msg.InfoStoreFiles {
Filters.IncomingRequest(peer, ActionInfoStore, msg.InfoStoreFiles[n].ID.Hash, &msg.InfoStoreFiles[n])
Filters.IncomingRequest(peer, protocol.ActionInfoStore, msg.InfoStoreFiles[n].ID.Hash, &msg.InfoStoreFiles[n])
}
peer.announcementStore(msg.InfoStoreFiles)
@@ -107,14 +107,14 @@ func (peer *PeerInfo) cmdAnouncement(msg *MessageAnnouncement, connection *Conne
peer.sendResponse(msg.Sequence, sendUA, hash2Peers, filesEmbed, hashesNotFound)
}
func (peer *PeerInfo) peer2Record(allowLocal, allowIPv4, allowIPv6 bool) (result *PeerRecord) {
func (peer *PeerInfo) peer2Record(allowLocal, allowIPv4, allowIPv6 bool) (result *protocol.PeerRecord) {
connectionIPv4 := peer.GetConnection2Share(allowLocal, allowIPv4, false)
connectionIPv6 := peer.GetConnection2Share(allowLocal, false, allowIPv6)
if connectionIPv4 == nil && connectionIPv6 == nil {
return nil
}
result = &PeerRecord{
result = &protocol.PeerRecord{
PublicKey: peer.PublicKey,
NodeID: peer.NodeID,
}
@@ -137,7 +137,7 @@ func (peer *PeerInfo) peer2Record(allowLocal, allowIPv4, allowIPv6 bool) (result
}
// cmdResponse handles the response to the announcement
func (peer *PeerInfo) cmdResponse(msg *MessageResponse, connection *Connection) {
func (peer *PeerInfo) cmdResponse(msg *protocol.MessageResponse, connection *Connection) {
// The sequence data is used to correlate this response with the announcement.
if msg.SequenceInfo == nil || msg.SequenceInfo.Data == nil {
// If there is no sequence data but there were results returned, it means we received unsolicited response data. It will be rejected.
@@ -191,7 +191,7 @@ func (peer *PeerInfo) cmdResponse(msg *MessageResponse, connection *Connection)
}
// cmdPing handles an incoming ping message
func (peer *PeerInfo) cmdPing(msg *MessageRaw, connection *Connection) {
func (peer *PeerInfo) cmdPing(msg *protocol.MessageRaw, connection *Connection) {
// If PortInternal is 0, it means no incoming announcement or response message was received on that connection.
// This means the ping is unexpected. In that case for security reasons the remote peer is not asked for FIND_SELF.
if connection.PortInternal == 0 {
@@ -207,16 +207,16 @@ func (peer *PeerInfo) cmdPing(msg *MessageRaw, connection *Connection) {
}
// cmdPong handles an incoming pong message
func (peer *PeerInfo) cmdPong(msg *MessageRaw, connection *Connection) {
func (peer *PeerInfo) cmdPong(msg *protocol.MessageRaw, connection *Connection) {
}
// cmdChat handles a chat message [debug]
func (peer *PeerInfo) cmdChat(msg *MessageRaw, connection *Connection) {
func (peer *PeerInfo) cmdChat(msg *protocol.MessageRaw, connection *Connection) {
fmt.Printf("Chat from '%s': %s\n", connection.Address.String(), string(msg.PacketRaw.Payload))
}
// cmdLocalDiscovery handles an incoming announcement via local discovery
func (peer *PeerInfo) cmdLocalDiscovery(msg *MessageAnnouncement, connection *Connection) {
func (peer *PeerInfo) cmdLocalDiscovery(msg *protocol.MessageAnnouncement, connection *Connection) {
// 21.04.2021 update: Local peer discovery from public IPv4s is possible in datacenter situations. Keep it enabled for now.
// only accept local discovery message from private IPs for IPv4
// IPv6 DHCP routers typically assign public IPv6s and they can join multicast in the local network.

View File

@@ -325,7 +325,7 @@ func (c *Connection) send(packet *protocol.PacketRaw, receiverPublicKey *btcec.P
return errors.New("invalid connection")
}
packet.Protocol = ProtocolVersion
packet.Protocol = protocol.ProtocolVersion
packet.SetSelfReportedPorts(c.Network.SelfReportedPorts())
Filters.PacketOut(packet, receiverPublicKey, c)

View File

@@ -45,14 +45,14 @@ var Filters struct {
PacketOut func(packet *protocol.PacketRaw, receiverPublicKey *btcec.PublicKey, connection *Connection)
// MessageIn is a high-level filter for decoded incoming messages. message is of type nil, MessageAnnouncement, MessageResponse, or MessageTraverse
MessageIn func(peer *PeerInfo, raw *MessageRaw, message interface{})
MessageIn func(peer *PeerInfo, raw *protocol.MessageRaw, message interface{})
// MessageOutAnnouncement is a high-level filter for outgoing announcements. Peer is nil on first contact.
// Broadcast and Multicast messages are not covered.
MessageOutAnnouncement func(receiverPublicKey *btcec.PublicKey, peer *PeerInfo, packet *protocol.PacketRaw, findSelf bool, findPeer []KeyHash, findValue []KeyHash, files []InfoStore)
MessageOutAnnouncement func(receiverPublicKey *btcec.PublicKey, peer *PeerInfo, packet *protocol.PacketRaw, findSelf bool, findPeer []protocol.KeyHash, findValue []protocol.KeyHash, files []protocol.InfoStore)
// MessageOutResponse is a high-level filter for outgoing responses.
MessageOutResponse func(peer *PeerInfo, packet *protocol.PacketRaw, hash2Peers []Hash2Peer, filesEmbed []EmbeddedFileData, hashesNotFound [][]byte)
MessageOutResponse func(peer *PeerInfo, packet *protocol.PacketRaw, hash2Peers []protocol.Hash2Peer, filesEmbed []protocol.EmbeddedFileData, hashesNotFound [][]byte)
// MessageOutTraverse is a high-level filter for outgoing traverse messages.
MessageOutTraverse func(peer *PeerInfo, packet *protocol.PacketRaw, embeddedPacket *protocol.PacketRaw, receiverEnd *btcec.PublicKey)
@@ -90,14 +90,14 @@ func initFilters() {
Filters.PacketOut = func(packet *protocol.PacketRaw, receiverPublicKey *btcec.PublicKey, c *Connection) {}
}
if Filters.MessageIn == nil {
Filters.MessageIn = func(peer *PeerInfo, raw *MessageRaw, message interface{}) {}
Filters.MessageIn = func(peer *PeerInfo, raw *protocol.MessageRaw, message interface{}) {}
}
if Filters.MessageOutAnnouncement == nil {
Filters.MessageOutAnnouncement = func(receiverPublicKey *btcec.PublicKey, peer *PeerInfo, packet *protocol.PacketRaw, findSelf bool, findPeer []KeyHash, findValue []KeyHash, files []InfoStore) {
Filters.MessageOutAnnouncement = func(receiverPublicKey *btcec.PublicKey, peer *PeerInfo, packet *protocol.PacketRaw, findSelf bool, findPeer []protocol.KeyHash, findValue []protocol.KeyHash, files []protocol.InfoStore) {
}
}
if Filters.MessageOutResponse == nil {
Filters.MessageOutResponse = func(peer *PeerInfo, packet *protocol.PacketRaw, hash2Peers []Hash2Peer, filesEmbed []EmbeddedFileData, hashesNotFound [][]byte) {
Filters.MessageOutResponse = func(peer *PeerInfo, packet *protocol.PacketRaw, hash2Peers []protocol.Hash2Peer, filesEmbed []protocol.EmbeddedFileData, hashesNotFound [][]byte) {
}
}
if Filters.MessageOutTraverse == nil {

View File

@@ -105,23 +105,23 @@ func (peer *PeerInfo) sendAnnouncementFindNode(request *dht.InformationRequest)
if bytes.Equal(request.Key, nodeID) {
peer.sendAnnouncement(false, true, nil, nil, nil, request)
} else {
peer.sendAnnouncement(false, false, []KeyHash{{Hash: request.Key}}, nil, nil, request)
peer.sendAnnouncement(false, false, []protocol.KeyHash{{Hash: request.Key}}, nil, nil, request)
}
}
func (peer *PeerInfo) sendAnnouncementFindValue(request *dht.InformationRequest) {
findSelf := false
var findPeer []KeyHash
var findValue []KeyHash
var findPeer []protocol.KeyHash
var findValue []protocol.KeyHash
findValue = append(findValue, KeyHash{Hash: request.Key})
findValue = append(findValue, protocol.KeyHash{Hash: request.Key})
peer.sendAnnouncement(false, findSelf, findPeer, findValue, nil, request)
}
func (peer *PeerInfo) sendAnnouncementStore(fileHash []byte, fileSize uint64) {
peer.sendAnnouncement(false, false, nil, nil, []InfoStore{{ID: KeyHash{Hash: fileHash}, Size: fileSize, Type: 0}}, nil)
peer.sendAnnouncement(false, false, nil, nil, []protocol.InfoStore{{ID: protocol.KeyHash{Hash: fileHash}, Size: fileSize, Type: 0}}, nil)
}
// ---- CORE DATA FUNCTIONS ----

View File

@@ -32,9 +32,9 @@ func (peer *PeerInfo) Chat(text string) {
}
// sendAnnouncement sends the announcement message. It acquires a new sequence for each message.
func (peer *PeerInfo) sendAnnouncement(sendUA, findSelf bool, findPeer []KeyHash, findValue []KeyHash, files []InfoStore, sequenceData interface{}) {
func (peer *PeerInfo) sendAnnouncement(sendUA, findSelf bool, findPeer []protocol.KeyHash, findValue []protocol.KeyHash, files []protocol.InfoStore, sequenceData interface{}) {
_, blockchainHeight, blockchainVersion := UserBlockchain.Header()
packets := EncodeAnnouncement(sendUA, findSelf, findPeer, findValue, files, FeatureSupport(), blockchainHeight, blockchainVersion)
packets := protocol.EncodeAnnouncement(sendUA, findSelf, findPeer, findValue, files, FeatureSupport(), blockchainHeight, blockchainVersion, userAgent)
for _, packet := range packets {
raw := &protocol.PacketRaw{Command: protocol.CommandAnnouncement, Payload: packet, Sequence: networks.Sequences.NewSequence(peer.PublicKey, &peer.messageSequence, sequenceData).SequenceNumber}
@@ -44,9 +44,9 @@ func (peer *PeerInfo) sendAnnouncement(sendUA, findSelf bool, findPeer []KeyHash
}
// sendResponse sends the response message
func (peer *PeerInfo) sendResponse(sequence uint32, sendUA bool, hash2Peers []Hash2Peer, filesEmbed []EmbeddedFileData, hashesNotFound [][]byte) (err error) {
func (peer *PeerInfo) sendResponse(sequence uint32, sendUA bool, hash2Peers []protocol.Hash2Peer, filesEmbed []protocol.EmbeddedFileData, hashesNotFound [][]byte) (err error) {
_, blockchainHeight, blockchainVersion := UserBlockchain.Header()
packets, err := msgEncodeResponse(sendUA, hash2Peers, filesEmbed, hashesNotFound, FeatureSupport(), blockchainHeight, blockchainVersion)
packets, err := protocol.EncodeResponse(sendUA, hash2Peers, filesEmbed, hashesNotFound, FeatureSupport(), blockchainHeight, blockchainVersion, userAgent)
for _, packet := range packets {
raw := &protocol.PacketRaw{Command: protocol.CommandResponse, Payload: packet, Sequence: sequence}
@@ -59,7 +59,7 @@ func (peer *PeerInfo) sendResponse(sequence uint32, sendUA bool, hash2Peers []Ha
// sendTraverse sends a traverse message
func (peer *PeerInfo) sendTraverse(packet *protocol.PacketRaw, receiverEnd *btcec.PublicKey) (err error) {
packet.Protocol = ProtocolVersion
packet.Protocol = protocol.ProtocolVersion
// self-reported ports are not set, as this isn't sent via a specific network but a relay
//packet.SetSelfReportedPorts(c.Network.SelfReportedPorts())
@@ -68,7 +68,7 @@ func (peer *PeerInfo) sendTraverse(packet *protocol.PacketRaw, receiverEnd *btce
return err
}
packetRaw, err := msgEncodeTraverse(peerPrivateKey, embeddedPacketRaw, receiverEnd, peer.PublicKey)
packetRaw, err := protocol.EncodeTraverse(peerPrivateKey, embeddedPacketRaw, receiverEnd, peer.PublicKey)
if err != nil {
return err
}

View File

@@ -92,12 +92,12 @@ func (network *Network) BroadcastIPv4Listen() {
// BroadcastIPv4Send sends out a single broadcast messages to discover peers
func (network *Network) BroadcastIPv4Send() (err error) {
_, blockchainHeight, blockchainVersion := UserBlockchain.Header()
packets := EncodeAnnouncement(true, true, nil, nil, nil, FeatureSupport(), blockchainHeight, blockchainVersion)
packets := protocol.EncodeAnnouncement(true, true, nil, nil, nil, FeatureSupport(), blockchainHeight, blockchainVersion, userAgent)
if len(packets) == 0 {
return errors.New("error encoding broadcast announcement")
}
raw, err := protocol.PacketEncrypt(peerPrivateKey, ipv4BroadcastPublicKey, &protocol.PacketRaw{Protocol: ProtocolVersion, Command: protocol.CommandLocalDiscovery, Payload: packets[0]})
raw, err := protocol.PacketEncrypt(peerPrivateKey, ipv4BroadcastPublicKey, &protocol.PacketRaw{Protocol: protocol.ProtocolVersion, Command: protocol.CommandLocalDiscovery, Payload: packets[0]})
if err != nil {
return err
}

View File

@@ -138,12 +138,12 @@ func (network *Network) MulticastIPv6Listen() {
// MulticastIPv6Send sends out a single multicast messages to discover peers at the same site
func (network *Network) MulticastIPv6Send() (err error) {
_, blockchainHeight, blockchainVersion := UserBlockchain.Header()
packets := EncodeAnnouncement(true, true, nil, nil, nil, FeatureSupport(), blockchainHeight, blockchainVersion)
packets := protocol.EncodeAnnouncement(true, true, nil, nil, nil, FeatureSupport(), blockchainHeight, blockchainVersion, userAgent)
if len(packets) == 0 {
return errors.New("error encoding multicast announcement")
}
raw, err := protocol.PacketEncrypt(peerPrivateKey, ipv6MulticastPublicKey, &protocol.PacketRaw{Protocol: ProtocolVersion, Command: protocol.CommandLocalDiscovery, Payload: packets[0]})
raw, err := protocol.PacketEncrypt(peerPrivateKey, ipv6MulticastPublicKey, &protocol.PacketRaw{Protocol: protocol.ProtocolVersion, Command: protocol.CommandLocalDiscovery, Payload: packets[0]})
if err != nil {
return err
}

View File

@@ -163,11 +163,11 @@ func (nets *Networks) packetWorker() {
connection.LastPacketIn = time.Now()
// process the packet
raw := &MessageRaw{SenderPublicKey: senderPublicKey, PacketRaw: *decoded}
raw := &protocol.MessageRaw{SenderPublicKey: senderPublicKey, PacketRaw: *decoded}
switch decoded.Command {
case protocol.CommandAnnouncement: // Announce
if announce, _ := msgDecodeAnnouncement(raw); announce != nil {
if announce, _ := protocol.DecodeAnnouncement(raw); announce != nil {
// Update known internal/external port and User Agent
connection.PortInternal = announce.PortInternal
connection.PortExternal = announce.PortExternal
@@ -184,9 +184,9 @@ func (nets *Networks) packetWorker() {
}
case protocol.CommandResponse: // Response
if response, _ := msgDecodeResponse(raw); response != nil {
if response, _ := protocol.DecodeResponse(raw); response != nil {
// Validate sequence number which prevents unsolicited responses.
sequenceInfo, valid, rtt := nets.Sequences.ValidateSequence(raw.SenderPublicKey, raw.Sequence, response.Actions&(1<<ActionSequenceLast) > 0, true)
sequenceInfo, valid, rtt := nets.Sequences.ValidateSequence(raw.SenderPublicKey, raw.Sequence, response.Actions&(1<<protocol.ActionSequenceLast) > 0, true)
if !valid {
//Filters.LogError("packetWorker", "message with invalid sequence %d command %d from %s\n", raw.Sequence, raw.Command, raw.connection.Address.String()) // Only log for debug purposes.
continue
@@ -211,7 +211,7 @@ func (nets *Networks) packetWorker() {
}
case protocol.CommandLocalDiscovery: // Local discovery, sent via IPv4 broadcast and IPv6 multicast
if announce, _ := msgDecodeAnnouncement(raw); announce != nil {
if announce, _ := protocol.DecodeAnnouncement(raw); announce != nil {
if len(announce.UserAgent) > 0 {
peer.UserAgent = announce.UserAgent
}
@@ -248,7 +248,7 @@ func (nets *Networks) packetWorker() {
peer.cmdChat(raw, connection)
case protocol.CommandTraverse:
if traverse, _ := msgDecodeTraverse(raw); traverse != nil {
if traverse, _ := protocol.DecodeTraverse(raw); traverse != nil {
Filters.MessageIn(peer, raw, traverse)
if traverse.TargetPeer.IsEqual(peerPublicKey) && traverse.AuthorizedRelayPeer.IsEqual(peer.PublicKey) {
peer.cmdTraverseReceive(traverse)
@@ -337,10 +337,10 @@ func (network *Network) SelfReportedPorts() (portI, portE uint16) {
// FeatureSupport returns supported features by this peer
func FeatureSupport() (feature byte) {
if networks.countListen4 > 0 {
feature |= 1 << FeatureIPv4Listen
feature |= 1 << protocol.FeatureIPv4Listen
}
if networks.countListen6 > 0 {
feature |= 1 << FeatureIPv6Listen
feature |= 1 << protocol.FeatureIPv6Listen
}
return feature
}

View File

@@ -79,6 +79,11 @@ func SelfNodeID() []byte {
return nodeID
}
// SelfUserAgent returns the User Agent
func SelfUserAgent() string {
return userAgent
}
// PeerInfo stores information about a single remote peer
type PeerInfo struct {
PublicKey *btcec.PublicKey // Public key
@@ -179,8 +184,7 @@ func PeerlistLookup(publicKey *btcec.PublicKey) (peer *PeerInfo) {
peerlistMutex.RLock()
defer peerlistMutex.RUnlock()
peer, _ = peerList[publicKey2Compressed(publicKey)]
return peer
return peerList[publicKey2Compressed(publicKey)]
}
// PeerlistCount returns the current count of peers in the peer list
@@ -199,9 +203,9 @@ func publicKey2Compressed(publicKey *btcec.PublicKey) [btcec.PubKeyBytesLenCompr
// records2Nodes translates infoPeer structures to nodes. If the reported nodes are not in the peer table, it will create temporary PeerInfo structures.
// LastContact is passed on in the Node.LastSeen field.
func records2Nodes(records []PeerRecord, peerSource *PeerInfo) (nodes []*dht.Node) {
func records2Nodes(records []protocol.PeerRecord, peerSource *PeerInfo) (nodes []*dht.Node) {
for _, record := range records {
if IsReturnedPeerBadQuality(&record) {
if isReturnedPeerBadQuality(&record) {
continue
}
@@ -212,7 +216,7 @@ func records2Nodes(records []PeerRecord, peerSource *PeerInfo) (nodes []*dht.Nod
} else if peer = PeerlistLookup(record.PublicKey); peer == nil {
// Create temporary peer which is not added to the global list and not added to Kademlia.
// traversePeer is set to the peer who provided the node information.
addresses := record.ToAddresses()
addresses := peerRecordToAddresses(&record)
if len(addresses) == 0 {
continue
}
@@ -227,8 +231,8 @@ func records2Nodes(records []PeerRecord, peerSource *PeerInfo) (nodes []*dht.Nod
}
// selfPeerRecord returns self as peer record
func selfPeerRecord() (result PeerRecord) {
return PeerRecord{
func selfPeerRecord() (result protocol.PeerRecord) {
return protocol.PeerRecord{
PublicKey: peerPublicKey,
NodeID: nodeID,
//IP: network.address.IP,

View File

@@ -6,8 +6,15 @@ Author: Peter Kleissner
package core
var userAgent = "Peernet Core/0.1" // must be overwritten by the caller
// Init initializes the client. The config must be loaded first!
func Init() {
// The User Agent must be provided in the form "Application Name/1.0".
func Init(UserAgent string) {
if userAgent = UserAgent; userAgent == "" {
return
}
initFilters()
initPeerID()
initUserBlockchain()

View File

@@ -7,6 +7,7 @@ Author: Peter Kleissner
package core
import (
"github.com/PeernetOfficial/core/protocol"
"github.com/PeernetOfficial/core/store"
)
@@ -27,7 +28,7 @@ func announcementGetData(hash []byte) (stored bool, data []byte) {
return false, nil
}
if len(data) <= EmbeddedFileSizeMax {
if len(data) <= protocol.EmbeddedFileSizeMax {
return true, data
}
@@ -35,7 +36,7 @@ func announcementGetData(hash []byte) (stored bool, data []byte) {
}
// announcementStore handles an incoming announcement by another peer about storing data
func (peer *PeerInfo) announcementStore(records []InfoStore) {
func (peer *PeerInfo) announcementStore(records []protocol.InfoStore) {
// TODO: Only store the other peers data if certain conditions are met:
// - enough storage available
// - not exceeding record count per peer

View File

@@ -6,7 +6,7 @@ Author: Peter Kleissner
Intermediary between low-level packets and high-level interpretation.
*/
package core
package protocol
import (
"bytes"
@@ -16,16 +16,12 @@ import (
"time"
"unicode/utf8"
"github.com/PeernetOfficial/core/protocol"
"github.com/btcsuite/btcd/btcec"
)
// ProtocolVersion is the current protocol version
const ProtocolVersion = 0
// UserAgent should be set by the caller
var UserAgent = "Peernet Core/0.1"
// Actions between peers, sent via Announcement message. They correspond to the bit array index.
const (
ActionFindSelf = 0 // FIND_SELF Request closest neighbors to self
@@ -47,9 +43,9 @@ const (
// MessageRaw is a high-level message between peers that has not been decoded
type MessageRaw struct {
protocol.PacketRaw
SenderPublicKey *btcec.PublicKey // Sender Public Key, ECDSA (secp256k1) 257-bit
SequenceInfo *protocol.SequenceExpiry // Sequence
PacketRaw
SenderPublicKey *btcec.PublicKey // Sender Public Key, ECDSA (secp256k1) 257-bit
SequenceInfo *SequenceExpiry // Sequence
}
// MessageAnnouncement is the decoded announcement message.
@@ -68,9 +64,6 @@ type MessageAnnouncement struct {
InfoStoreFiles []InfoStore // INFO_STORE data
}
// blake3 digest size in bytes
const hashSize = 32
// KeyHash is a single blake3 key hash
type KeyHash struct {
Hash []byte
@@ -151,8 +144,8 @@ type MessageTraverse struct {
// Minimum length of Announcement payload header without User Agent
const announcementPayloadHeaderSize = 20
// msgDecodeAnnouncement decodes the incoming announcement message. Returns nil if invalid.
func msgDecodeAnnouncement(msg *MessageRaw) (result *MessageAnnouncement, err error) {
// DecodeAnnouncement decodes the incoming announcement message. Returns nil if invalid.
func DecodeAnnouncement(msg *MessageRaw) (result *MessageAnnouncement, err error) {
result = &MessageAnnouncement{
MessageRaw: msg,
}
@@ -228,19 +221,19 @@ func msgDecodeAnnouncement(msg *MessageRaw) (result *MessageAnnouncement, err er
// decodeKeys decodes keys. Header is 2 bytes (count) followed by the actual keys (each 32 bytes blake3 hash).
func decodeKeys(data []byte) (keys []KeyHash, read int, valid bool) {
if len(data) < 2+hashSize { // minimum length
if len(data) < 2+HashSize { // minimum length
return nil, 0, false
}
count := binary.LittleEndian.Uint16(data[0:2])
if read = 2 + int(count)*hashSize; len(data) < read {
if read = 2 + int(count)*HashSize; len(data) < read {
return nil, 0, false
}
for n := 0; n < int(count); n++ {
key := make([]byte, hashSize)
copy(key, data[2+n*hashSize:2+n*hashSize+hashSize])
key := make([]byte, HashSize)
copy(key, data[2+n*HashSize:2+n*HashSize+HashSize])
keys = append(keys, KeyHash{Hash: key})
}
@@ -260,8 +253,8 @@ func decodeInfoStore(data []byte) (files []InfoStore, read int, valid bool) {
for n := 0; n < int(count); n++ {
file := InfoStore{}
file.ID.Hash = make([]byte, hashSize)
copy(file.ID.Hash, data[2+n*41:2+n*41+hashSize])
file.ID.Hash = make([]byte, HashSize)
copy(file.ID.Hash, data[2+n*41:2+n*41+HashSize])
file.Size = binary.LittleEndian.Uint64(data[2+n*41+32 : 2+n*41+32+8])
file.Type = data[2+n*41+40]
@@ -271,8 +264,8 @@ func decodeInfoStore(data []byte) (files []InfoStore, read int, valid bool) {
return files, read, true
}
// msgDecodeResponse decodes the incoming response message. Returns nil if invalid.
func msgDecodeResponse(msg *MessageRaw) (result *MessageResponse, err error) {
// DecodeResponse decodes the incoming response message. Returns nil if invalid.
func DecodeResponse(msg *MessageRaw) (result *MessageResponse, err error) {
result = &MessageResponse{
MessageRaw: msg,
}
@@ -346,7 +339,7 @@ func msgDecodeResponse(msg *MessageRaw) (result *MessageResponse, err error) {
}
for n := 0; n < int(countHashesNotFound); n++ {
hash := make([]byte, hashSize)
hash := make([]byte, HashSize)
copy(hash, data[n*32:n*32+32])
result.HashesNotFound = append(result.HashesNotFound, hash)
@@ -368,7 +361,7 @@ func decodePeerRecord(data []byte, count int) (hash2Peers []Hash2Peer, read int,
return nil, 0, false
}
hash := make([]byte, hashSize)
hash := make([]byte, HashSize)
copy(hash, data[index:index+32])
countField := binary.LittleEndian.Uint16(data[index+32:index+32+2]) & 0x7FFF
isLast := binary.LittleEndian.Uint16(data[index+32:index+32+2])&0x8000 > 0
@@ -418,7 +411,7 @@ func decodePeerRecord(data []byte, count int) (hash2Peers []Hash2Peer, read int,
return nil, 0, false
}
peer.NodeID = protocol.PublicKey2NodeID(peer.PublicKey)
peer.NodeID = PublicKey2NodeID(peer.PublicKey)
if reason == 0 { // Peer was returned because it is close to the requested hash
hash2Peer.Closest = append(hash2Peer.Closest, peer)
@@ -444,7 +437,7 @@ func decodeEmbeddedFile(data []byte, count int) (filesEmbed []EmbeddedFileData,
return nil, 0, false
}
hash := make([]byte, hashSize)
hash := make([]byte, HashSize)
copy(hash, data[index:index+32])
sizeField := int(binary.LittleEndian.Uint16(data[index+32 : index+32+2]))
index += 34
@@ -459,7 +452,7 @@ func decodeEmbeddedFile(data []byte, count int) (filesEmbed []EmbeddedFileData,
index += sizeField
// validate the hash
if !bytes.Equal(hash, protocol.HashData(fileData)) {
if !bytes.Equal(hash, HashData(fileData)) {
return nil, read, false
}
@@ -475,14 +468,14 @@ const udpMaxPacketSize = 65507
// isPacketSizeExceed checks if the max packet size would be exceeded with the payload
func isPacketSizeExceed(currentSize int, testSize int) bool {
return currentSize+testSize > udpMaxPacketSize-protocol.PacketLengthMin
return currentSize+testSize > udpMaxPacketSize-PacketLengthMin
}
// EncodeAnnouncement encodes an announcement message. It may return multiple messages if the input does not fit into one.
// findPeer is a list of node IDs (blake3 hash of peer ID compressed form)
// findValue is a list of hashes
// files is a list of files stored to inform about
func EncodeAnnouncement(sendUA, findSelf bool, findPeer []KeyHash, findValue []KeyHash, files []InfoStore, features byte, blockchainHeight, blockchainVersion uint64) (packetsRaw [][]byte) {
func EncodeAnnouncement(sendUA, findSelf bool, findPeer []KeyHash, findValue []KeyHash, files []InfoStore, features byte, blockchainHeight, blockchainVersion uint64, userAgent string) (packetsRaw [][]byte) {
createPacketLoop:
for {
raw := make([]byte, 64*1024) // max UDP packet size
@@ -497,7 +490,7 @@ createPacketLoop:
// only on initial announcement the User Agent must be provided according to the protocol spec
if sendUA {
userAgentB := []byte(UserAgent)
userAgentB := []byte(userAgent)
if len(userAgentB) > 255 {
userAgentB = userAgentB[:255]
}
@@ -609,11 +602,11 @@ createPacketLoop:
}
// EmbeddedFileSizeMax is the maximum size of embedded files in response messages. Any file exceeding that must be shared via regular file transfer.
const EmbeddedFileSizeMax = udpMaxPacketSize - protocol.PacketLengthMin - announcementPayloadHeaderSize - 2 - 35
const EmbeddedFileSizeMax = udpMaxPacketSize - PacketLengthMin - announcementPayloadHeaderSize - 2 - 35
// msgEncodeResponse encodes a response message
// EncodeResponse encodes a response message
// hash2Peers will be modified.
func msgEncodeResponse(sendUA bool, hash2Peers []Hash2Peer, filesEmbed []EmbeddedFileData, hashesNotFound [][]byte, features byte, blockchainHeight, blockchainVersion uint64) (packetsRaw [][]byte, err error) {
func EncodeResponse(sendUA bool, hash2Peers []Hash2Peer, filesEmbed []EmbeddedFileData, hashesNotFound [][]byte, features byte, blockchainHeight, blockchainVersion uint64, userAgent string) (packetsRaw [][]byte, err error) {
for n := range filesEmbed {
if len(filesEmbed[n].Data) > EmbeddedFileSizeMax {
return nil, errors.New("embedded file too big")
@@ -634,7 +627,7 @@ createPacketLoop:
// only on initial response the User Agent must be provided according to the protocol spec
if sendUA {
userAgentB := []byte(UserAgent)
userAgentB := []byte(userAgent)
if len(userAgentB) > 255 {
userAgentB = userAgentB[:255]
}
@@ -782,10 +775,10 @@ func encodePeerRecord(raw []byte, peer *PeerRecord, reason uint8) {
const traversePayloadHeaderSize = 76 + 65 + 28
// msgDecodeTraverse decodes a traverse message.
// DecodeTraverse decodes a traverse message.
// It does not verify if the receiver is authorized to read or forward this message.
// It validates the signature, but does not validate the signer.
func msgDecodeTraverse(msg *MessageRaw) (result *MessageTraverse, err error) {
func DecodeTraverse(msg *MessageRaw) (result *MessageTraverse, err error) {
result = &MessageTraverse{
MessageRaw: msg,
}
@@ -821,7 +814,7 @@ func msgDecodeTraverse(msg *MessageRaw) (result *MessageTraverse, err error) {
signature := msg.Payload[76+sizePacketEmbed : 76+sizePacketEmbed+65]
result.SignerPublicKey, _, err = btcec.RecoverCompact(btcec.S256(), signature, protocol.HashData(msg.Payload[:76+sizePacketEmbed]))
result.SignerPublicKey, _, err = btcec.RecoverCompact(btcec.S256(), signature, HashData(msg.Payload[:76+sizePacketEmbed]))
if err != nil {
return nil, err
}
@@ -850,8 +843,8 @@ func msgDecodeTraverse(msg *MessageRaw) (result *MessageTraverse, err error) {
return result, nil
}
// msgEncodeTraverse encodes a traverse message
func msgEncodeTraverse(senderPrivateKey *btcec.PrivateKey, embeddedPacketRaw []byte, receiverEnd *btcec.PublicKey, relayPeer *btcec.PublicKey) (packetRaw []byte, err error) {
// EncodeTraverse encodes a traverse message
func EncodeTraverse(senderPrivateKey *btcec.PrivateKey, embeddedPacketRaw []byte, receiverEnd *btcec.PublicKey, relayPeer *btcec.PublicKey) (packetRaw []byte, err error) {
sizePacketEmbed := len(embeddedPacketRaw)
if isPacketSizeExceed(traversePayloadHeaderSize, sizePacketEmbed) {
return nil, errors.New("traverse encode: embedded packet too big")
@@ -871,7 +864,7 @@ func msgEncodeTraverse(senderPrivateKey *btcec.PrivateKey, embeddedPacketRaw []b
copy(raw[76:76+sizePacketEmbed], embeddedPacketRaw)
// add signature
signature, err := btcec.SignCompact(btcec.S256(), senderPrivateKey, protocol.HashData(raw[:76+sizePacketEmbed]), true)
signature, err := btcec.SignCompact(btcec.S256(), senderPrivateKey, HashData(raw[:76+sizePacketEmbed]), true)
if err != nil {
return nil, err
}
@@ -882,8 +875,8 @@ func msgEncodeTraverse(senderPrivateKey *btcec.PrivateKey, embeddedPacketRaw []b
return raw, nil
}
// msgEncodeTraverseSetAddress sets the IP and Port
func msgEncodeTraverseSetAddress(raw []byte, IPv4 net.IP, PortIPv4, PortIPv4ReportedExternal uint16, IPv6 net.IP, PortIPv6, PortIPv6ReportedExternal uint16) (err error) {
// EncodeTraverseSetAddress sets the IP and Port
func EncodeTraverseSetAddress(raw []byte, IPv4 net.IP, PortIPv4, PortIPv4ReportedExternal uint16, IPv6 net.IP, PortIPv6, PortIPv6ReportedExternal uint16) (err error) {
if isPacketSizeExceed(len(raw), 0) {
return errors.New("traverse encode 2: embedded packet too big")
} else if len(raw) < traversePayloadHeaderSize {
@@ -896,14 +889,14 @@ func msgEncodeTraverseSetAddress(raw []byte, IPv4 net.IP, PortIPv4, PortIPv4Repo
}
// IPv4
if IPv4 != nil && IsIPv4(IPv4) {
if IPv4 != nil && len(IPv4) == net.IPv4len {
copy(raw[76+sizePacketEmbed+65:76+sizePacketEmbed+65+4], IPv4.To4())
binary.LittleEndian.PutUint16(raw[76+sizePacketEmbed+65+4:76+sizePacketEmbed+65+4+2], PortIPv4)
binary.LittleEndian.PutUint16(raw[76+sizePacketEmbed+65+6:76+sizePacketEmbed+65+6+2], PortIPv4ReportedExternal)
}
// IPv6
if IPv6 != nil && IsIPv6(IPv6) {
if IPv6 != nil && len(IPv6) == net.IPv6len {
copy(raw[76+sizePacketEmbed+65+8:76+sizePacketEmbed+65+8+16], IPv6.To16())
binary.LittleEndian.PutUint16(raw[76+sizePacketEmbed+65+24:76+sizePacketEmbed+65+24+2], PortIPv6)
binary.LittleEndian.PutUint16(raw[76+sizePacketEmbed+65+26:76+sizePacketEmbed+65+26+2], PortIPv6ReportedExternal)

View File

@@ -1,40 +1,41 @@
// Functions to manually debug encoding/decoding. No actual automated unit tests.
package core
package protocol
import (
"fmt"
"testing"
"github.com/PeernetOfficial/core/protocol"
"github.com/btcsuite/btcd/btcec"
)
func TestMessageEncodingAnnouncement(t *testing.T) {
_, publicKey, err := Secp256k1NewPrivateKey()
privateKey, err := btcec.NewPrivateKey(btcec.S256())
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
publicKey := (*btcec.PublicKey)(&privateKey.PublicKey)
// encode and decode announcement
packetR := protocol.PacketRaw{Protocol: 0, Command: protocol.CommandAnnouncement, Sequence: 123}
packetR := PacketRaw{Protocol: 0, Command: CommandAnnouncement, Sequence: 123}
var findPeer []KeyHash
var findValue []KeyHash
var files []InfoStore
hash1 := protocol.HashData([]byte("test"))
hash2 := protocol.HashData([]byte("test3"))
hash1 := HashData([]byte("test"))
hash2 := HashData([]byte("test3"))
findPeer = append(findPeer, KeyHash{Hash: hash1})
findValue = append(findValue, KeyHash{Hash: hash2})
packets := EncodeAnnouncement(true, true, findPeer, findValue, files, 1<<FeatureIPv4Listen|1<<FeatureIPv6Listen, 0, 0)
packets := EncodeAnnouncement(true, true, findPeer, findValue, files, 1<<FeatureIPv4Listen|1<<FeatureIPv6Listen, 0, 0, "Debug Test/1.0")
msg := &MessageRaw{PacketRaw: packetR, SenderPublicKey: publicKey}
msg.Payload = packets[0]
result, err := msgDecodeAnnouncement(msg)
result, err := DecodeAnnouncement(msg)
if err != nil {
fmt.Printf("Error msgDecodeAnnouncement: %s\n", err.Error())
fmt.Printf("Error DecodeAnnouncement: %s\n", err.Error())
return
}
@@ -42,14 +43,15 @@ func TestMessageEncodingAnnouncement(t *testing.T) {
}
func TestMessageEncodingResponse(t *testing.T) {
_, publicKey, err := Secp256k1NewPrivateKey()
privateKey, err := btcec.NewPrivateKey(btcec.S256())
if err != nil {
fmt.Printf("Error: %s\n", err.Error())
return
}
publicKey := (*btcec.PublicKey)(&privateKey.PublicKey)
// encode and decode response
packetR := protocol.PacketRaw{Protocol: 0, Command: protocol.CommandResponse}
packetR := PacketRaw{Protocol: 0, Command: CommandResponse}
var hash2Peers []Hash2Peer
var filesEmbed []EmbeddedFileData
@@ -57,14 +59,14 @@ func TestMessageEncodingResponse(t *testing.T) {
file1Data := []byte("test")
file2Data := []byte("test3")
file1 := EmbeddedFileData{ID: KeyHash{protocol.HashData(file1Data)}, Data: file1Data}
file2 := EmbeddedFileData{ID: KeyHash{protocol.HashData(file2Data)}, Data: file2Data}
file1 := EmbeddedFileData{ID: KeyHash{HashData(file1Data)}, Data: file1Data}
file2 := EmbeddedFileData{ID: KeyHash{HashData(file2Data)}, Data: file2Data}
filesEmbed = append(filesEmbed, file1)
filesEmbed = append(filesEmbed, file2)
hashesNotFound = append(hashesNotFound, protocol.HashData([]byte("NA")))
hashesNotFound = append(hashesNotFound, HashData([]byte("NA")))
packetsRaw, err := msgEncodeResponse(true, hash2Peers, filesEmbed, hashesNotFound, 1<<FeatureIPv4Listen|1<<FeatureIPv6Listen, 0, 0)
packetsRaw, err := EncodeResponse(true, hash2Peers, filesEmbed, hashesNotFound, 1<<FeatureIPv4Listen|1<<FeatureIPv6Listen, 0, 0, "Debug Test/1.0")
if err != nil {
fmt.Printf("Error msgEncodeAnnouncement: %s\n", err.Error())
return
@@ -73,9 +75,9 @@ func TestMessageEncodingResponse(t *testing.T) {
msg := &MessageRaw{PacketRaw: packetR, SenderPublicKey: publicKey}
msg.Payload = packetsRaw[0]
result, err := msgDecodeResponse(msg)
result, err := DecodeResponse(msg)
if err != nil {
fmt.Printf("Error msgDecodeAnnouncement: %s\n", err.Error())
fmt.Printf("Error DecodeAnnouncement: %s\n", err.Error())
return
}