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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"errors"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -22,20 +23,18 @@ const (
|
||||||
bucketSize = 10
|
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) {
|
func NewRendezvous(servers []ma.Multiaddr, identity *ecdsa.PrivateKey, node *discover.Node) (*Rendezvous, error) {
|
||||||
r := new(Rendezvous)
|
r := new(Rendezvous)
|
||||||
|
r.node = node
|
||||||
|
r.identity = identity
|
||||||
r.servers = servers
|
r.servers = servers
|
||||||
r.registrationPeriod = registrationPeriod
|
r.registrationPeriod = registrationPeriod
|
||||||
r.bucketSize = bucketSize
|
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
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +43,7 @@ func NewRendezvousWithENR(servers []ma.Multiaddr, record enr.Record) *Rendezvous
|
||||||
r.servers = servers
|
r.servers = servers
|
||||||
r.registrationPeriod = registrationPeriod
|
r.registrationPeriod = registrationPeriod
|
||||||
r.bucketSize = bucketSize
|
r.bucketSize = bucketSize
|
||||||
r.record = record
|
r.record = &record
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +61,11 @@ type Rendezvous struct {
|
||||||
servers []ma.Multiaddr
|
servers []ma.Multiaddr
|
||||||
registrationPeriod time.Duration
|
registrationPeriod time.Duration
|
||||||
bucketSize int
|
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 {
|
func (r *Rendezvous) Running() bool {
|
||||||
|
@ -93,7 +96,30 @@ func (r *Rendezvous) Stop() error {
|
||||||
return nil
|
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))]
|
srv := r.servers[rand.Intn(len(r.servers))]
|
||||||
ctx, cancel := context.WithTimeout(r.rootCtx, requestTimeout)
|
ctx, cancel := context.WithTimeout(r.rootCtx, requestTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -101,7 +127,7 @@ func (r *Rendezvous) register(topic string) error {
|
||||||
r.mu.RLock()
|
r.mu.RLock()
|
||||||
defer r.mu.RUnlock()
|
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 {
|
if err != nil {
|
||||||
log.Error("error registering", "topic", topic, "rendezvous server", srv, "err", err)
|
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.
|
// Register renews registration in the specified server.
|
||||||
func (r *Rendezvous) Register(topic string, stop chan struct{}) error {
|
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
|
// sending registration more often than the whole registraton period
|
||||||
// will ensure that it won't be accidentally removed
|
// will ensure that it won't be accidentally removed
|
||||||
ticker := time.NewTicker(r.registrationPeriod / 2)
|
ticker := time.NewTicker(r.registrationPeriod / 2)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
if err := r.register(topic); err == context.Canceled {
|
if err := r.register(topic, record); err == context.Canceled {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +154,7 @@ func (r *Rendezvous) Register(topic string, stop chan struct{}) error {
|
||||||
case <-stop:
|
case <-stop:
|
||||||
return nil
|
return nil
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if err := r.register(topic); err == context.Canceled {
|
if err := r.register(topic, record); err == context.Canceled {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||||
lcrypto "github.com/libp2p/go-libp2p-crypto"
|
lcrypto "github.com/libp2p/go-libp2p-crypto"
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
"github.com/status-im/rendezvous/server"
|
"github.com/status-im/rendezvous/server"
|
||||||
|
@ -60,6 +61,18 @@ func TestRendezvousDiscovery(t *testing.T) {
|
||||||
close(period)
|
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) {
|
func BenchmarkRendezvousStart(b *testing.B) {
|
||||||
identity, err := crypto.GenerateKey()
|
identity, err := crypto.GenerateKey()
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
|
|
Loading…
Reference in New Issue