In general case create enr.Record right before registering it
This commit is contained in:
parent
aab84e53dc
commit
4ad036f2e1
|
@ -3,6 +3,7 @@ package discovery
|
|||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"sync"
|
||||
|
@ -22,20 +23,18 @@ const (
|
|||
bucketSize = 10
|
||||
)
|
||||
|
||||
var (
|
||||
errNodeIsNil = errors.New("node cannot be nil")
|
||||
errIdentityIsNil = errors.New("identity cannot be nil")
|
||||
)
|
||||
|
||||
func NewRendezvous(servers []ma.Multiaddr, identity *ecdsa.PrivateKey, node *discover.Node) (*Rendezvous, error) {
|
||||
r := new(Rendezvous)
|
||||
r.node = node
|
||||
r.identity = identity
|
||||
r.servers = servers
|
||||
r.registrationPeriod = registrationPeriod
|
||||
r.bucketSize = bucketSize
|
||||
|
||||
r.record = enr.Record{}
|
||||
r.record.Set(enr.IP(node.IP))
|
||||
r.record.Set(enr.TCP(node.TCP))
|
||||
r.record.Set(enr.UDP(node.UDP))
|
||||
// public key is added to ENR when ENR is signed
|
||||
if err := enr.SignV4(&r.record, identity); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
|
@ -44,7 +43,7 @@ func NewRendezvousWithENR(servers []ma.Multiaddr, record enr.Record) *Rendezvous
|
|||
r.servers = servers
|
||||
r.registrationPeriod = registrationPeriod
|
||||
r.bucketSize = bucketSize
|
||||
r.record = record
|
||||
r.record = &record
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -62,7 +61,11 @@ type Rendezvous struct {
|
|||
servers []ma.Multiaddr
|
||||
registrationPeriod time.Duration
|
||||
bucketSize int
|
||||
record enr.Record
|
||||
node *discover.Node
|
||||
identity *ecdsa.PrivateKey
|
||||
|
||||
recordMu sync.Mutex
|
||||
record *enr.Record // record is set directly if rendezvous is used in proxy mode
|
||||
}
|
||||
|
||||
func (r *Rendezvous) Running() bool {
|
||||
|
@ -93,7 +96,30 @@ func (r *Rendezvous) Stop() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *Rendezvous) register(topic string) error {
|
||||
func (r *Rendezvous) MakeRecord() (record enr.Record, err error) {
|
||||
r.recordMu.Lock()
|
||||
defer r.recordMu.Unlock()
|
||||
if r.record != nil {
|
||||
return *r.record, nil
|
||||
}
|
||||
if r.node == nil {
|
||||
return record, errNodeIsNil
|
||||
}
|
||||
if r.identity == nil {
|
||||
return record, errIdentityIsNil
|
||||
}
|
||||
record.Set(enr.IP(r.node.IP))
|
||||
record.Set(enr.TCP(r.node.TCP))
|
||||
record.Set(enr.UDP(r.node.UDP))
|
||||
// public key is added to ENR when ENR is signed
|
||||
if err := enr.SignV4(&record, r.identity); err != nil {
|
||||
return record, err
|
||||
}
|
||||
r.record = &record
|
||||
return record, nil
|
||||
}
|
||||
|
||||
func (r *Rendezvous) register(topic string, record enr.Record) error {
|
||||
srv := r.servers[rand.Intn(len(r.servers))]
|
||||
ctx, cancel := context.WithTimeout(r.rootCtx, requestTimeout)
|
||||
defer cancel()
|
||||
|
@ -101,7 +127,7 @@ func (r *Rendezvous) register(topic string) error {
|
|||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
|
||||
err := r.client.Register(ctx, srv, topic, r.record, r.registrationPeriod)
|
||||
err := r.client.Register(ctx, srv, topic, record, r.registrationPeriod)
|
||||
if err != nil {
|
||||
log.Error("error registering", "topic", topic, "rendezvous server", srv, "err", err)
|
||||
}
|
||||
|
@ -110,12 +136,16 @@ func (r *Rendezvous) register(topic string) error {
|
|||
|
||||
// Register renews registration in the specified server.
|
||||
func (r *Rendezvous) Register(topic string, stop chan struct{}) error {
|
||||
record, err := r.MakeRecord()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// sending registration more often than the whole registraton period
|
||||
// will ensure that it won't be accidentally removed
|
||||
ticker := time.NewTicker(r.registrationPeriod / 2)
|
||||
defer ticker.Stop()
|
||||
|
||||
if err := r.register(topic); err == context.Canceled {
|
||||
if err := r.register(topic, record); err == context.Canceled {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -124,7 +154,7 @@ func (r *Rendezvous) Register(topic string, stop chan struct{}) error {
|
|||
case <-stop:
|
||||
return nil
|
||||
case <-ticker.C:
|
||||
if err := r.register(topic); err == context.Canceled {
|
||||
if err := r.register(topic, record); err == context.Canceled {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
lcrypto "github.com/libp2p/go-libp2p-crypto"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
"github.com/status-im/rendezvous/server"
|
||||
|
@ -60,6 +61,18 @@ func TestRendezvousDiscovery(t *testing.T) {
|
|||
close(period)
|
||||
}
|
||||
|
||||
func TestMakeRecordReturnsCachedRecord(t *testing.T) {
|
||||
identity, err := crypto.GenerateKey()
|
||||
require.NoError(t, err)
|
||||
record := enr.Record{}
|
||||
require.NoError(t, enr.SignV4(&record, identity))
|
||||
c := NewRendezvousWithENR(nil, record)
|
||||
rst, err := c.MakeRecord()
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, rst.NodeAddr())
|
||||
require.Equal(t, record.NodeAddr(), rst.NodeAddr())
|
||||
}
|
||||
|
||||
func BenchmarkRendezvousStart(b *testing.B) {
|
||||
identity, err := crypto.GenerateKey()
|
||||
require.NoError(b, err)
|
||||
|
|
Loading…
Reference in New Issue