github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/neorpc/filters.go (about) 1 package neorpc 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/nspcc-dev/neo-go/pkg/core/interop/runtime" 8 "github.com/nspcc-dev/neo-go/pkg/core/mempoolevent" 9 "github.com/nspcc-dev/neo-go/pkg/util" 10 "github.com/nspcc-dev/neo-go/pkg/vm/vmstate" 11 ) 12 13 type ( 14 // BlockFilter is a wrapper structure for the block event filter. It allows 15 // to filter blocks by primary index and/or by block index (allowing blocks 16 // since/till the specified index inclusively). nil value treated as missing 17 // filter. 18 BlockFilter struct { 19 Primary *byte `json:"primary,omitempty"` 20 Since *uint32 `json:"since,omitempty"` 21 Till *uint32 `json:"till,omitempty"` 22 } 23 // TxFilter is a wrapper structure for the transaction event filter. It 24 // allows to filter transactions by senders and/or signers. nil value treated 25 // as missing filter. 26 TxFilter struct { 27 Sender *util.Uint160 `json:"sender,omitempty"` 28 Signer *util.Uint160 `json:"signer,omitempty"` 29 } 30 // NotificationFilter is a wrapper structure representing a filter used for 31 // notifications generated during transaction execution. Notifications can 32 // be filtered by contract hash and/or by name. nil value treated as missing 33 // filter. 34 NotificationFilter struct { 35 Contract *util.Uint160 `json:"contract,omitempty"` 36 Name *string `json:"name,omitempty"` 37 } 38 // ExecutionFilter is a wrapper structure used for transaction and persisting 39 // scripts execution events. It allows to choose failing or successful 40 // transactions and persisting scripts based on their VM state and/or to 41 // choose execution event with the specified container. nil value treated as 42 // missing filter. 43 ExecutionFilter struct { 44 State *string `json:"state,omitempty"` 45 Container *util.Uint256 `json:"container,omitempty"` 46 } 47 // NotaryRequestFilter is a wrapper structure used for notary request events. 48 // It allows to choose notary request events with the specified request sender, 49 // main transaction signer and/or type. nil value treated as missing filter. 50 NotaryRequestFilter struct { 51 Sender *util.Uint160 `json:"sender,omitempty"` 52 Signer *util.Uint160 `json:"signer,omitempty"` 53 Type *mempoolevent.Type `json:"type,omitempty"` 54 } 55 ) 56 57 // SubscriptionFilter is an interface for all subscription filters. 58 type SubscriptionFilter interface { 59 // IsValid checks whether the filter is valid and returns 60 // a specific [ErrInvalidSubscriptionFilter] error if not. 61 IsValid() error 62 } 63 64 // ErrInvalidSubscriptionFilter is returned when the subscription filter is invalid. 65 var ErrInvalidSubscriptionFilter = errors.New("invalid subscription filter") 66 67 // Copy creates a deep copy of the BlockFilter. It handles nil BlockFilter correctly. 68 func (f *BlockFilter) Copy() *BlockFilter { 69 if f == nil { 70 return nil 71 } 72 var res = new(BlockFilter) 73 if f.Primary != nil { 74 res.Primary = new(byte) 75 *res.Primary = *f.Primary 76 } 77 if f.Since != nil { 78 res.Since = new(uint32) 79 *res.Since = *f.Since 80 } 81 if f.Till != nil { 82 res.Till = new(uint32) 83 *res.Till = *f.Till 84 } 85 return res 86 } 87 88 // IsValid implements SubscriptionFilter interface. 89 func (f BlockFilter) IsValid() error { 90 return nil 91 } 92 93 // Copy creates a deep copy of the TxFilter. It handles nil TxFilter correctly. 94 func (f *TxFilter) Copy() *TxFilter { 95 if f == nil { 96 return nil 97 } 98 var res = new(TxFilter) 99 if f.Sender != nil { 100 res.Sender = new(util.Uint160) 101 *res.Sender = *f.Sender 102 } 103 if f.Signer != nil { 104 res.Signer = new(util.Uint160) 105 *res.Signer = *f.Signer 106 } 107 return res 108 } 109 110 // IsValid implements SubscriptionFilter interface. 111 func (f TxFilter) IsValid() error { 112 return nil 113 } 114 115 // Copy creates a deep copy of the NotificationFilter. It handles nil NotificationFilter correctly. 116 func (f *NotificationFilter) Copy() *NotificationFilter { 117 if f == nil { 118 return nil 119 } 120 var res = new(NotificationFilter) 121 if f.Contract != nil { 122 res.Contract = new(util.Uint160) 123 *res.Contract = *f.Contract 124 } 125 if f.Name != nil { 126 res.Name = new(string) 127 *res.Name = *f.Name 128 } 129 return res 130 } 131 132 // IsValid implements SubscriptionFilter interface. 133 func (f NotificationFilter) IsValid() error { 134 if f.Name != nil && len(*f.Name) > runtime.MaxEventNameLen { 135 return fmt.Errorf("%w: NotificationFilter name parameter must be less than %d", ErrInvalidSubscriptionFilter, runtime.MaxEventNameLen) 136 } 137 return nil 138 } 139 140 // Copy creates a deep copy of the ExecutionFilter. It handles nil ExecutionFilter correctly. 141 func (f *ExecutionFilter) Copy() *ExecutionFilter { 142 if f == nil { 143 return nil 144 } 145 var res = new(ExecutionFilter) 146 if f.State != nil { 147 res.State = new(string) 148 *res.State = *f.State 149 } 150 if f.Container != nil { 151 res.Container = new(util.Uint256) 152 *res.Container = *f.Container 153 } 154 return res 155 } 156 157 // IsValid implements SubscriptionFilter interface. 158 func (f ExecutionFilter) IsValid() error { 159 if f.State != nil { 160 if *f.State != vmstate.Halt.String() && *f.State != vmstate.Fault.String() { 161 return fmt.Errorf("%w: ExecutionFilter state parameter must be either %s or %s", ErrInvalidSubscriptionFilter, vmstate.Halt, vmstate.Fault) 162 } 163 } 164 165 return nil 166 } 167 168 // Copy creates a deep copy of the NotaryRequestFilter. It handles nil NotaryRequestFilter correctly. 169 func (f *NotaryRequestFilter) Copy() *NotaryRequestFilter { 170 if f == nil { 171 return nil 172 } 173 var res = new(NotaryRequestFilter) 174 if f.Sender != nil { 175 res.Sender = new(util.Uint160) 176 *res.Sender = *f.Sender 177 } 178 if f.Signer != nil { 179 res.Signer = new(util.Uint160) 180 *res.Signer = *f.Signer 181 } 182 if f.Type != nil { 183 res.Type = new(mempoolevent.Type) 184 *res.Type = *f.Type 185 } 186 return res 187 } 188 189 // IsValid implements SubscriptionFilter interface. 190 func (f NotaryRequestFilter) IsValid() error { 191 return nil 192 }