aboutsummaryrefslogtreecommitdiffstats
path: root/dex/nodetable.go
blob: cc1de160fe3048ca7988a6460672813cdfb51025 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package dex

import (
    "sync"

    "github.com/dexon-foundation/dexon/event"
    "github.com/dexon-foundation/dexon/log"
    "github.com/dexon-foundation/dexon/p2p/enode"
    "github.com/dexon-foundation/dexon/p2p/enr"
)

type newRecordsEvent struct{ Records []*enr.Record }

type nodeTable struct {
    mu    sync.RWMutex
    entry map[enode.ID]*enode.Node
    feed  event.Feed
}

func newNodeTable() *nodeTable {
    return &nodeTable{
        entry: make(map[enode.ID]*enode.Node),
    }
}

func (t *nodeTable) GetNode(id enode.ID) *enode.Node {
    t.mu.RLock()
    defer t.mu.RUnlock()
    return t.entry[id]
}

func (t *nodeTable) AddRecords(records []*enr.Record) {
    t.mu.Lock()
    defer t.mu.Unlock()

    var newRecords []*enr.Record
    for _, record := range records {
        node, err := enode.New(enode.ValidSchemes, record)
        if err != nil {
            log.Error("invalid node record", "err", err)
            return
        }

        if n, ok := t.entry[node.ID()]; ok && n.Seq() >= node.Seq() {
            log.Trace("Ignore new record, already exists", "id", node.ID().String(),
                "ip", node.IP().String(), "udp", node.UDP(), "tcp", node.TCP())
            continue
        }

        t.entry[node.ID()] = node
        newRecords = append(newRecords, record)
        log.Debug("Add new record to node table", "id", node.ID().String(),
            "ip", node.IP().String(), "udp", node.UDP(), "tcp", node.TCP())
    }
    if len(newRecords) > 0 {
        go t.feed.Send(newRecordsEvent{newRecords})
    }
}

func (t *nodeTable) Records() []*enr.Record {
    t.mu.RLock()
    defer t.mu.RUnlock()
    records := make([]*enr.Record, 0, len(t.entry))
    for _, node := range t.entry {
        records = append(records, node.Record())
    }
    return records
}

func (t *nodeTable) SubscribeNewRecordsEvent(
    ch chan<- newRecordsEvent) event.Subscription {
    return t.feed.Subscribe(ch)
}