cache the mapping of addr to node

pull/31075/head
thinkAfCod 6 days ago
parent 75526bb8e0
commit cd9f1b7274
  1. 64
      p2p/discover/v5_udp.go

@ -30,6 +30,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/ethereum/go-ethereum/common/lru"
"github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/common/mclock"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/discover/v5wire" "github.com/ethereum/go-ethereum/p2p/discover/v5wire"
@ -62,15 +63,16 @@ type codecV5 interface {
// UDPv5 is the implementation of protocol version 5. // UDPv5 is the implementation of protocol version 5.
type UDPv5 struct { type UDPv5 struct {
// static fields // static fields
conn UDPConn conn UDPConn
tab *Table tab *Table
netrestrict *netutil.Netlist netrestrict *netutil.Netlist
priv *ecdsa.PrivateKey priv *ecdsa.PrivateKey
localNode *enode.LocalNode localNode *enode.LocalNode
db *enode.DB db *enode.DB
log log.Logger log log.Logger
clock mclock.Clock clock mclock.Clock
validSchemes enr.IdentityScheme validSchemes enr.IdentityScheme
cacheIdToNode *lru.Cache[enode.ID, *enode.Node]
// misc buffers used during message handling // misc buffers used during message handling
logcontext []interface{} logcontext []interface{}
@ -150,14 +152,15 @@ func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) {
cfg = cfg.withDefaults() cfg = cfg.withDefaults()
t := &UDPv5{ t := &UDPv5{
// static fields // static fields
conn: newMeteredConn(conn), conn: newMeteredConn(conn),
localNode: ln, localNode: ln,
db: ln.Database(), db: ln.Database(),
netrestrict: cfg.NetRestrict, netrestrict: cfg.NetRestrict,
priv: cfg.PrivateKey, priv: cfg.PrivateKey,
log: cfg.Log, log: cfg.Log,
validSchemes: cfg.ValidSchemes, validSchemes: cfg.ValidSchemes,
clock: cfg.Clock, clock: cfg.Clock,
cacheIdToNode: lru.NewCache[enode.ID, *enode.Node](1024),
// channels into dispatch // channels into dispatch
packetInCh: make(chan ReadPacket, 1), packetInCh: make(chan ReadPacket, 1),
readNextCh: make(chan struct{}, 1), readNextCh: make(chan struct{}, 1),
@ -705,6 +708,7 @@ func (t *UDPv5) handlePacket(rawpacket []byte, fromAddr netip.AddrPort) error {
if fromNode != nil { if fromNode != nil {
// Handshake succeeded, add to table. // Handshake succeeded, add to table.
t.tab.addInboundNode(fromNode) t.tab.addInboundNode(fromNode)
t.cacheNode(fromNode)
} }
if packet.Kind() != v5wire.WhoareyouPacket { if packet.Kind() != v5wire.WhoareyouPacket {
// WHOAREYOU logged separately to report errors. // WHOAREYOU logged separately to report errors.
@ -737,16 +741,30 @@ func (t *UDPv5) handleCallResponse(fromID enode.ID, fromAddr netip.AddrPort, p v
} }
// getNode looks for a node record in table and database. // getNode looks for a node record in table and database.
func (t *UDPv5) getNode(id enode.ID) *enode.Node { func (t *UDPv5) GetNode(id enode.ID) (n *enode.Node) {
if n := t.tab.getNode(id); n != nil { if node, ok := t.cacheIdToNode.Get(id); ok {
return n return node
}
defer func() {
t.cacheNode(n)
}()
if n = t.tab.getNode(id); n != nil {
return
} }
if n := t.localNode.Database().Node(id); n != nil { if n = t.localNode.Database().Node(id); n != nil {
return n return
} }
return nil return nil
} }
// cacheNode cache addr to node
func (t *UDPv5) cacheNode(node *enode.Node) {
if node == nil {
return
}
t.cacheIdToNode.Add(node.ID(), node)
}
// handle processes incoming packets according to their message type. // handle processes incoming packets according to their message type.
func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort) { func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort) {
switch p := p.(type) { switch p := p.(type) {
@ -776,7 +794,7 @@ func (t *UDPv5) handle(p v5wire.Packet, fromID enode.ID, fromAddr netip.AddrPort
func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) { func (t *UDPv5) handleUnknown(p *v5wire.Unknown, fromID enode.ID, fromAddr netip.AddrPort) {
challenge := &v5wire.Whoareyou{Nonce: p.Nonce} challenge := &v5wire.Whoareyou{Nonce: p.Nonce}
crand.Read(challenge.IDNonce[:]) crand.Read(challenge.IDNonce[:])
if n := t.getNode(fromID); n != nil { if n := t.GetNode(fromID); n != nil {
challenge.Node = n challenge.Node = n
challenge.RecordSeq = n.Seq() challenge.RecordSeq = n.Seq()
} }

Loading…
Cancel
Save