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) }