github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/neorpc/rpcevent/filter.go (about) 1 package rpcevent 2 3 import ( 4 "github.com/nspcc-dev/neo-go/pkg/core/block" 5 "github.com/nspcc-dev/neo-go/pkg/core/state" 6 "github.com/nspcc-dev/neo-go/pkg/core/transaction" 7 "github.com/nspcc-dev/neo-go/pkg/neorpc" 8 "github.com/nspcc-dev/neo-go/pkg/neorpc/result" 9 ) 10 11 type ( 12 // Comparator is an interface required from notification event filter to be able to 13 // filter notifications. 14 Comparator interface { 15 EventID() neorpc.EventID 16 Filter() neorpc.SubscriptionFilter 17 } 18 // Container is an interface required from notification event to be able to 19 // pass filter. 20 Container interface { 21 EventID() neorpc.EventID 22 EventPayload() any 23 } 24 ) 25 26 // Matches filters our given Container against Comparator filter. 27 func Matches(f Comparator, r Container) bool { 28 expectedEvent := f.EventID() 29 filter := f.Filter() 30 if r.EventID() != expectedEvent { 31 return false 32 } 33 if filter == nil { 34 return true 35 } 36 switch f.EventID() { 37 case neorpc.BlockEventID, neorpc.HeaderOfAddedBlockEventID: 38 filt := filter.(neorpc.BlockFilter) 39 var b *block.Header 40 if f.EventID() == neorpc.HeaderOfAddedBlockEventID { 41 b = r.EventPayload().(*block.Header) 42 } else { 43 b = &r.EventPayload().(*block.Block).Header 44 } 45 primaryOk := filt.Primary == nil || *filt.Primary == b.PrimaryIndex 46 sinceOk := filt.Since == nil || *filt.Since <= b.Index 47 tillOk := filt.Till == nil || b.Index <= *filt.Till 48 return primaryOk && sinceOk && tillOk 49 case neorpc.TransactionEventID: 50 filt := filter.(neorpc.TxFilter) 51 tx := r.EventPayload().(*transaction.Transaction) 52 senderOK := filt.Sender == nil || tx.Sender().Equals(*filt.Sender) 53 signerOK := true 54 if filt.Signer != nil { 55 signerOK = false 56 for i := range tx.Signers { 57 if tx.Signers[i].Account.Equals(*filt.Signer) { 58 signerOK = true 59 break 60 } 61 } 62 } 63 return senderOK && signerOK 64 case neorpc.NotificationEventID: 65 filt := filter.(neorpc.NotificationFilter) 66 notification := r.EventPayload().(*state.ContainedNotificationEvent) 67 hashOk := filt.Contract == nil || notification.ScriptHash.Equals(*filt.Contract) 68 nameOk := filt.Name == nil || notification.Name == *filt.Name 69 return hashOk && nameOk 70 case neorpc.ExecutionEventID: 71 filt := filter.(neorpc.ExecutionFilter) 72 applog := r.EventPayload().(*state.AppExecResult) 73 stateOK := filt.State == nil || applog.VMState.String() == *filt.State 74 containerOK := filt.Container == nil || applog.Container.Equals(*filt.Container) 75 return stateOK && containerOK 76 case neorpc.NotaryRequestEventID: 77 filt := filter.(neorpc.NotaryRequestFilter) 78 req := r.EventPayload().(*result.NotaryRequestEvent) 79 typeOk := filt.Type == nil || req.Type == *filt.Type 80 senderOk := filt.Sender == nil || req.NotaryRequest.FallbackTransaction.Signers[1].Account == *filt.Sender 81 signerOK := true 82 if filt.Signer != nil { 83 signerOK = false 84 for _, signer := range req.NotaryRequest.MainTransaction.Signers { 85 if signer.Account.Equals(*filt.Signer) { 86 signerOK = true 87 break 88 } 89 } 90 } 91 return senderOk && signerOK && typeOk 92 } 93 return false 94 }