diff --git a/node/p2p/blossomsub.go b/node/p2p/blossomsub.go index 5c702d1..7cdcf65 100644 --- a/node/p2p/blossomsub.go +++ b/node/p2p/blossomsub.go @@ -416,7 +416,18 @@ func NewBlossomSub( GraylistThreshold: -10000, AcceptPXThreshold: 1, OpportunisticGraftThreshold: 2, - })) + }, + )) + blossomOpts = append(blossomOpts, blossomsub.WithPeerFilter(internal.NewStaticPeerFilter( + // We filter out the bootstrap peers explicitly from BlossomSub + // as they do not subscribe to relevant topics anymore. + // However, the beacon is one of the bootstrap peers usually + // and as such it gets special treatment - it is the only bootstrap + // peer which is engaged in the network. + []peer.ID{internal.BeaconPeerID(uint(p2pConfig.Network))}, + internal.PeerAddrInfosToPeerIDSlice(bootstrappers), + true, + ))) params := mergeDefaults(p2pConfig) rt := blossomsub.NewBlossomSubRouter(h, params, bs.network) diff --git a/node/p2p/internal/beacon.go b/node/p2p/internal/beacon.go new file mode 100644 index 0000000..d7ba01c --- /dev/null +++ b/node/p2p/internal/beacon.go @@ -0,0 +1,24 @@ +package internal + +import ( + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "source.quilibrium.com/quilibrium/monorepo/node/config" +) + +// BeaconPeerID returns the peer ID of the beacon node. +func BeaconPeerID(network uint) peer.ID { + genesis, err := config.DownloadAndVerifyGenesis(network) + if err != nil { + panic(err) + } + pub, err := crypto.UnmarshalEd448PublicKey(genesis.Beacon) + if err != nil { + panic(err) + } + peerID, err := peer.IDFromPublicKey(pub) + if err != nil { + panic(err) + } + return peerID +} diff --git a/node/p2p/internal/peer_filter.go b/node/p2p/internal/peer_filter.go new file mode 100644 index 0000000..54d78d5 --- /dev/null +++ b/node/p2p/internal/peer_filter.go @@ -0,0 +1,31 @@ +package internal + +import ( + "github.com/libp2p/go-libp2p/core/peer" + blossomsub "source.quilibrium.com/quilibrium/monorepo/go-libp2p-blossomsub" +) + +// NewStaticPeerFilter creates a new static peer filter. +// The allowList is a list of peers that are allowed to mesh. +// The blockList is a list of peers that are blocked from meshing. +// The def is the default value for peers that are not in the allowList or blockList. +// The allowList has priority over the blockList. +func NewStaticPeerFilter(allowList, blockList []peer.ID, def bool) blossomsub.PeerFilter { + allowed := make(map[peer.ID]struct{}) + for _, p := range allowList { + allowed[p] = struct{}{} + } + blocked := make(map[peer.ID]struct{}) + for _, p := range blockList { + blocked[p] = struct{}{} + } + return func(peerID peer.ID, _ []byte) bool { + if _, ok := allowed[peerID]; ok { + return true + } + if _, ok := blocked[peerID]; ok { + return false + } + return def + } +}