p2p/discover: add support for EIP-868 (v4 ENR extension) (#19540)
This change implements EIP-868. The UDPv4 transport announces support for the extension in ping/pong and handles enrRequest messages. There are two uses of the extension: If a remote node announces support for EIP-868 in their pong, node revalidation pulls the node's record. The Resolve method requests the record unconditionally.
This commit is contained in:
@ -98,6 +98,7 @@ func fillTable(tab *Table, nodes []*node) {
|
||||
type pingRecorder struct {
|
||||
mu sync.Mutex
|
||||
dead, pinged map[enode.ID]bool
|
||||
records map[enode.ID]*enode.Node
|
||||
n *enode.Node
|
||||
}
|
||||
|
||||
@ -107,38 +108,53 @@ func newPingRecorder() *pingRecorder {
|
||||
n := enode.SignNull(&r, enode.ID{})
|
||||
|
||||
return &pingRecorder{
|
||||
dead: make(map[enode.ID]bool),
|
||||
pinged: make(map[enode.ID]bool),
|
||||
n: n,
|
||||
dead: make(map[enode.ID]bool),
|
||||
pinged: make(map[enode.ID]bool),
|
||||
records: make(map[enode.ID]*enode.Node),
|
||||
n: n,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *pingRecorder) Self() *enode.Node {
|
||||
return nullNode
|
||||
// setRecord updates a node record. Future calls to ping and
|
||||
// requestENR will return this record.
|
||||
func (t *pingRecorder) updateRecord(n *enode.Node) {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.records[n.ID()] = n
|
||||
}
|
||||
|
||||
func (t *pingRecorder) ping(n *enode.Node) error {
|
||||
// Stubs to satisfy the transport interface.
|
||||
func (t *pingRecorder) Self() *enode.Node { return nullNode }
|
||||
func (t *pingRecorder) lookupSelf() []*enode.Node { return nil }
|
||||
func (t *pingRecorder) lookupRandom() []*enode.Node { return nil }
|
||||
func (t *pingRecorder) close() {}
|
||||
|
||||
// ping simulates a ping request.
|
||||
func (t *pingRecorder) ping(n *enode.Node) (seq uint64, err error) {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
t.pinged[n.ID()] = true
|
||||
if t.dead[n.ID()] {
|
||||
return errTimeout
|
||||
} else {
|
||||
return nil
|
||||
return 0, errTimeout
|
||||
}
|
||||
if t.records[n.ID()] != nil {
|
||||
seq = t.records[n.ID()].Seq()
|
||||
}
|
||||
return seq, nil
|
||||
}
|
||||
|
||||
func (t *pingRecorder) lookupSelf() []*enode.Node {
|
||||
return nil
|
||||
}
|
||||
// requestENR simulates an ENR request.
|
||||
func (t *pingRecorder) requestENR(n *enode.Node) (*enode.Node, error) {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
func (t *pingRecorder) lookupRandom() []*enode.Node {
|
||||
return nil
|
||||
if t.dead[n.ID()] || t.records[n.ID()] == nil {
|
||||
return nil, errTimeout
|
||||
}
|
||||
return t.records[n.ID()], nil
|
||||
}
|
||||
|
||||
func (t *pingRecorder) close() {}
|
||||
|
||||
func hasDuplicates(slice []*node) bool {
|
||||
seen := make(map[enode.ID]bool)
|
||||
for i, e := range slice {
|
||||
|
Reference in New Issue
Block a user