oc-discovery -> conf
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"oc-discovery/conf"
|
||||
"oc-discovery/daemons/node/common"
|
||||
"oc-discovery/daemons/node/indexer"
|
||||
"oc-discovery/daemons/node/location"
|
||||
"oc-discovery/daemons/node/pubsub"
|
||||
"oc-discovery/daemons/node/stream"
|
||||
"sync"
|
||||
@@ -108,7 +109,11 @@ func InitNode(isNode bool, isIndexer bool) (*Node, error) {
|
||||
return nil
|
||||
}
|
||||
fresh := *node.peerRecord
|
||||
fresh.PeerRecordPayload.ExpiryDate = time.Now().UTC().Add(2 * time.Minute)
|
||||
ttl := time.Duration(fresh.TTLSeconds) * time.Second
|
||||
if ttl <= 0 {
|
||||
ttl = indexer.DefaultTTLSeconds * time.Second
|
||||
}
|
||||
fresh.PeerRecordPayload.ExpiryDate = time.Now().UTC().Add(ttl)
|
||||
payload, _ := json.Marshal(fresh.PeerRecordPayload)
|
||||
fresh.Signature, err = priv.Sign(payload)
|
||||
if err != nil {
|
||||
@@ -170,10 +175,24 @@ func InitNode(isNode bool, isIndexer bool) (*Node, error) {
|
||||
if err != nil || evt.From == node.PeerID.String() {
|
||||
return
|
||||
}
|
||||
fmt.Println("PUBSUB SendResponse bef peerrece")
|
||||
if p, err := node.GetPeerRecord(ctx, evt.From); err == nil && len(p) > 0 && m["search"] != nil {
|
||||
fmt.Println("PUBSUB SendResponse af peerrece", m)
|
||||
node.StreamService.SendResponse(p[0], &evt, fmt.Sprintf("%v", m["search"]))
|
||||
}
|
||||
}
|
||||
node.AllowInbound = func(remotePeer pp.ID, isNew bool) error {
|
||||
if isNew {
|
||||
// DB blacklist check: blocks reconnection after EvictPeer + blacklist.
|
||||
if !node.isPeerKnown(remotePeer) {
|
||||
return errors.New("peer is blacklisted or unknown")
|
||||
}
|
||||
if !node.ConnGuard.Allow() {
|
||||
return errors.New("connection rate limit exceeded, retry later")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
logger.Info().Msg("subscribe to decentralized search flow...")
|
||||
go node.SubscribeToSearch(node.PS, &f)
|
||||
logger.Info().Msg("connect to NATS")
|
||||
@@ -187,6 +206,39 @@ func InitNode(isNode bool, isIndexer bool) (*Node, error) {
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// isPeerKnown is the stream-level gate: returns true if pid is allowed.
|
||||
// Check order (fast → slow):
|
||||
// 1. In-memory stream records — currently heartbeating to this indexer.
|
||||
// 2. Local DB by peer_id — known peer, blacklist enforced here.
|
||||
// 3. DHT /pid/{peerID} → /node/{DID} — registered on any indexer.
|
||||
//
|
||||
// ProtocolHeartbeat and ProtocolPublish handlers do NOT call this — they are
|
||||
// the streams through which a node first makes itself known.
|
||||
func (d *Node) isPeerKnown(pid pp.ID) bool {
|
||||
// 1. Fast path: active heartbeat session.
|
||||
d.StreamMU.RLock()
|
||||
_, active := d.StreamRecords[common.ProtocolHeartbeat][pid]
|
||||
d.StreamMU.RUnlock()
|
||||
if active {
|
||||
return true
|
||||
}
|
||||
// 2. Local DB: known peer (handles blacklist).
|
||||
access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
|
||||
results := access.Search(&dbs.Filters{
|
||||
And: map[string][]dbs.Filter{
|
||||
"peer_id": {{Operator: dbs.EQUAL.String(), Value: pid.String()}},
|
||||
},
|
||||
}, pid.String(), false)
|
||||
for _, item := range results.Data {
|
||||
p, ok := item.(*peer.Peer)
|
||||
if !ok || p.PeerID != pid.String() {
|
||||
continue
|
||||
}
|
||||
return p.Relation != peer.BLACKLIST
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (d *Node) Close() {
|
||||
if d.isIndexer && d.IndexerService != nil {
|
||||
d.IndexerService.Close()
|
||||
@@ -211,11 +263,16 @@ func (d *Node) publishPeerRecord(
|
||||
continue
|
||||
}
|
||||
stream := common.Indexers.Streams.GetPerID(common.ProtocolPublish, ad.Info.ID)
|
||||
ttl := time.Duration(rec.TTLSeconds) * time.Second
|
||||
if ttl <= 0 {
|
||||
ttl = indexer.DefaultTTLSeconds * time.Second
|
||||
}
|
||||
base := indexer.PeerRecordPayload{
|
||||
Name: rec.Name,
|
||||
DID: rec.DID,
|
||||
PubKey: rec.PubKey,
|
||||
ExpiryDate: time.Now().UTC().Add(2 * time.Minute),
|
||||
TTLSeconds: rec.TTLSeconds,
|
||||
ExpiryDate: time.Now().UTC().Add(ttl),
|
||||
}
|
||||
payload, _ := json.Marshal(base)
|
||||
rec.PeerRecordPayload = base
|
||||
@@ -377,13 +434,12 @@ func (d *Node) claimInfo(
|
||||
}
|
||||
|
||||
now := time.Now().UTC()
|
||||
expiry := now.Add(150 * time.Second)
|
||||
|
||||
pRec := indexer.PeerRecordPayload{
|
||||
Name: name,
|
||||
DID: did, // REAL PEER ID
|
||||
PubKey: pubBytes,
|
||||
ExpiryDate: expiry,
|
||||
TTLSeconds: indexer.DefaultTTLSeconds,
|
||||
ExpiryDate: now.Add(indexer.DefaultTTLSeconds * time.Second),
|
||||
}
|
||||
d.PeerID = d.Host.ID()
|
||||
payload, _ := json.Marshal(pRec)
|
||||
@@ -400,6 +456,7 @@ func (d *Node) claimInfo(
|
||||
rec.StreamAddress = "/ip4/" + conf.GetConfig().Hostname + "/tcp/" + fmt.Sprintf("%v", conf.GetConfig().NodeEndpointPort) + "/p2p/" + rec.PeerID
|
||||
rec.NATSAddress = oclib.GetConfig().NATSUrl
|
||||
rec.WalletAddress = "my-wallet"
|
||||
rec.Location = location.Geolocate(conf.GetConfig().LocationGranularity)
|
||||
|
||||
if err := d.publishPeerRecord(rec); err != nil {
|
||||
return nil, err
|
||||
@@ -424,6 +481,55 @@ func (d *Node) claimInfo(
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteRecord broadcasts a signed tombstone to all connected indexers, signalling
|
||||
// that this node is voluntarily leaving the network.
|
||||
// Each indexer verifies the signature, stores the tombstone in the DHT (replacing
|
||||
// the live record), and evicts the peer from its active pool.
|
||||
// After a successful call, d.peerRecord is set to nil.
|
||||
func (d *Node) DeleteRecord() error {
|
||||
if d.peerRecord == nil {
|
||||
return errors.New("no peer record to delete")
|
||||
}
|
||||
priv, err := tools.LoadKeyFromFilePrivate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pubBytes, err := crypto.MarshalPublicKey(priv.GetPublic())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tp := indexer.TombstonePayload{
|
||||
DID: d.peerRecord.DID,
|
||||
PeerID: d.PeerID.String(),
|
||||
DeletedAt: time.Now().UTC(),
|
||||
}
|
||||
payloadBytes, _ := json.Marshal(tp)
|
||||
sig, err := priv.Sign(payloadBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ts := &indexer.TombstoneRecord{
|
||||
TombstonePayload: tp,
|
||||
PubKey: pubBytes,
|
||||
Tombstone: true,
|
||||
Signature: sig,
|
||||
}
|
||||
data, _ := json.Marshal(ts)
|
||||
for _, ad := range common.Indexers.GetAddrs() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
s, err := d.Host.NewStream(ctx, ad.Info.ID, common.ProtocolDelete)
|
||||
cancel()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
s.SetDeadline(time.Now().Add(5 * time.Second))
|
||||
s.Write(data)
|
||||
s.Close()
|
||||
}
|
||||
d.peerRecord = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- Le booking est un flow neuf décentralisé :
|
||||
|
||||
Reference in New Issue
Block a user