8
8
9
9
"github.com/onflow/flow-go/engine/access/rest/common/parser"
10
10
"github.com/onflow/flow-go/engine/access/rest/http/request"
11
+ "github.com/onflow/flow-go/engine/access/rest/util"
11
12
"github.com/onflow/flow-go/engine/access/rest/websockets/models"
12
13
"github.com/onflow/flow-go/engine/access/state_stream"
13
14
"github.com/onflow/flow-go/engine/access/state_stream/backend"
@@ -16,11 +17,12 @@ import (
16
17
"github.com/onflow/flow-go/module/counters"
17
18
)
18
19
19
- // eventsArguments contains the arguments required for subscribing to events
20
+ // eventsArguments contains the arguments a user passes to subscribe to events
20
21
type eventsArguments struct {
21
- StartBlockID flow.Identifier // ID of the block to start subscription from
22
- StartBlockHeight uint64 // Height of the block to start subscription from
23
- Filter state_stream.EventFilter // Filter applied to events for a given subscription
22
+ StartBlockID flow.Identifier // ID of the block to start subscription from
23
+ StartBlockHeight uint64 // Height of the block to start subscription from
24
+ Filter state_stream.EventFilter // Filter applied to events for a given subscription
25
+ HeartbeatInterval * uint64 // Maximum number of blocks message won't be sent. Nil if not set
24
26
}
25
27
26
28
// EventsDataProvider is responsible for providing events
@@ -63,6 +65,9 @@ func NewEventsDataProvider(
63
65
if err != nil {
64
66
return nil , fmt .Errorf ("invalid arguments for events data provider: %w" , err )
65
67
}
68
+ if eventArgs .HeartbeatInterval != nil {
69
+ p .heartbeatInterval = * eventArgs .HeartbeatInterval
70
+ }
66
71
67
72
subCtx , cancel := context .WithCancel (ctx )
68
73
@@ -139,10 +144,23 @@ func parseEventsArguments(
139
144
chain flow.Chain ,
140
145
eventFilterConfig state_stream.EventFilterConfig ,
141
146
) (eventsArguments , error ) {
147
+ allowedFields := []string {
148
+ "start_block_id" ,
149
+ "start_block_height" ,
150
+ "event_types" ,
151
+ "addresses" ,
152
+ "contracts" ,
153
+ "heartbeat_interval" ,
154
+ }
155
+ err := ensureAllowedFields (arguments , allowedFields )
156
+ if err != nil {
157
+ return eventsArguments {}, err
158
+ }
159
+
142
160
var args eventsArguments
143
161
144
162
// Parse block arguments
145
- startBlockID , startBlockHeight , err := ParseStartBlock (arguments )
163
+ startBlockID , startBlockHeight , err := parseStartBlock (arguments )
146
164
if err != nil {
147
165
return args , err
148
166
}
@@ -154,12 +172,12 @@ func parseEventsArguments(
154
172
if eventTypesIn , ok := arguments ["event_types" ]; ok && eventTypesIn != "" {
155
173
result , ok := eventTypesIn .([]string )
156
174
if ! ok {
157
- return args , fmt .Errorf ("'event_types' must be an array of string" )
175
+ return eventsArguments {} , fmt .Errorf ("'event_types' must be an array of string" )
158
176
}
159
177
160
178
err := eventTypes .Parse (result )
161
179
if err != nil {
162
- return args , fmt .Errorf ("invalid 'event_types': %w" , err )
180
+ return eventsArguments {} , fmt .Errorf ("invalid 'event_types': %w" , err )
163
181
}
164
182
}
165
183
@@ -168,7 +186,7 @@ func parseEventsArguments(
168
186
if addressesIn , ok := arguments ["addresses" ]; ok && addressesIn != "" {
169
187
addresses , ok = addressesIn .([]string )
170
188
if ! ok {
171
- return args , fmt .Errorf ("'addresses' must be an array of string" )
189
+ return eventsArguments {} , fmt .Errorf ("'addresses' must be an array of string" )
172
190
}
173
191
}
174
192
@@ -177,14 +195,29 @@ func parseEventsArguments(
177
195
if contractsIn , ok := arguments ["contracts" ]; ok && contractsIn != "" {
178
196
contracts , ok = contractsIn .([]string )
179
197
if ! ok {
180
- return args , fmt .Errorf ("'contracts' must be an array of string" )
198
+ return eventsArguments {} , fmt .Errorf ("'contracts' must be an array of string" )
181
199
}
182
200
}
183
201
202
+ var heartbeatInterval uint64
203
+ if heartbeatIntervalIn , ok := arguments ["heartbeat_interval" ]; ok && heartbeatIntervalIn != "" {
204
+ result , ok := heartbeatIntervalIn .(string )
205
+ if ! ok {
206
+ return eventsArguments {}, fmt .Errorf ("'heartbeat_interval' must be a string" )
207
+ }
208
+
209
+ heartbeatInterval , err = util .ToUint64 (result )
210
+ if err != nil {
211
+ return eventsArguments {}, fmt .Errorf ("invalid 'heartbeat_interval': %w" , err )
212
+ }
213
+
214
+ args .HeartbeatInterval = & heartbeatInterval
215
+ }
216
+
184
217
// Initialize the event filter with the parsed arguments
185
218
args .Filter , err = state_stream .NewEventFilter (eventFilterConfig , chain , eventTypes .Flow (), addresses , contracts )
186
219
if err != nil {
187
- return args , fmt .Errorf ("failed to create event filter: %w" , err )
220
+ return eventsArguments {} , fmt .Errorf ("failed to create event filter: %w" , err )
188
221
}
189
222
190
223
return args , nil
0 commit comments