@@ -112,6 +112,7 @@ type (
112
112
VerifyWitness (util.Uint160 , hash.Hashable , * transaction.Witness , int64 ) (int64 , error )
113
113
mempool.Feer // fee interface
114
114
ContractStorageSeeker
115
+ GetTrimmedBlock (hash util.Uint256 ) (* block.Block , error )
115
116
}
116
117
117
118
// ContractStorageSeeker is the interface `findstorage*` handlers need to be able to
@@ -219,6 +220,7 @@ var rpcHandlers = map[string]func(*Server, params.Params) (any, *neorpc.Error){
219
220
"getblockhash" : (* Server ).getBlockHash ,
220
221
"getblockheader" : (* Server ).getBlockHeader ,
221
222
"getblockheadercount" : (* Server ).getBlockHeaderCount ,
223
+ "getblocknotifications" : (* Server ).getBlockNotifications ,
222
224
"getblocksysfee" : (* Server ).getBlockSysFee ,
223
225
"getcandidates" : (* Server ).getCandidates ,
224
226
"getcommittee" : (* Server ).getCommittee ,
@@ -3202,3 +3204,59 @@ func (s *Server) getRawNotaryTransaction(reqParams params.Params) (any, *neorpc.
3202
3204
}
3203
3205
return tx .Bytes (), nil
3204
3206
}
3207
+
3208
+ // getBlockNotifications returns notifications from a specific block with optional filtering.
3209
+ func (s * Server ) getBlockNotifications (reqParams params.Params ) (any , * neorpc.Error ) {
3210
+ param := reqParams .Value (0 )
3211
+ hash , respErr := s .blockHashFromParam (param )
3212
+ if respErr != nil {
3213
+ return nil , respErr
3214
+ }
3215
+
3216
+ var filter * neorpc.NotificationFilter
3217
+ if len (reqParams ) > 1 {
3218
+ var (
3219
+ reader = bytes .NewBuffer ([]byte (reqParams [1 ].RawMessage ))
3220
+ decoder = json .NewDecoder (reader )
3221
+ )
3222
+ decoder .DisallowUnknownFields ()
3223
+ filter = new (neorpc.NotificationFilter )
3224
+
3225
+ err := decoder .Decode (filter )
3226
+ if err != nil {
3227
+ return nil , neorpc .WrapErrorWithData (neorpc .ErrInvalidParams , fmt .Sprintf ("invalid filter: %s" , err ))
3228
+ }
3229
+ if err := filter .IsValid (); err != nil {
3230
+ return nil , neorpc .WrapErrorWithData (neorpc .ErrInvalidParams , fmt .Sprintf ("invalid filter: %s" , err ))
3231
+ }
3232
+ }
3233
+
3234
+ block , err := s .chain .GetTrimmedBlock (hash )
3235
+ if err != nil {
3236
+ return nil , neorpc .ErrUnknownBlock
3237
+ }
3238
+
3239
+ notifications := & result.BlockNotifications {}
3240
+
3241
+ aers , err := s .chain .GetAppExecResults (block .Hash (), trigger .OnPersist )
3242
+ if err != nil {
3243
+ return nil , neorpc .NewInternalServerError ("failed to get app exec results for onpersist" )
3244
+ }
3245
+ notifications .OnPersist = processAppExecResults ([]state.AppExecResult {aers [0 ]}, filter )
3246
+
3247
+ for _ , txHash := range block .Transactions {
3248
+ aers , err := s .chain .GetAppExecResults (txHash .Hash (), trigger .Application )
3249
+ if err != nil {
3250
+ return nil , neorpc .NewInternalServerError ("failed to get app exec results" )
3251
+ }
3252
+ notifications .Application = append (notifications .Application , processAppExecResults (aers , filter )... )
3253
+ }
3254
+
3255
+ aers , err = s .chain .GetAppExecResults (block .Hash (), trigger .PostPersist )
3256
+ if err != nil {
3257
+ return nil , neorpc .NewInternalServerError ("failed to get app exec results for postpersist" )
3258
+ }
3259
+ notifications .PostPersist = processAppExecResults ([]state.AppExecResult {aers [0 ]}, filter )
3260
+
3261
+ return notifications , nil
3262
+ }
0 commit comments