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/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7
|
||||
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/yeqown/go-qrcode/v2 v2.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-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-waku v0.8.1-0.20240626004844-19a47a1ac1f5 h1:9UyIIy/IvlJB2nHIXydne6OfNfOWPPL08+XmCI3iEBo=
|
||||
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 h1:7BqEcKgJs9QNzrLlC4jn1opCjGKZxNX2B/AVqhsvwzw=
|
||||
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/go.mod h1:1PdBdPzyTaKt3VnpAHk3zj+r9dXPFOr3IHZP9nFle6E=
|
||||
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.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 {
|
||||
// An advertised address disables libp2p address updates
|
||||
// and discv5 predictions
|
||||
|
@ -245,7 +251,6 @@ func selectCircuitRelayListenAddresses(ctx context.Context, addresses []ma.Multi
|
|||
return result, nil
|
||||
}
|
||||
|
||||
|
||||
func filter0Port(addresses []ma.Multiaddr) ([]ma.Multiaddr, error) {
|
||||
var result []ma.Multiaddr
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"math/rand"
|
||||
"net"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/enr"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
|
@ -26,16 +27,32 @@ type ENROption func(*enode.LocalNode) error
|
|||
|
||||
func WithMultiaddress(multiaddrs ...multiaddr.Multiaddr) ENROption {
|
||||
return func(localnode *enode.LocalNode) (err error) {
|
||||
|
||||
// Randomly shuffle multiaddresses
|
||||
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
|
||||
failedOnceWritingENR := false
|
||||
couldWriteENRatLeastOnce := false
|
||||
successIdx := -1
|
||||
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 {
|
||||
couldWriteENRatLeastOnce = true
|
||||
successIdx = i
|
||||
|
@ -46,10 +63,7 @@ func WithMultiaddress(multiaddrs ...multiaddr.Multiaddr) ENROption {
|
|||
|
||||
if failedOnceWritingENR && couldWriteENRatLeastOnce {
|
||||
// Could write a subset of multiaddresses but not all
|
||||
err = writeMultiaddressField(localnode, multiaddrs[0:successIdx])
|
||||
if err != nil {
|
||||
return errors.New("could not write new ENR")
|
||||
}
|
||||
writeMultiaddressField(localnode, multiaddrs[0:successIdx])
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -110,15 +124,7 @@ func Update(logger *zap.Logger, localnode *enode.LocalNode, enrOptions ...ENROpt
|
|||
return nil
|
||||
}
|
||||
|
||||
func writeMultiaddressField(localnode *enode.LocalNode, addrAggr []multiaddr.Multiaddr) (err error) {
|
||||
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")
|
||||
}
|
||||
}()
|
||||
|
||||
func marshalMultiaddress(addrAggr []multiaddr.Multiaddr) []byte {
|
||||
var fieldRaw []byte
|
||||
for _, addr := range addrAggr {
|
||||
maRaw := addr.Bytes()
|
||||
|
@ -128,11 +134,14 @@ func writeMultiaddressField(localnode *enode.LocalNode, addrAggr []multiaddr.Mul
|
|||
fieldRaw = append(fieldRaw, maSize...)
|
||||
fieldRaw = append(fieldRaw, maRaw...)
|
||||
}
|
||||
|
||||
localnode.Set(enr.WithEntry(MultiaddrENRField, fieldRaw))
|
||||
|
||||
// This is to trigger the signing record err due to exceeding 300bytes limit
|
||||
_ = localnode.Node()
|
||||
|
||||
return nil
|
||||
return fieldRaw
|
||||
}
|
||||
|
||||
func writeMultiaddressField(localnode *enode.LocalNode, addrAggr []multiaddr.Multiaddr) {
|
||||
fieldRaw := marshalMultiaddress(addrAggr)
|
||||
localnode.Set(enr.WithEntry(MultiaddrENRField, fieldRaw))
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
wenr "github.com/waku-org/go-waku/waku/v2/protocol/enr"
|
||||
"github.com/waku-org/go-waku/waku/v2/protocol/peer_exchange/pb"
|
||||
)
|
||||
|
||||
// simpleLRU internal uses container/list, which is ring buffer(double linked list)
|
||||
type enrCache struct {
|
||||
// using lru, saves us from periodically cleaning the cache to mauintain a certain size
|
||||
data *shardLRU
|
||||
data *shardLRU
|
||||
clusterID uint16
|
||||
}
|
||||
|
||||
// err on negative size
|
||||
func newEnrCache(size int) *enrCache {
|
||||
func newEnrCache(size int, clusterID uint16) *enrCache {
|
||||
inner := newShardLRU(int(size))
|
||||
return &enrCache{
|
||||
data: inner,
|
||||
data: inner,
|
||||
clusterID: clusterID,
|
||||
}
|
||||
}
|
||||
|
||||
// updating cache
|
||||
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())
|
||||
if currNode == nil || node.Seq() > currNode.Seq() {
|
||||
return c.data.Add(node)
|
||||
|
|
|
@ -54,12 +54,12 @@ type WakuPeerExchange struct {
|
|||
// NewWakuPeerExchange returns a new instance of WakuPeerExchange struct
|
||||
// Takes an optional peermanager if WakuPeerExchange is being created along with WakuNode.
|
||||
// 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.disc = disc
|
||||
wakuPX.metrics = newMetrics(reg)
|
||||
wakuPX.log = log.Named("wakupx")
|
||||
wakuPX.enrCache = newEnrCache(MaxCacheSize)
|
||||
wakuPX.enrCache = newEnrCache(MaxCacheSize, clusterID)
|
||||
wakuPX.peerConnector = peerConnector
|
||||
wakuPX.pm = pm
|
||||
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/db
|
||||
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
|
||||
github.com/waku-org/go-waku/logging
|
||||
github.com/waku-org/go-waku/tests
|
||||
|
|
Loading…
Reference in New Issue