fix_: panic when enr exceeds 300 bytes (#5446)
This commit is contained in:
parent
131cfe7b3d
commit
0c470854ef
2
go.mod
2
go.mod
|
@ -93,7 +93,7 @@ require (
|
||||||
github.com/schollz/peerdiscovery v1.7.0
|
github.com/schollz/peerdiscovery v1.7.0
|
||||||
github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7
|
github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7
|
||||||
github.com/urfave/cli/v2 v2.27.2
|
github.com/urfave/cli/v2 v2.27.2
|
||||||
github.com/waku-org/go-waku v0.8.1-0.20240626004844-19a47a1ac1f5
|
github.com/waku-org/go-waku v0.8.1-0.20240628140035-3604bf39ad28
|
||||||
github.com/wk8/go-ordered-map/v2 v2.1.7
|
github.com/wk8/go-ordered-map/v2 v2.1.7
|
||||||
github.com/yeqown/go-qrcode/v2 v2.2.1
|
github.com/yeqown/go-qrcode/v2 v2.2.1
|
||||||
github.com/yeqown/go-qrcode/writer/standard v1.2.1
|
github.com/yeqown/go-qrcode/writer/standard v1.2.1
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -2137,8 +2137,8 @@ github.com/waku-org/go-discover v0.0.0-20240506173252-4912704efdc5 h1:4K3IS97Jry
|
||||||
github.com/waku-org/go-discover v0.0.0-20240506173252-4912704efdc5/go.mod h1:eBHgM6T4EG0RZzxpxKy+rGz/6Dw2Nd8DWxS0lm9ESDw=
|
github.com/waku-org/go-discover v0.0.0-20240506173252-4912704efdc5/go.mod h1:eBHgM6T4EG0RZzxpxKy+rGz/6Dw2Nd8DWxS0lm9ESDw=
|
||||||
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20240110193335-a67d1cc760a0 h1:R4YYx2QamhBRl/moIxkDCNW+OP7AHbyWLBygDc/xIMo=
|
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20240110193335-a67d1cc760a0 h1:R4YYx2QamhBRl/moIxkDCNW+OP7AHbyWLBygDc/xIMo=
|
||||||
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20240110193335-a67d1cc760a0/go.mod h1:EhZP9fee0DYjKH/IOQvoNSy1tSHp2iZadsHGphcAJgY=
|
github.com/waku-org/go-libp2p-rendezvous v0.0.0-20240110193335-a67d1cc760a0/go.mod h1:EhZP9fee0DYjKH/IOQvoNSy1tSHp2iZadsHGphcAJgY=
|
||||||
github.com/waku-org/go-waku v0.8.1-0.20240626004844-19a47a1ac1f5 h1:9UyIIy/IvlJB2nHIXydne6OfNfOWPPL08+XmCI3iEBo=
|
github.com/waku-org/go-waku v0.8.1-0.20240628140035-3604bf39ad28 h1:7BqEcKgJs9QNzrLlC4jn1opCjGKZxNX2B/AVqhsvwzw=
|
||||||
github.com/waku-org/go-waku v0.8.1-0.20240626004844-19a47a1ac1f5/go.mod h1:biffO55kWbvfO8jdu/aAPiWcmozrfFKPum4EMFDib+k=
|
github.com/waku-org/go-waku v0.8.1-0.20240628140035-3604bf39ad28/go.mod h1:fHQ6WCSAlTollYHvAeZeO+d7lOYwcvQxHk+DyGLeoMI=
|
||||||
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59 h1:jisj+OCI6QydLtFq3Pyhu49wl9ytPN7oAHjMfepHDrA=
|
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59 h1:jisj+OCI6QydLtFq3Pyhu49wl9ytPN7oAHjMfepHDrA=
|
||||||
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59/go.mod h1:1PdBdPzyTaKt3VnpAHk3zj+r9dXPFOr3IHZP9nFle6E=
|
github.com/waku-org/go-zerokit-rln v0.1.14-0.20240102145250-fa738c0bdf59/go.mod h1:1PdBdPzyTaKt3VnpAHk3zj+r9dXPFOr3IHZP9nFle6E=
|
||||||
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b h1:KgZVhsLkxsj5gb/FfndSCQu6VYwALrCOgYI3poR95yE=
|
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20230916172309-ee0ee61dde2b h1:KgZVhsLkxsj5gb/FfndSCQu6VYwALrCOgYI3poR95yE=
|
||||||
|
|
|
@ -23,6 +23,12 @@ func (w *WakuNode) updateLocalNode(localnode *enode.LocalNode, multiaddrs []ma.M
|
||||||
options = append(options, wenr.WithUDPPort(udpPort))
|
options = append(options, wenr.WithUDPPort(udpPort))
|
||||||
options = append(options, wenr.WithWakuBitfield(wakuFlags))
|
options = append(options, wenr.WithWakuBitfield(wakuFlags))
|
||||||
|
|
||||||
|
// Reset ENR fields
|
||||||
|
wenr.DeleteField(localnode, wenr.MultiaddrENRField)
|
||||||
|
wenr.DeleteField(localnode, enr.TCP(0).ENRKey())
|
||||||
|
wenr.DeleteField(localnode, enr.IPv4{}.ENRKey())
|
||||||
|
wenr.DeleteField(localnode, enr.IPv6{}.ENRKey())
|
||||||
|
|
||||||
if advertiseAddr != nil {
|
if advertiseAddr != nil {
|
||||||
// An advertised address disables libp2p address updates
|
// An advertised address disables libp2p address updates
|
||||||
// and discv5 predictions
|
// and discv5 predictions
|
||||||
|
@ -245,7 +251,6 @@ func selectCircuitRelayListenAddresses(ctx context.Context, addresses []ma.Multi
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func filter0Port(addresses []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
func filter0Port(addresses []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
||||||
var result []ma.Multiaddr
|
var result []ma.Multiaddr
|
||||||
for _, addr := range addresses {
|
for _, addr := range addresses {
|
||||||
|
|
|
@ -270,7 +270,7 @@ func New(opts ...WakuNodeOption) (*WakuNode, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.peerExchange, err = peer_exchange.NewWakuPeerExchange(w.DiscV5(), w.peerConnector, w.peermanager, w.opts.prometheusReg, w.log)
|
w.peerExchange, err = peer_exchange.NewWakuPeerExchange(w.DiscV5(), w.opts.clusterID, w.peerConnector, w.peermanager, w.opts.prometheusReg, w.log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||||
"github.com/multiformats/go-multiaddr"
|
"github.com/multiformats/go-multiaddr"
|
||||||
|
@ -26,16 +27,32 @@ type ENROption func(*enode.LocalNode) error
|
||||||
|
|
||||||
func WithMultiaddress(multiaddrs ...multiaddr.Multiaddr) ENROption {
|
func WithMultiaddress(multiaddrs ...multiaddr.Multiaddr) ENROption {
|
||||||
return func(localnode *enode.LocalNode) (err error) {
|
return func(localnode *enode.LocalNode) (err error) {
|
||||||
|
|
||||||
// Randomly shuffle multiaddresses
|
// Randomly shuffle multiaddresses
|
||||||
rand.Shuffle(len(multiaddrs), func(i, j int) { multiaddrs[i], multiaddrs[j] = multiaddrs[j], multiaddrs[i] })
|
rand.Shuffle(len(multiaddrs), func(i, j int) { multiaddrs[i], multiaddrs[j] = multiaddrs[j], multiaddrs[i] })
|
||||||
|
|
||||||
|
// Testing how many multiaddresses we can write before we exceed the limit
|
||||||
|
// By simulating what the localnode does when signing the enr, but without
|
||||||
|
// causing a panic
|
||||||
|
|
||||||
|
privk, err := crypto.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Adding extra multiaddresses. Should probably not exceed the enr max size of 300bytes
|
// Adding extra multiaddresses. Should probably not exceed the enr max size of 300bytes
|
||||||
failedOnceWritingENR := false
|
failedOnceWritingENR := false
|
||||||
couldWriteENRatLeastOnce := false
|
couldWriteENRatLeastOnce := false
|
||||||
successIdx := -1
|
successIdx := -1
|
||||||
for i := len(multiaddrs); i > 0; i-- {
|
for i := len(multiaddrs); i > 0; i-- {
|
||||||
err = writeMultiaddressField(localnode, multiaddrs[0:i])
|
cpy := localnode.Node().Record() // Record() creates a copy for the current iteration
|
||||||
|
// Copy all the entries that might not have been written in the ENR record due to the
|
||||||
|
// async nature of localnode.Set
|
||||||
|
for _, entry := range localnode.Entries() {
|
||||||
|
cpy.Set(entry)
|
||||||
|
}
|
||||||
|
cpy.Set(enr.WithEntry(MultiaddrENRField, marshalMultiaddress(multiaddrs[0:i])))
|
||||||
|
cpy.SetSeq(localnode.Seq() + 1)
|
||||||
|
err = enode.SignV4(cpy, privk)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
couldWriteENRatLeastOnce = true
|
couldWriteENRatLeastOnce = true
|
||||||
successIdx = i
|
successIdx = i
|
||||||
|
@ -46,10 +63,7 @@ func WithMultiaddress(multiaddrs ...multiaddr.Multiaddr) ENROption {
|
||||||
|
|
||||||
if failedOnceWritingENR && couldWriteENRatLeastOnce {
|
if failedOnceWritingENR && couldWriteENRatLeastOnce {
|
||||||
// Could write a subset of multiaddresses but not all
|
// Could write a subset of multiaddresses but not all
|
||||||
err = writeMultiaddressField(localnode, multiaddrs[0:successIdx])
|
writeMultiaddressField(localnode, multiaddrs[0:successIdx])
|
||||||
if err != nil {
|
|
||||||
return errors.New("could not write new ENR")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -110,15 +124,7 @@ func Update(logger *zap.Logger, localnode *enode.LocalNode, enrOptions ...ENROpt
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeMultiaddressField(localnode *enode.LocalNode, addrAggr []multiaddr.Multiaddr) (err error) {
|
func marshalMultiaddress(addrAggr []multiaddr.Multiaddr) []byte {
|
||||||
defer func() {
|
|
||||||
if e := recover(); e != nil {
|
|
||||||
// Deleting the multiaddr entry, as we could not write it succesfully
|
|
||||||
localnode.Delete(enr.WithEntry(MultiaddrENRField, struct{}{}))
|
|
||||||
err = errors.New("could not write enr record")
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var fieldRaw []byte
|
var fieldRaw []byte
|
||||||
for _, addr := range addrAggr {
|
for _, addr := range addrAggr {
|
||||||
maRaw := addr.Bytes()
|
maRaw := addr.Bytes()
|
||||||
|
@ -128,11 +134,14 @@ func writeMultiaddressField(localnode *enode.LocalNode, addrAggr []multiaddr.Mul
|
||||||
fieldRaw = append(fieldRaw, maSize...)
|
fieldRaw = append(fieldRaw, maSize...)
|
||||||
fieldRaw = append(fieldRaw, maRaw...)
|
fieldRaw = append(fieldRaw, maRaw...)
|
||||||
}
|
}
|
||||||
|
return fieldRaw
|
||||||
localnode.Set(enr.WithEntry(MultiaddrENRField, fieldRaw))
|
}
|
||||||
|
|
||||||
// This is to trigger the signing record err due to exceeding 300bytes limit
|
func writeMultiaddressField(localnode *enode.LocalNode, addrAggr []multiaddr.Multiaddr) {
|
||||||
_ = localnode.Node()
|
fieldRaw := marshalMultiaddress(addrAggr)
|
||||||
|
localnode.Set(enr.WithEntry(MultiaddrENRField, fieldRaw))
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
func DeleteField(localnode *enode.LocalNode, field string) {
|
||||||
|
localnode.Delete(enr.WithEntry(field, struct{}{}))
|
||||||
}
|
}
|
||||||
|
|
21
vendor/github.com/waku-org/go-waku/waku/v2/protocol/peer_exchange/enr_cache.go
generated
vendored
21
vendor/github.com/waku-org/go-waku/waku/v2/protocol/peer_exchange/enr_cache.go
generated
vendored
|
@ -6,25 +6,40 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
|
|
||||||
|
wenr "github.com/waku-org/go-waku/waku/v2/protocol/enr"
|
||||||
"github.com/waku-org/go-waku/waku/v2/protocol/peer_exchange/pb"
|
"github.com/waku-org/go-waku/waku/v2/protocol/peer_exchange/pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
// simpleLRU internal uses container/list, which is ring buffer(double linked list)
|
// simpleLRU internal uses container/list, which is ring buffer(double linked list)
|
||||||
type enrCache struct {
|
type enrCache struct {
|
||||||
// using lru, saves us from periodically cleaning the cache to mauintain a certain size
|
// using lru, saves us from periodically cleaning the cache to mauintain a certain size
|
||||||
data *shardLRU
|
data *shardLRU
|
||||||
|
clusterID uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// err on negative size
|
// err on negative size
|
||||||
func newEnrCache(size int) *enrCache {
|
func newEnrCache(size int, clusterID uint16) *enrCache {
|
||||||
inner := newShardLRU(int(size))
|
inner := newShardLRU(int(size))
|
||||||
return &enrCache{
|
return &enrCache{
|
||||||
data: inner,
|
data: inner,
|
||||||
|
clusterID: clusterID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// updating cache
|
// updating cache
|
||||||
func (c *enrCache) updateCache(node *enode.Node) error {
|
func (c *enrCache) updateCache(node *enode.Node) error {
|
||||||
|
if c.clusterID != 0 {
|
||||||
|
rs, err := wenr.RelaySharding(node.Record())
|
||||||
|
if err != nil || rs == nil {
|
||||||
|
// Node does not contain valid shard information, ignoring...
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.ClusterID != c.clusterID {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
currNode := c.data.Get(node.ID())
|
currNode := c.data.Get(node.ID())
|
||||||
if currNode == nil || node.Seq() > currNode.Seq() {
|
if currNode == nil || node.Seq() > currNode.Seq() {
|
||||||
return c.data.Add(node)
|
return c.data.Add(node)
|
||||||
|
|
|
@ -54,12 +54,12 @@ type WakuPeerExchange struct {
|
||||||
// NewWakuPeerExchange returns a new instance of WakuPeerExchange struct
|
// NewWakuPeerExchange returns a new instance of WakuPeerExchange struct
|
||||||
// Takes an optional peermanager if WakuPeerExchange is being created along with WakuNode.
|
// Takes an optional peermanager if WakuPeerExchange is being created along with WakuNode.
|
||||||
// If using libp2p host, then pass peermanager as nil
|
// If using libp2p host, then pass peermanager as nil
|
||||||
func NewWakuPeerExchange(disc *discv5.DiscoveryV5, peerConnector PeerConnector, pm *peermanager.PeerManager, reg prometheus.Registerer, log *zap.Logger, opts ...Option) (*WakuPeerExchange, error) {
|
func NewWakuPeerExchange(disc *discv5.DiscoveryV5, clusterID uint16, peerConnector PeerConnector, pm *peermanager.PeerManager, reg prometheus.Registerer, log *zap.Logger, opts ...Option) (*WakuPeerExchange, error) {
|
||||||
wakuPX := new(WakuPeerExchange)
|
wakuPX := new(WakuPeerExchange)
|
||||||
wakuPX.disc = disc
|
wakuPX.disc = disc
|
||||||
wakuPX.metrics = newMetrics(reg)
|
wakuPX.metrics = newMetrics(reg)
|
||||||
wakuPX.log = log.Named("wakupx")
|
wakuPX.log = log.Named("wakupx")
|
||||||
wakuPX.enrCache = newEnrCache(MaxCacheSize)
|
wakuPX.enrCache = newEnrCache(MaxCacheSize, clusterID)
|
||||||
wakuPX.peerConnector = peerConnector
|
wakuPX.peerConnector = peerConnector
|
||||||
wakuPX.pm = pm
|
wakuPX.pm = pm
|
||||||
wakuPX.CommonService = service.NewCommonService()
|
wakuPX.CommonService = service.NewCommonService()
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ github.com/waku-org/go-discover/discover/v5wire
|
||||||
github.com/waku-org/go-libp2p-rendezvous
|
github.com/waku-org/go-libp2p-rendezvous
|
||||||
github.com/waku-org/go-libp2p-rendezvous/db
|
github.com/waku-org/go-libp2p-rendezvous/db
|
||||||
github.com/waku-org/go-libp2p-rendezvous/pb
|
github.com/waku-org/go-libp2p-rendezvous/pb
|
||||||
# github.com/waku-org/go-waku v0.8.1-0.20240626004844-19a47a1ac1f5
|
# github.com/waku-org/go-waku v0.8.1-0.20240628140035-3604bf39ad28
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/waku-org/go-waku/logging
|
github.com/waku-org/go-waku/logging
|
||||||
github.com/waku-org/go-waku/tests
|
github.com/waku-org/go-waku/tests
|
||||||
|
|
Loading…
Reference in New Issue