github.com/amazechain/amc@v0.1.3/internal/p2p/pubsub_filter.go (about) 1 package p2p 2 3 import ( 4 "fmt" 5 "github.com/amazechain/amc/internal/p2p/encoder" 6 "strings" 7 8 pubsub "github.com/libp2p/go-libp2p-pubsub" 9 pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" 10 "github.com/libp2p/go-libp2p/core/peer" 11 ) 12 13 // It is set at this limit to handle the possibility 14 // of double topic subscriptions at fork boundaries. 15 // -> 64 Attestation Subnets * 2. 16 // -> 4 Sync Committee Subnets * 2. 17 // -> Block,Aggregate,ProposerSlashing,AttesterSlashing,Exits,SyncContribution * 2. 18 const pubsubSubscriptionRequestLimit = 200 19 20 // CanSubscribe returns true if the topic is of interest and we could subscribe to it. 21 func (s *Service) CanSubscribe(topic string) bool { 22 parts := strings.Split(topic, "/") 23 if len(parts) != 5 { 24 return false 25 } 26 // The topic must start with a slash, which means the first part will be empty. 27 if parts[0] != "" { 28 return false 29 } 30 if parts[1] != "amc" { 31 return false 32 } 33 34 //fork 35 if parts[4] != encoder.ProtocolSuffixSSZSnappy { 36 return false 37 } 38 39 // Check the incoming topic matches any topic mapping. This includes a check for part[3]. 40 for gt := range gossipTopicMappings { 41 if _, err := scanfcheck(strings.Join(parts[0:4], "/"), gt); err == nil { 42 return true 43 } 44 } 45 46 return false 47 } 48 49 // FilterIncomingSubscriptions is invoked for all RPCs containing subscription notifications. 50 // This method returns only the topics of interest and may return an error if the subscription 51 // request contains too many topics. 52 func (s *Service) FilterIncomingSubscriptions(_ peer.ID, subs []*pubsubpb.RPC_SubOpts) ([]*pubsubpb.RPC_SubOpts, error) { 53 if len(subs) > pubsubSubscriptionRequestLimit { 54 return nil, pubsub.ErrTooManySubscriptions 55 } 56 57 return pubsub.FilterSubscriptions(subs, s.CanSubscribe), nil 58 } 59 60 // scanfcheck uses fmt.Sscanf to check that a given string matches expected format. This method 61 // returns the number of formatting substitutions matched and error if the string does not match 62 // the expected format. Note: this method only accepts integer compatible formatting substitutions 63 // such as %d or %x. 64 func scanfcheck(input, format string) (int, error) { 65 var t int 66 // Sscanf requires argument pointers with the appropriate type to load the value from the input. 67 // This method only checks that the input conforms to the format, the arguments are not used and 68 // therefore we can reuse the same integer pointer. 69 var cnt = strings.Count(format, "%") 70 var args []interface{} 71 for i := 0; i < cnt; i++ { 72 args = append(args, &t) 73 } 74 return fmt.Sscanf(input, format, args...) 75 }