Discovery Neo Oclib

This commit is contained in:
mr
2026-05-27 16:17:00 +02:00
parent 7f951afd41
commit 6ce6e6fe7d
20 changed files with 1436 additions and 1133 deletions
+40 -2
View File
@@ -39,6 +39,8 @@ type PeerRecordPayload struct {
PubKey []byte `json:"public_key"`
ExpiryDate time.Time `json:"expiry_date"`
IsNano bool `json:"is_nano"`
// MasterID is the libp2p PeerID of this peer's MASTER, self-attested and signed.
MasterID string `json:"master_id,omitempty"`
// TTLSeconds is the publisher's declared lifetime for this record in seconds.
// 0 means "use the default (120 s)". Included in the signed payload so it
// cannot be altered by an intermediary.
@@ -105,6 +107,7 @@ func (pr *PeerRecord) ExtractPeer(ourkey string, key string, pubKey crypto.PubKe
NATSAddress: pr.NATSAddress,
WalletAddress: pr.WalletAddress,
Location: pr.Location,
MasterID: pr.MasterID,
}
if time.Now().UTC().After(pr.ExpiryDate) {
return pp.SELF == p.Relation, nil, errors.New("peer " + key + " is offline")
@@ -285,6 +288,20 @@ func (ix *IndexerService) initNodeHandler() {
}
cancel2()
}
// PendingContact: update inverted index — for each target peer in the list,
// record that hb.PeerID wants to contact it. Entries expire after 3 heartbeat
// intervals so stale callers are cleaned up automatically if they stop advertising.
if len(hb.PendingContact) > 0 {
expiry := time.Now().Add(3 * 20 * time.Second)
ix.pendingContactIndexMu.Lock()
for _, targetID := range hb.PendingContact {
if ix.pendingContactIndex[targetID] == nil {
ix.pendingContactIndex[targetID] = map[string]time.Time{}
}
ix.pendingContactIndex[targetID][hb.PeerID] = expiry
}
ix.pendingContactIndexMu.Unlock()
}
}
ix.Host.SetStreamHandler(common.ProtocolHeartbeat, ix.HandleHeartbeat)
ix.Host.SetStreamHandler(common.ProtocolPublish, ix.handleNodePublish)
@@ -351,7 +368,8 @@ func (ix *IndexerService) handleNodePublish(s network.Stream) {
}
continue
}
if _, err := rec.Verify(); err != nil {
pubKey, err := rec.Verify()
if err != nil {
ix.behavior.RecordBadSignature(remotePeer)
logger.Warn().Err(err).Str("peer", remotePeer.String()).Msg("bad signature on publish")
return
@@ -369,6 +387,26 @@ func (ix *IndexerService) handleNodePublish(s network.Stream) {
if err != nil {
return
}
// Chain of trust: PubKey → PeerID (libp2p invariant), then transport identity.
// This prevents a peer from publishing a record on behalf of someone else.
if derivedID, err := lpp.IDFromPublicKey(pubKey); err != nil || derivedID != pid {
ix.behavior.RecordBadSignature(remotePeer)
logger.Warn().Str("peer", remotePeer.String()).Msg("PubKey/PeerID mismatch on publish")
s.Reset()
return
}
if remotePeer != pid {
ix.behavior.RecordBadSignature(remotePeer)
logger.Warn().Str("remote", remotePeer.String()).Str("claimed", pid.String()).Msg("transport identity mismatch on publish")
s.Reset()
return
}
if rec.StreamAddress != "" && !strings.HasSuffix(rec.StreamAddress, "/p2p/"+rec.PeerID) {
ix.behavior.RecordBadSignature(remotePeer)
logger.Warn().Str("peer", remotePeer.String()).Msg("StreamAddress/PeerID mismatch on publish")
s.Reset()
return
}
ix.StreamMU.Lock()
defer ix.StreamMU.Unlock()
@@ -566,7 +604,7 @@ func (ix *IndexerService) handleIndirectProbe(s network.Stream) {
// Connect to target if not already connected.
ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second)
defer cancel()
if ix.Host.Network().Connectedness(req.Target.ID) != network.Connected {
if len(ix.Host.Network().ConnsToPeer(req.Target.ID)) == 0 {
if err := ix.Host.Connect(ctx, req.Target); err != nil {
respond(false, 0)
return