mirror of https://github.com/status-im/go-waku.git
fix: wakuflag for ListenAddresses ENR (#171)
Also, reorganize code in utils package
This commit is contained in:
parent
23cbb24a94
commit
ed91f47ff0
|
@ -61,11 +61,6 @@ type discV5Parameters struct {
|
|||
advertiseAddr *net.IP
|
||||
}
|
||||
|
||||
const WakuENRField = "waku2"
|
||||
|
||||
// WakuEnrBitfield is a8-bit flag field to indicate Waku capabilities. Only the 4 LSBs are currently defined according to RFC31 (https://rfc.vac.dev/spec/31/).
|
||||
type WakuEnrBitfield = uint8
|
||||
|
||||
type DiscoveryV5Option func(*discV5Parameters)
|
||||
|
||||
func WithAutoUpdate(autoUpdate bool) DiscoveryV5Option {
|
||||
|
@ -98,29 +93,7 @@ func DefaultOptions() []DiscoveryV5Option {
|
|||
}
|
||||
}
|
||||
|
||||
func NewWakuEnrBitfield(lightpush, filter, store, relay bool) WakuEnrBitfield {
|
||||
var v uint8 = 0
|
||||
|
||||
if lightpush {
|
||||
v |= (1 << 3)
|
||||
}
|
||||
|
||||
if filter {
|
||||
v |= (1 << 2)
|
||||
}
|
||||
|
||||
if store {
|
||||
v |= (1 << 1)
|
||||
}
|
||||
|
||||
if relay {
|
||||
v |= (1 << 0)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func NewDiscoveryV5(host host.Host, ipAddr net.IP, tcpPort int, priv *ecdsa.PrivateKey, wakuFlags WakuEnrBitfield, opts ...DiscoveryV5Option) (*DiscoveryV5, error) {
|
||||
func NewDiscoveryV5(host host.Host, ipAddr net.IP, tcpPort int, priv *ecdsa.PrivateKey, wakuFlags utils.WakuEnrBitfield, opts ...DiscoveryV5Option) (*DiscoveryV5, error) {
|
||||
params := new(discV5Parameters)
|
||||
optList := DefaultOptions()
|
||||
optList = append(optList, opts...)
|
||||
|
@ -161,7 +134,7 @@ func NewDiscoveryV5(host host.Host, ipAddr net.IP, tcpPort int, priv *ecdsa.Priv
|
|||
}, nil
|
||||
}
|
||||
|
||||
func newLocalnode(priv *ecdsa.PrivateKey, ipAddr net.IP, udpPort int, tcpPort int, wakuFlags WakuEnrBitfield, advertiseAddr *net.IP) (*enode.LocalNode, error) {
|
||||
func newLocalnode(priv *ecdsa.PrivateKey, ipAddr net.IP, udpPort int, tcpPort int, wakuFlags utils.WakuEnrBitfield, advertiseAddr *net.IP) (*enode.LocalNode, error) {
|
||||
db, err := enode.OpenDB("")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -169,7 +142,7 @@ func newLocalnode(priv *ecdsa.PrivateKey, ipAddr net.IP, udpPort int, tcpPort in
|
|||
localnode := enode.NewLocalNode(db, priv)
|
||||
localnode.SetFallbackIP(net.IP{127, 0, 0, 1})
|
||||
localnode.SetFallbackUDP(udpPort)
|
||||
localnode.Set(enr.WithEntry(WakuENRField, wakuFlags))
|
||||
localnode.Set(enr.WithEntry(utils.WakuENRField, wakuFlags))
|
||||
localnode.Set(enr.IP(ipAddr))
|
||||
|
||||
if udpPort > 0 && udpPort <= math.MaxUint16 {
|
||||
|
@ -303,8 +276,8 @@ func (d *DiscoveryV5) UpdateAddr(addr net.IP) error {
|
|||
}
|
||||
|
||||
func isWakuNode(node *enode.Node) bool {
|
||||
enrField := new(WakuEnrBitfield)
|
||||
if err := node.Record().Load(enr.WithEntry(WakuENRField, &enrField)); err != nil {
|
||||
enrField := new(utils.WakuEnrBitfield)
|
||||
if err := node.Record().Load(enr.WithEntry(utils.WakuENRField, &enrField)); err != nil {
|
||||
if !enr.IsNotFound(err) {
|
||||
log.Error("could not retrieve port for enr ", node)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/status-im/go-waku/tests"
|
||||
"github.com/status-im/go-waku/waku/v2/utils"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/libp2p/go-libp2p"
|
||||
|
@ -48,19 +49,19 @@ func TestDiscV5(t *testing.T) {
|
|||
host1, tcpPort1, prvKey1 := createHost(t)
|
||||
udpPort1, err := tests.FindFreePort(t, "127.0.0.1", 3)
|
||||
require.NoError(t, err)
|
||||
d1, err := NewDiscoveryV5(host1, net.IPv4(127, 0, 0, 1), tcpPort1, prvKey1, NewWakuEnrBitfield(true, true, true, true), WithUDPPort(udpPort1))
|
||||
d1, err := NewDiscoveryV5(host1, net.IPv4(127, 0, 0, 1), tcpPort1, prvKey1, utils.NewWakuEnrBitfield(true, true, true, true), WithUDPPort(udpPort1))
|
||||
require.NoError(t, err)
|
||||
|
||||
host2, tcpPort2, prvKey2 := createHost(t)
|
||||
udpPort2, err := tests.FindFreePort(t, "127.0.0.1", 3)
|
||||
require.NoError(t, err)
|
||||
d2, err := NewDiscoveryV5(host2, net.IPv4(127, 0, 0, 1), tcpPort2, prvKey2, NewWakuEnrBitfield(true, true, true, true), WithUDPPort(udpPort2), WithBootnodes([]*enode.Node{d1.localnode.Node()}))
|
||||
d2, err := NewDiscoveryV5(host2, net.IPv4(127, 0, 0, 1), tcpPort2, prvKey2, utils.NewWakuEnrBitfield(true, true, true, true), WithUDPPort(udpPort2), WithBootnodes([]*enode.Node{d1.localnode.Node()}))
|
||||
require.NoError(t, err)
|
||||
|
||||
host3, tcpPort3, prvKey3 := createHost(t)
|
||||
udpPort3, err := tests.FindFreePort(t, "127.0.0.1", 3)
|
||||
require.NoError(t, err)
|
||||
d3, err := NewDiscoveryV5(host3, net.IPv4(127, 0, 0, 1), tcpPort3, prvKey3, NewWakuEnrBitfield(true, true, true, true), WithUDPPort(udpPort3), WithBootnodes([]*enode.Node{d2.localnode.Node()}))
|
||||
d3, err := NewDiscoveryV5(host3, net.IPv4(127, 0, 0, 1), tcpPort3, prvKey3, utils.NewWakuEnrBitfield(true, true, true, true), WithUDPPort(udpPort3), WithBootnodes([]*enode.Node{d2.localnode.Node()}))
|
||||
require.NoError(t, err)
|
||||
|
||||
defer d1.Stop()
|
||||
|
|
|
@ -55,6 +55,7 @@ type WakuNode struct {
|
|||
lightPush *lightpush.WakuLightPush
|
||||
rendezvous *rendezvous.RendezvousService
|
||||
store *store.WakuStore
|
||||
wakuFlag utils.WakuEnrBitfield
|
||||
|
||||
addrChan chan ma.Multiaddr
|
||||
|
||||
|
@ -132,6 +133,7 @@ func New(ctx context.Context, opts ...WakuNodeOption) (*WakuNode, error) {
|
|||
w.wg = &sync.WaitGroup{}
|
||||
w.addrChan = make(chan ma.Multiaddr, 1024)
|
||||
w.keepAliveFails = make(map[peer.ID]int)
|
||||
w.wakuFlag = utils.NewWakuEnrBitfield(w.opts.enableLightPush, w.opts.enableFilter, w.opts.enableStore, w.opts.enableRelay)
|
||||
|
||||
if w.protocolEventSub, err = host.EventBus().Subscribe(new(event.EvtPeerProtocolsUpdated)); err != nil {
|
||||
return nil, err
|
||||
|
@ -190,7 +192,7 @@ func (w *WakuNode) logAddress(addr ma.Multiaddr) {
|
|||
|
||||
// TODO: make this optional depending on DNS Disc being enabled
|
||||
if w.opts.privKey != nil {
|
||||
enr, ip, err := utils.GetENRandIP(addr, w.opts.privKey)
|
||||
enr, ip, err := utils.GetENRandIP(addr, w.wakuFlag, w.opts.privKey)
|
||||
if err != nil {
|
||||
log.Error("could not obtain ENR record from multiaddress", err)
|
||||
} else {
|
||||
|
@ -388,8 +390,6 @@ func (w *WakuNode) mountRelay(opts ...pubsub.Option) error {
|
|||
}
|
||||
|
||||
func (w *WakuNode) mountDiscV5() error {
|
||||
wakuFlag := discv5.NewWakuEnrBitfield(w.opts.enableLightPush, w.opts.enableFilter, w.opts.enableStore, w.opts.enableRelay)
|
||||
|
||||
discV5Options := []discv5.DiscoveryV5Option{
|
||||
discv5.WithBootnodes(w.opts.discV5bootnodes),
|
||||
discv5.WithUDPPort(w.opts.udpPort),
|
||||
|
@ -413,7 +413,7 @@ func (w *WakuNode) mountDiscV5() error {
|
|||
return err
|
||||
}
|
||||
|
||||
discoveryV5, err := discv5.NewDiscoveryV5(w.Host(), net.ParseIP(ipStr), port, w.opts.privKey, wakuFlag, discV5Options...)
|
||||
discoveryV5, err := discv5.NewDiscoveryV5(w.Host(), net.ParseIP(ipStr), port, w.opts.privKey, w.wakuFlag, discV5Options...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
const WakuENRField = "waku2"
|
||||
|
||||
// WakuEnrBitfield is a8-bit flag field to indicate Waku capabilities. Only the 4 LSBs are currently defined according to RFC31 (https://rfc.vac.dev/spec/31/).
|
||||
type WakuEnrBitfield = uint8
|
||||
|
||||
func NewWakuEnrBitfield(lightpush, filter, store, relay bool) WakuEnrBitfield {
|
||||
var v uint8 = 0
|
||||
|
||||
if lightpush {
|
||||
v |= (1 << 3)
|
||||
}
|
||||
|
||||
if filter {
|
||||
v |= (1 << 2)
|
||||
}
|
||||
|
||||
if store {
|
||||
v |= (1 << 1)
|
||||
}
|
||||
|
||||
if relay {
|
||||
v |= (1 << 0)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func GetENRandIP(addr ma.Multiaddr, wakuFlags WakuEnrBitfield, privK *ecdsa.PrivateKey) (*enode.Node, *net.TCPAddr, error) {
|
||||
ip, err := addr.ValueForProtocol(ma.P_IP4)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
portStr, err := addr.ValueForProtocol(ma.P_TCP)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
r := &enr.Record{}
|
||||
|
||||
if port > 0 && port <= math.MaxUint16 {
|
||||
r.Set(enr.TCP(uint16(port))) // lgtm [go/incorrect-integer-conversion]
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("could not set port %d", port)
|
||||
}
|
||||
|
||||
r.Set(enr.IP(net.ParseIP(ip)))
|
||||
r.Set(enr.WithEntry(WakuENRField, wakuFlags))
|
||||
|
||||
err = enode.SignV4(r, privK)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
node, err := enode.New(enode.ValidSchemes, r)
|
||||
|
||||
return node, tcpAddr, err
|
||||
}
|
||||
|
||||
func EnodeToMultiAddr(node *enode.Node) (ma.Multiaddr, error) {
|
||||
peerID, err := peer.IDFromPublicKey(&ECDSAPublicKey{node.Pubkey()})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", node.IP(), node.TCP(), peerID))
|
||||
}
|
||||
|
||||
func EnodeToPeerInfo(node *enode.Node) (*peer.AddrInfo, error) {
|
||||
address, err := EnodeToMultiAddr(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return peer.AddrInfoFromP2pAddr(address)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
gcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
crypto "github.com/libp2p/go-libp2p-core/crypto"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEnodeToMultiAddr(t *testing.T) {
|
||||
enr := "enr:-IS4QAmC_o1PMi5DbR4Bh4oHVyQunZblg4bTaottPtBodAhJZvxVlWW-4rXITPNg4mwJ8cW__D9FBDc9N4mdhyMqB-EBgmlkgnY0gmlwhIbRi9KJc2VjcDI1NmsxoQOevTdO6jvv3fRruxguKR-3Ge4bcFsLeAIWEDjrfaigNoN0Y3CCdl8"
|
||||
|
||||
parsedNode := enode.MustParse(enr)
|
||||
expectedMultiAddr := "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ"
|
||||
actualMultiAddr, err := EnodeToMultiAddr(parsedNode)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedMultiAddr, actualMultiAddr.String())
|
||||
}
|
||||
|
||||
func TestGetENRandIP(t *testing.T) {
|
||||
key, _ := gcrypto.GenerateKey()
|
||||
privKey := crypto.PrivKey((*crypto.Secp256k1PrivateKey)(key))
|
||||
id, _ := peer.IDFromPublicKey(privKey.GetPublic())
|
||||
|
||||
hostAddr := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 9999}
|
||||
hostMultiAddr, _ := manet.FromNetAddr(hostAddr)
|
||||
hostInfo, _ := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", id.Pretty()))
|
||||
ogMultiaddress := hostMultiAddr.Encapsulate(hostInfo)
|
||||
|
||||
wakuFlag := NewWakuEnrBitfield(true, true, true, true)
|
||||
|
||||
node, resTCPAddr, err := GetENRandIP(ogMultiaddress, wakuFlag, key)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hostAddr, resTCPAddr)
|
||||
|
||||
parsedNode := enode.MustParse(node.String())
|
||||
resMultiaddress, err := EnodeToMultiAddr(parsedNode)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, ogMultiaddress.String(), resMultiaddress.String())
|
||||
}
|
|
@ -2,20 +2,11 @@ package utils
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
logging "github.com/ipfs/go-log"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
|
@ -122,62 +113,3 @@ func SelectPeerWithLowestRTT(ctx context.Context, host host.Host, protocolId str
|
|||
return nil, ErrNoPeersAvailable
|
||||
}
|
||||
}
|
||||
|
||||
func EnodeToMultiAddr(node *enode.Node) (ma.Multiaddr, error) {
|
||||
peerID, err := peer.IDFromPublicKey(&ECDSAPublicKey{node.Pubkey()})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", node.IP(), node.TCP(), peerID))
|
||||
}
|
||||
|
||||
func EnodeToPeerInfo(node *enode.Node) (*peer.AddrInfo, error) {
|
||||
address, err := EnodeToMultiAddr(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return peer.AddrInfoFromP2pAddr(address)
|
||||
}
|
||||
|
||||
func GetENRandIP(addr ma.Multiaddr, privK *ecdsa.PrivateKey) (*enode.Node, *net.TCPAddr, error) {
|
||||
ip, err := addr.ValueForProtocol(ma.P_IP4)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
portStr, err := addr.ValueForProtocol(ma.P_TCP)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
tcpAddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
r := &enr.Record{}
|
||||
|
||||
if port > 0 && port <= math.MaxUint16 {
|
||||
r.Set(enr.TCP(uint16(port))) // lgtm [go/incorrect-integer-conversion]
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("could not set port %d", port)
|
||||
}
|
||||
|
||||
r.Set(enr.IP(net.ParseIP(ip)))
|
||||
|
||||
err = enode.SignV4(r, privK)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
node, err := enode.New(enode.ValidSchemes, r)
|
||||
|
||||
return node, tcpAddr, err
|
||||
}
|
||||
|
|
|
@ -3,18 +3,10 @@ package utils
|
|||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
gcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
crypto "github.com/libp2p/go-libp2p-core/crypto"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p-core/peerstore"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
"github.com/status-im/go-waku/tests"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -87,33 +79,3 @@ func TestSelectPeerWithLowestRTT(t *testing.T) {
|
|||
_, err = SelectPeerWithLowestRTT(ctx, h1, proto)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestEnodeToMultiAddr(t *testing.T) {
|
||||
enr := "enr:-IS4QAmC_o1PMi5DbR4Bh4oHVyQunZblg4bTaottPtBodAhJZvxVlWW-4rXITPNg4mwJ8cW__D9FBDc9N4mdhyMqB-EBgmlkgnY0gmlwhIbRi9KJc2VjcDI1NmsxoQOevTdO6jvv3fRruxguKR-3Ge4bcFsLeAIWEDjrfaigNoN0Y3CCdl8"
|
||||
|
||||
parsedNode := enode.MustParse(enr)
|
||||
expectedMultiAddr := "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ"
|
||||
actualMultiAddr, err := EnodeToMultiAddr(parsedNode)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedMultiAddr, actualMultiAddr.String())
|
||||
}
|
||||
|
||||
func TestGetENRandIP(t *testing.T) {
|
||||
key, _ := gcrypto.GenerateKey()
|
||||
privKey := crypto.PrivKey((*crypto.Secp256k1PrivateKey)(key))
|
||||
id, _ := peer.IDFromPublicKey(privKey.GetPublic())
|
||||
|
||||
hostAddr := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 9999}
|
||||
hostMultiAddr, _ := manet.FromNetAddr(hostAddr)
|
||||
hostInfo, _ := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", id.Pretty()))
|
||||
ogMultiaddress := hostMultiAddr.Encapsulate(hostInfo)
|
||||
|
||||
node, resTCPAddr, err := GetENRandIP(ogMultiaddress, key)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hostAddr, resTCPAddr)
|
||||
|
||||
parsedNode := enode.MustParse(node.String())
|
||||
resMultiaddress, err := EnodeToMultiAddr(parsedNode)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, ogMultiaddress.String(), resMultiaddress.String())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue