envio 2.27.6 → 2.28.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/rescript.json +3 -0
- package/src/Hasura.res +135 -12
- package/src/Hasura.res.js +95 -13
- package/src/Internal.res +7 -4
- package/src/InternalConfig.res +20 -0
- package/src/InternalConfig.res.js +2 -0
- package/src/Js.shim.ts +11 -0
- package/src/LoadManager.res +12 -6
- package/src/LoadManager.res.js +13 -6
- package/src/Persistence.res +25 -33
- package/src/Persistence.res.js +18 -20
- package/src/PgStorage.res +155 -101
- package/src/PgStorage.res.js +141 -100
- package/src/Prometheus.res +2 -2
- package/src/Prometheus.res.js +2 -3
- package/src/bindings/Pino.res +1 -1
- package/src/bindings/Pino.res.js +2 -1
- package/src/db/EntityHistory.res +18 -17
- package/src/db/EntityHistory.res.js +28 -26
- package/src/db/InternalTable.gen.ts +43 -0
- package/src/db/InternalTable.res +392 -0
- package/src/db/InternalTable.res.js +295 -0
- package/src/vendored/Rest.res +11 -2
- package/src/vendored/Rest.res.js +44 -35
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
open Table
|
|
2
|
+
|
|
3
|
+
//shorthand for punning
|
|
4
|
+
let isPrimaryKey = true
|
|
5
|
+
let isNullable = true
|
|
6
|
+
let isIndex = true
|
|
7
|
+
|
|
8
|
+
module EventSyncState = {
|
|
9
|
+
//Used unsafely in DbFunctions.res so just enforcing the naming here
|
|
10
|
+
let blockTimestampFieldName = "block_timestamp"
|
|
11
|
+
let blockNumberFieldName = "block_number"
|
|
12
|
+
let logIndexFieldName = "log_index"
|
|
13
|
+
let isPreRegisteringDynamicContractsFieldName = "is_pre_registering_dynamic_contracts"
|
|
14
|
+
|
|
15
|
+
// @genType Used for Test DB
|
|
16
|
+
@genType
|
|
17
|
+
type t = {
|
|
18
|
+
@as("chain_id") chainId: int,
|
|
19
|
+
@as("block_number") blockNumber: int,
|
|
20
|
+
@as("log_index") logIndex: int,
|
|
21
|
+
@as("block_timestamp") blockTimestamp: int,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let table = mkTable(
|
|
25
|
+
"event_sync_state",
|
|
26
|
+
~fields=[
|
|
27
|
+
mkField("chain_id", Integer, ~fieldSchema=S.int, ~isPrimaryKey),
|
|
28
|
+
mkField(blockNumberFieldName, Integer, ~fieldSchema=S.int),
|
|
29
|
+
mkField(logIndexFieldName, Integer, ~fieldSchema=S.int),
|
|
30
|
+
mkField(blockTimestampFieldName, Integer, ~fieldSchema=S.int),
|
|
31
|
+
// Keep it in case Hosted Service relies on it to prevent a breaking changes
|
|
32
|
+
mkField(
|
|
33
|
+
isPreRegisteringDynamicContractsFieldName,
|
|
34
|
+
Boolean,
|
|
35
|
+
~default="false",
|
|
36
|
+
~fieldSchema=S.bool,
|
|
37
|
+
),
|
|
38
|
+
],
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
//We need to update values here not delet the rows, since restarting without a row
|
|
42
|
+
//has a different behaviour to restarting with an initialised row with zero values
|
|
43
|
+
let resetCurrentCurrentSyncStateQuery = (~pgSchema) =>
|
|
44
|
+
`UPDATE "${pgSchema}"."${table.tableName}"
|
|
45
|
+
SET ${blockNumberFieldName} = 0,
|
|
46
|
+
${logIndexFieldName} = 0,
|
|
47
|
+
${blockTimestampFieldName} = 0,
|
|
48
|
+
${isPreRegisteringDynamicContractsFieldName} = false;`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module Chains = {
|
|
52
|
+
type field = [
|
|
53
|
+
| #id
|
|
54
|
+
| #start_block
|
|
55
|
+
| #end_block
|
|
56
|
+
| #source_block
|
|
57
|
+
| #first_event_block
|
|
58
|
+
| #buffer_block
|
|
59
|
+
| #ready_at
|
|
60
|
+
| #events_processed
|
|
61
|
+
| #_is_hyper_sync
|
|
62
|
+
| #_latest_processed_block
|
|
63
|
+
| #_num_batches_fetched
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
let fields: array<field> = [
|
|
67
|
+
#id,
|
|
68
|
+
#start_block,
|
|
69
|
+
#end_block,
|
|
70
|
+
#source_block,
|
|
71
|
+
#first_event_block,
|
|
72
|
+
#buffer_block,
|
|
73
|
+
#ready_at,
|
|
74
|
+
#events_processed,
|
|
75
|
+
#_is_hyper_sync,
|
|
76
|
+
#_latest_processed_block,
|
|
77
|
+
#_num_batches_fetched,
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
type t = {
|
|
81
|
+
@as("id") id: int,
|
|
82
|
+
@as("start_block") startBlock: int,
|
|
83
|
+
@as("end_block") endBlock: Js.null<int>,
|
|
84
|
+
@as("source_block") blockHeight: int,
|
|
85
|
+
@as("first_event_block") firstEventBlockNumber: Js.null<int>,
|
|
86
|
+
@as("buffer_block") latestFetchedBlockNumber: int,
|
|
87
|
+
@as("ready_at")
|
|
88
|
+
timestampCaughtUpToHeadOrEndblock: Js.null<Js.Date.t>,
|
|
89
|
+
@as("events_processed") numEventsProcessed: int,
|
|
90
|
+
@as("_latest_processed_block") latestProcessedBlock: Js.null<int>,
|
|
91
|
+
@as("_is_hyper_sync") isHyperSync: bool,
|
|
92
|
+
@as("_num_batches_fetched") numBatchesFetched: int,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let table = mkTable(
|
|
96
|
+
"envio_chains",
|
|
97
|
+
~fields=[
|
|
98
|
+
mkField((#id: field :> string), Integer, ~fieldSchema=S.int, ~isPrimaryKey),
|
|
99
|
+
// Values populated from config
|
|
100
|
+
mkField((#start_block: field :> string), Integer, ~fieldSchema=S.int),
|
|
101
|
+
mkField((#end_block: field :> string), Integer, ~fieldSchema=S.null(S.int), ~isNullable),
|
|
102
|
+
// Block number of the latest block that was fetched from the source
|
|
103
|
+
mkField((#buffer_block: field :> string), Integer, ~fieldSchema=S.int),
|
|
104
|
+
// Block number of the currently active source
|
|
105
|
+
mkField((#source_block: field :> string), Integer, ~fieldSchema=S.int),
|
|
106
|
+
// Block number of the first event that was processed for this chain
|
|
107
|
+
mkField(
|
|
108
|
+
(#first_event_block: field :> string),
|
|
109
|
+
Integer,
|
|
110
|
+
~fieldSchema=S.null(S.int),
|
|
111
|
+
~isNullable,
|
|
112
|
+
),
|
|
113
|
+
// Used to show how much time historical sync has taken, so we need a timezone here (TUI and Hosted Service)
|
|
114
|
+
// null during historical sync, set to current time when sync is complete
|
|
115
|
+
mkField(
|
|
116
|
+
(#ready_at: field :> string),
|
|
117
|
+
TimestampWithNullTimezone,
|
|
118
|
+
~fieldSchema=S.null(Utils.Schema.dbDate),
|
|
119
|
+
~isNullable,
|
|
120
|
+
),
|
|
121
|
+
mkField((#events_processed: field :> string), Integer, ~fieldSchema=S.int), // TODO: In the future it should reference a table with sources
|
|
122
|
+
mkField((#_is_hyper_sync: field :> string), Boolean, ~fieldSchema=S.bool),
|
|
123
|
+
// TODO: Make the data more public facing
|
|
124
|
+
mkField(
|
|
125
|
+
(#_latest_processed_block: field :> string),
|
|
126
|
+
Integer,
|
|
127
|
+
~fieldSchema=S.null(S.int),
|
|
128
|
+
~isNullable,
|
|
129
|
+
),
|
|
130
|
+
mkField((#_num_batches_fetched: field :> string), Integer, ~fieldSchema=S.int),
|
|
131
|
+
],
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
let initialFromConfig = (chainConfig: InternalConfig.chain) => {
|
|
135
|
+
{
|
|
136
|
+
id: chainConfig.id,
|
|
137
|
+
startBlock: chainConfig.startBlock,
|
|
138
|
+
endBlock: chainConfig.endBlock->Js.Null.fromOption,
|
|
139
|
+
blockHeight: 0,
|
|
140
|
+
firstEventBlockNumber: Js.Null.empty,
|
|
141
|
+
latestFetchedBlockNumber: -1,
|
|
142
|
+
timestampCaughtUpToHeadOrEndblock: Js.Null.empty,
|
|
143
|
+
latestProcessedBlock: Js.Null.empty,
|
|
144
|
+
isHyperSync: false,
|
|
145
|
+
numEventsProcessed: 0,
|
|
146
|
+
numBatchesFetched: 0,
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
let makeInitialValuesQuery = (~pgSchema, ~chainConfigs: array<InternalConfig.chain>) => {
|
|
151
|
+
if chainConfigs->Array.length === 0 {
|
|
152
|
+
None
|
|
153
|
+
} else {
|
|
154
|
+
// Create column names list
|
|
155
|
+
let columnNames = fields->Belt.Array.map(field => `"${(field :> string)}"`)
|
|
156
|
+
|
|
157
|
+
// Create VALUES rows for each chain config
|
|
158
|
+
let valuesRows = chainConfigs->Belt.Array.map(chainConfig => {
|
|
159
|
+
let initialValues = initialFromConfig(chainConfig)
|
|
160
|
+
let values = fields->Belt.Array.map((field: field) => {
|
|
161
|
+
let value =
|
|
162
|
+
initialValues->(Utils.magic: t => dict<unknown>)->Js.Dict.get((field :> string))
|
|
163
|
+
switch Js.typeof(value) {
|
|
164
|
+
| "object" => "NULL"
|
|
165
|
+
| "number" => value->Utils.magic->Belt.Int.toString
|
|
166
|
+
| "boolean" => value->Utils.magic ? "true" : "false"
|
|
167
|
+
| _ => Js.Exn.raiseError("Invalid envio_chains value type")
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
`(${values->Js.Array2.joinWith(", ")})`
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
Some(
|
|
175
|
+
`INSERT INTO "${pgSchema}"."${table.tableName}" (${columnNames->Js.Array2.joinWith(", ")})
|
|
176
|
+
VALUES ${valuesRows->Js.Array2.joinWith(",\n ")};`,
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Fields that should be updated on conflict (excluding static config fields)
|
|
182
|
+
let updateFields: array<field> = [
|
|
183
|
+
#source_block,
|
|
184
|
+
#first_event_block,
|
|
185
|
+
#buffer_block,
|
|
186
|
+
#ready_at,
|
|
187
|
+
#events_processed,
|
|
188
|
+
#_is_hyper_sync,
|
|
189
|
+
#_latest_processed_block,
|
|
190
|
+
#_num_batches_fetched,
|
|
191
|
+
]
|
|
192
|
+
|
|
193
|
+
let makeSingleUpdateQuery = (~pgSchema) => {
|
|
194
|
+
// Generate SET clauses with parameter placeholders
|
|
195
|
+
let setClauses = Belt.Array.mapWithIndex(updateFields, (index, field) => {
|
|
196
|
+
let fieldName = (field :> string)
|
|
197
|
+
let paramIndex = index + 2 // +2 because $1 is for id in WHERE clause
|
|
198
|
+
`"${fieldName}" = $${Belt.Int.toString(paramIndex)}`
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
`UPDATE "${pgSchema}"."${table.tableName}"
|
|
202
|
+
SET ${setClauses->Js.Array2.joinWith(",\n ")}
|
|
203
|
+
WHERE "id" = $1;`
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let setValues = (sql, ~pgSchema, ~chainsData: array<t>) => {
|
|
207
|
+
let query = makeSingleUpdateQuery(~pgSchema)
|
|
208
|
+
|
|
209
|
+
let promises = chainsData->Belt.Array.map(chain => {
|
|
210
|
+
let params = []
|
|
211
|
+
|
|
212
|
+
// Push id first (for WHERE clause)
|
|
213
|
+
let idValue = chain->(Utils.magic: t => dict<unknown>)->Js.Dict.get("id")
|
|
214
|
+
params->Js.Array2.push(idValue)->ignore
|
|
215
|
+
|
|
216
|
+
// Then push all updateable field values (for SET clause)
|
|
217
|
+
updateFields->Js.Array2.forEach(field => {
|
|
218
|
+
let value = chain->(Utils.magic: t => dict<unknown>)->Js.Dict.get((field :> string))
|
|
219
|
+
params->Js.Array2.push(value)->ignore
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
sql->Postgres.preparedUnsafe(query, params->Obj.magic)
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
Promise.all(promises)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
module PersistedState = {
|
|
230
|
+
type t = {
|
|
231
|
+
id: int,
|
|
232
|
+
envio_version: string,
|
|
233
|
+
config_hash: string,
|
|
234
|
+
schema_hash: string,
|
|
235
|
+
handler_files_hash: string,
|
|
236
|
+
abi_files_hash: string,
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
let table = mkTable(
|
|
240
|
+
"persisted_state",
|
|
241
|
+
~fields=[
|
|
242
|
+
mkField("id", Serial, ~fieldSchema=S.int, ~isPrimaryKey),
|
|
243
|
+
mkField("envio_version", Text, ~fieldSchema=S.string),
|
|
244
|
+
mkField("config_hash", Text, ~fieldSchema=S.string),
|
|
245
|
+
mkField("schema_hash", Text, ~fieldSchema=S.string),
|
|
246
|
+
mkField("handler_files_hash", Text, ~fieldSchema=S.string),
|
|
247
|
+
mkField("abi_files_hash", Text, ~fieldSchema=S.string),
|
|
248
|
+
],
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
module EndOfBlockRangeScannedData = {
|
|
253
|
+
type t = {
|
|
254
|
+
chain_id: int,
|
|
255
|
+
block_number: int,
|
|
256
|
+
block_hash: string,
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
let table = mkTable(
|
|
260
|
+
"end_of_block_range_scanned_data",
|
|
261
|
+
~fields=[
|
|
262
|
+
mkField("chain_id", Integer, ~fieldSchema=S.int, ~isPrimaryKey),
|
|
263
|
+
mkField("block_number", Integer, ~fieldSchema=S.int, ~isPrimaryKey),
|
|
264
|
+
mkField("block_hash", Text, ~fieldSchema=S.string),
|
|
265
|
+
],
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
module RawEvents = {
|
|
270
|
+
// @genType Used for Test DB and internal tests
|
|
271
|
+
@genType
|
|
272
|
+
type t = {
|
|
273
|
+
@as("chain_id") chainId: int,
|
|
274
|
+
@as("event_id") eventId: bigint,
|
|
275
|
+
@as("event_name") eventName: string,
|
|
276
|
+
@as("contract_name") contractName: string,
|
|
277
|
+
@as("block_number") blockNumber: int,
|
|
278
|
+
@as("log_index") logIndex: int,
|
|
279
|
+
@as("src_address") srcAddress: Address.t,
|
|
280
|
+
@as("block_hash") blockHash: string,
|
|
281
|
+
@as("block_timestamp") blockTimestamp: int,
|
|
282
|
+
@as("block_fields") blockFields: Js.Json.t,
|
|
283
|
+
@as("transaction_fields") transactionFields: Js.Json.t,
|
|
284
|
+
params: Js.Json.t,
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
let schema = S.schema(s => {
|
|
288
|
+
chainId: s.matches(S.int),
|
|
289
|
+
eventId: s.matches(S.bigint),
|
|
290
|
+
eventName: s.matches(S.string),
|
|
291
|
+
contractName: s.matches(S.string),
|
|
292
|
+
blockNumber: s.matches(S.int),
|
|
293
|
+
logIndex: s.matches(S.int),
|
|
294
|
+
srcAddress: s.matches(Address.schema),
|
|
295
|
+
blockHash: s.matches(S.string),
|
|
296
|
+
blockTimestamp: s.matches(S.int),
|
|
297
|
+
blockFields: s.matches(S.json(~validate=false)),
|
|
298
|
+
transactionFields: s.matches(S.json(~validate=false)),
|
|
299
|
+
params: s.matches(S.json(~validate=false)),
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
let table = mkTable(
|
|
303
|
+
"raw_events",
|
|
304
|
+
~fields=[
|
|
305
|
+
mkField("chain_id", Integer, ~fieldSchema=S.int),
|
|
306
|
+
mkField("event_id", Numeric, ~fieldSchema=S.bigint),
|
|
307
|
+
mkField("event_name", Text, ~fieldSchema=S.string),
|
|
308
|
+
mkField("contract_name", Text, ~fieldSchema=S.string),
|
|
309
|
+
mkField("block_number", Integer, ~fieldSchema=S.int),
|
|
310
|
+
mkField("log_index", Integer, ~fieldSchema=S.int),
|
|
311
|
+
mkField("src_address", Text, ~fieldSchema=Address.schema),
|
|
312
|
+
mkField("block_hash", Text, ~fieldSchema=S.string),
|
|
313
|
+
mkField("block_timestamp", Integer, ~fieldSchema=S.int),
|
|
314
|
+
mkField("block_fields", JsonB, ~fieldSchema=S.json(~validate=false)),
|
|
315
|
+
mkField("transaction_fields", JsonB, ~fieldSchema=S.json(~validate=false)),
|
|
316
|
+
mkField("params", JsonB, ~fieldSchema=S.json(~validate=false)),
|
|
317
|
+
mkField(
|
|
318
|
+
"db_write_timestamp",
|
|
319
|
+
TimestampWithoutTimezone,
|
|
320
|
+
~default="CURRENT_TIMESTAMP",
|
|
321
|
+
~fieldSchema=S.int,
|
|
322
|
+
),
|
|
323
|
+
mkField("serial", Serial, ~isNullable, ~isPrimaryKey, ~fieldSchema=S.null(S.int)),
|
|
324
|
+
],
|
|
325
|
+
)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
module DynamicContractRegistry = {
|
|
329
|
+
let name = "dynamic_contract_registry"
|
|
330
|
+
|
|
331
|
+
let makeId = (~chainId, ~contractAddress) => {
|
|
332
|
+
chainId->Belt.Int.toString ++ "-" ++ contractAddress->Address.toString
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// @genType Used for Test DB
|
|
336
|
+
@genType
|
|
337
|
+
type t = {
|
|
338
|
+
id: string,
|
|
339
|
+
@as("chain_id") chainId: int,
|
|
340
|
+
@as("registering_event_block_number") registeringEventBlockNumber: int,
|
|
341
|
+
@as("registering_event_log_index") registeringEventLogIndex: int,
|
|
342
|
+
@as("registering_event_block_timestamp") registeringEventBlockTimestamp: int,
|
|
343
|
+
@as("registering_event_contract_name") registeringEventContractName: string,
|
|
344
|
+
@as("registering_event_name") registeringEventName: string,
|
|
345
|
+
@as("registering_event_src_address") registeringEventSrcAddress: Address.t,
|
|
346
|
+
@as("contract_address") contractAddress: Address.t,
|
|
347
|
+
@as("contract_name") contractName: string,
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
let schema = S.schema(s => {
|
|
351
|
+
id: s.matches(S.string),
|
|
352
|
+
chainId: s.matches(S.int),
|
|
353
|
+
registeringEventBlockNumber: s.matches(S.int),
|
|
354
|
+
registeringEventLogIndex: s.matches(S.int),
|
|
355
|
+
registeringEventContractName: s.matches(S.string),
|
|
356
|
+
registeringEventName: s.matches(S.string),
|
|
357
|
+
registeringEventSrcAddress: s.matches(Address.schema),
|
|
358
|
+
registeringEventBlockTimestamp: s.matches(S.int),
|
|
359
|
+
contractAddress: s.matches(Address.schema),
|
|
360
|
+
contractName: s.matches(S.string),
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
let rowsSchema = S.array(schema)
|
|
364
|
+
|
|
365
|
+
let table = mkTable(
|
|
366
|
+
name,
|
|
367
|
+
~fields=[
|
|
368
|
+
mkField("id", Text, ~isPrimaryKey, ~fieldSchema=S.string),
|
|
369
|
+
mkField("chain_id", Integer, ~fieldSchema=S.int),
|
|
370
|
+
mkField("registering_event_block_number", Integer, ~fieldSchema=S.int),
|
|
371
|
+
mkField("registering_event_log_index", Integer, ~fieldSchema=S.int),
|
|
372
|
+
mkField("registering_event_block_timestamp", Integer, ~fieldSchema=S.int),
|
|
373
|
+
mkField("registering_event_contract_name", Text, ~fieldSchema=S.string),
|
|
374
|
+
mkField("registering_event_name", Text, ~fieldSchema=S.string),
|
|
375
|
+
mkField("registering_event_src_address", Text, ~fieldSchema=Address.schema),
|
|
376
|
+
mkField("contract_address", Text, ~fieldSchema=Address.schema),
|
|
377
|
+
mkField("contract_name", Text, ~fieldSchema=S.string),
|
|
378
|
+
],
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
let entityHistory = table->EntityHistory.fromTable(~schema)
|
|
382
|
+
|
|
383
|
+
external castToInternal: t => Internal.entity = "%identity"
|
|
384
|
+
|
|
385
|
+
let config = {
|
|
386
|
+
name,
|
|
387
|
+
schema,
|
|
388
|
+
rowsSchema,
|
|
389
|
+
table,
|
|
390
|
+
entityHistory,
|
|
391
|
+
}->Internal.fromGenericEntityConfig
|
|
392
|
+
}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var Table = require("./Table.res.js");
|
|
5
|
+
var Utils = require("../Utils.res.js");
|
|
6
|
+
var Js_exn = require("rescript/lib/js/js_exn.js");
|
|
7
|
+
var Address = require("../Address.res.js");
|
|
8
|
+
var Js_dict = require("rescript/lib/js/js_dict.js");
|
|
9
|
+
var Js_null = require("rescript/lib/js/js_null.js");
|
|
10
|
+
var Belt_Array = require("rescript/lib/js/belt_Array.js");
|
|
11
|
+
var EntityHistory = require("./EntityHistory.res.js");
|
|
12
|
+
var S$RescriptSchema = require("rescript-schema/src/S.res.js");
|
|
13
|
+
|
|
14
|
+
var blockTimestampFieldName = "block_timestamp";
|
|
15
|
+
|
|
16
|
+
var blockNumberFieldName = "block_number";
|
|
17
|
+
|
|
18
|
+
var logIndexFieldName = "log_index";
|
|
19
|
+
|
|
20
|
+
var isPreRegisteringDynamicContractsFieldName = "is_pre_registering_dynamic_contracts";
|
|
21
|
+
|
|
22
|
+
var table = Table.mkTable("event_sync_state", undefined, [
|
|
23
|
+
Table.mkField("chain_id", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, true, undefined, undefined),
|
|
24
|
+
Table.mkField(blockNumberFieldName, "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
25
|
+
Table.mkField(logIndexFieldName, "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
26
|
+
Table.mkField(blockTimestampFieldName, "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
27
|
+
Table.mkField(isPreRegisteringDynamicContractsFieldName, "BOOLEAN", S$RescriptSchema.bool, "false", undefined, undefined, undefined, undefined, undefined)
|
|
28
|
+
]);
|
|
29
|
+
|
|
30
|
+
function resetCurrentCurrentSyncStateQuery(pgSchema) {
|
|
31
|
+
return "UPDATE \"" + pgSchema + "\".\"" + table.tableName + "\"\n SET " + blockNumberFieldName + " = 0, \n " + logIndexFieldName + " = 0, \n " + blockTimestampFieldName + " = 0, \n " + isPreRegisteringDynamicContractsFieldName + " = false;";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var EventSyncState = {
|
|
35
|
+
blockTimestampFieldName: blockTimestampFieldName,
|
|
36
|
+
blockNumberFieldName: blockNumberFieldName,
|
|
37
|
+
logIndexFieldName: logIndexFieldName,
|
|
38
|
+
isPreRegisteringDynamicContractsFieldName: isPreRegisteringDynamicContractsFieldName,
|
|
39
|
+
table: table,
|
|
40
|
+
resetCurrentCurrentSyncStateQuery: resetCurrentCurrentSyncStateQuery
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
var fields = [
|
|
44
|
+
"id",
|
|
45
|
+
"start_block",
|
|
46
|
+
"end_block",
|
|
47
|
+
"source_block",
|
|
48
|
+
"first_event_block",
|
|
49
|
+
"buffer_block",
|
|
50
|
+
"ready_at",
|
|
51
|
+
"events_processed",
|
|
52
|
+
"_is_hyper_sync",
|
|
53
|
+
"_latest_processed_block",
|
|
54
|
+
"_num_batches_fetched"
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
var table$1 = Table.mkTable("envio_chains", undefined, [
|
|
58
|
+
Table.mkField("id", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, true, undefined, undefined),
|
|
59
|
+
Table.mkField("start_block", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
60
|
+
Table.mkField("end_block", "INTEGER", S$RescriptSchema.$$null(S$RescriptSchema.$$int), undefined, undefined, true, undefined, undefined, undefined),
|
|
61
|
+
Table.mkField("buffer_block", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
62
|
+
Table.mkField("source_block", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
63
|
+
Table.mkField("first_event_block", "INTEGER", S$RescriptSchema.$$null(S$RescriptSchema.$$int), undefined, undefined, true, undefined, undefined, undefined),
|
|
64
|
+
Table.mkField("ready_at", "TIMESTAMP WITH TIME ZONE NULL", S$RescriptSchema.$$null(Utils.Schema.dbDate), undefined, undefined, true, undefined, undefined, undefined),
|
|
65
|
+
Table.mkField("events_processed", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
66
|
+
Table.mkField("_is_hyper_sync", "BOOLEAN", S$RescriptSchema.bool, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
67
|
+
Table.mkField("_latest_processed_block", "INTEGER", S$RescriptSchema.$$null(S$RescriptSchema.$$int), undefined, undefined, true, undefined, undefined, undefined),
|
|
68
|
+
Table.mkField("_num_batches_fetched", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
function initialFromConfig(chainConfig) {
|
|
72
|
+
return {
|
|
73
|
+
id: chainConfig.id,
|
|
74
|
+
start_block: chainConfig.startBlock,
|
|
75
|
+
end_block: Js_null.fromOption(chainConfig.endBlock),
|
|
76
|
+
source_block: 0,
|
|
77
|
+
first_event_block: null,
|
|
78
|
+
buffer_block: -1,
|
|
79
|
+
ready_at: null,
|
|
80
|
+
events_processed: 0,
|
|
81
|
+
_latest_processed_block: null,
|
|
82
|
+
_is_hyper_sync: false,
|
|
83
|
+
_num_batches_fetched: 0
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function makeInitialValuesQuery(pgSchema, chainConfigs) {
|
|
88
|
+
if (chainConfigs.length === 0) {
|
|
89
|
+
return ;
|
|
90
|
+
}
|
|
91
|
+
var columnNames = Belt_Array.map(fields, (function (field) {
|
|
92
|
+
return "\"" + field + "\"";
|
|
93
|
+
}));
|
|
94
|
+
var valuesRows = Belt_Array.map(chainConfigs, (function (chainConfig) {
|
|
95
|
+
var initialValues = initialFromConfig(chainConfig);
|
|
96
|
+
var values = Belt_Array.map(fields, (function (field) {
|
|
97
|
+
var value = Js_dict.get(initialValues, field);
|
|
98
|
+
var match = typeof value;
|
|
99
|
+
switch (match) {
|
|
100
|
+
case "boolean" :
|
|
101
|
+
if (value) {
|
|
102
|
+
return "true";
|
|
103
|
+
} else {
|
|
104
|
+
return "false";
|
|
105
|
+
}
|
|
106
|
+
case "number" :
|
|
107
|
+
return String(value);
|
|
108
|
+
case "object" :
|
|
109
|
+
return "NULL";
|
|
110
|
+
default:
|
|
111
|
+
return Js_exn.raiseError("Invalid envio_chains value type");
|
|
112
|
+
}
|
|
113
|
+
}));
|
|
114
|
+
return "(" + values.join(", ") + ")";
|
|
115
|
+
}));
|
|
116
|
+
return "INSERT INTO \"" + pgSchema + "\".\"" + table$1.tableName + "\" (" + columnNames.join(", ") + ")\nVALUES " + valuesRows.join(",\n ") + ";";
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
var updateFields = [
|
|
120
|
+
"source_block",
|
|
121
|
+
"first_event_block",
|
|
122
|
+
"buffer_block",
|
|
123
|
+
"ready_at",
|
|
124
|
+
"events_processed",
|
|
125
|
+
"_is_hyper_sync",
|
|
126
|
+
"_latest_processed_block",
|
|
127
|
+
"_num_batches_fetched"
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
function makeSingleUpdateQuery(pgSchema) {
|
|
131
|
+
var setClauses = Belt_Array.mapWithIndex(updateFields, (function (index, field) {
|
|
132
|
+
var paramIndex = index + 2 | 0;
|
|
133
|
+
return "\"" + field + "\" = $" + String(paramIndex);
|
|
134
|
+
}));
|
|
135
|
+
return "UPDATE \"" + pgSchema + "\".\"" + table$1.tableName + "\"\nSET " + setClauses.join(",\n ") + "\nWHERE \"id\" = $1;";
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function setValues(sql, pgSchema, chainsData) {
|
|
139
|
+
var query = makeSingleUpdateQuery(pgSchema);
|
|
140
|
+
return Promise.all(Belt_Array.map(chainsData, (function (chain) {
|
|
141
|
+
var params = [];
|
|
142
|
+
var idValue = Js_dict.get(chain, "id");
|
|
143
|
+
params.push(idValue);
|
|
144
|
+
updateFields.forEach(function (field) {
|
|
145
|
+
var value = Js_dict.get(chain, field);
|
|
146
|
+
params.push(value);
|
|
147
|
+
});
|
|
148
|
+
return sql.unsafe(query, params, {prepare: true});
|
|
149
|
+
})));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
var Chains = {
|
|
153
|
+
fields: fields,
|
|
154
|
+
table: table$1,
|
|
155
|
+
initialFromConfig: initialFromConfig,
|
|
156
|
+
makeInitialValuesQuery: makeInitialValuesQuery,
|
|
157
|
+
updateFields: updateFields,
|
|
158
|
+
makeSingleUpdateQuery: makeSingleUpdateQuery,
|
|
159
|
+
setValues: setValues
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
var table$2 = Table.mkTable("persisted_state", undefined, [
|
|
163
|
+
Table.mkField("id", "SERIAL", S$RescriptSchema.$$int, undefined, undefined, undefined, true, undefined, undefined),
|
|
164
|
+
Table.mkField("envio_version", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
165
|
+
Table.mkField("config_hash", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
166
|
+
Table.mkField("schema_hash", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
167
|
+
Table.mkField("handler_files_hash", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
168
|
+
Table.mkField("abi_files_hash", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
169
|
+
]);
|
|
170
|
+
|
|
171
|
+
var PersistedState = {
|
|
172
|
+
table: table$2
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
var table$3 = Table.mkTable("end_of_block_range_scanned_data", undefined, [
|
|
176
|
+
Table.mkField("chain_id", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, true, undefined, undefined),
|
|
177
|
+
Table.mkField("block_number", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, true, undefined, undefined),
|
|
178
|
+
Table.mkField("block_hash", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
179
|
+
]);
|
|
180
|
+
|
|
181
|
+
var EndOfBlockRangeScannedData = {
|
|
182
|
+
table: table$3
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
var schema = S$RescriptSchema.schema(function (s) {
|
|
186
|
+
return {
|
|
187
|
+
chain_id: s.m(S$RescriptSchema.$$int),
|
|
188
|
+
event_id: s.m(S$RescriptSchema.bigint),
|
|
189
|
+
event_name: s.m(S$RescriptSchema.string),
|
|
190
|
+
contract_name: s.m(S$RescriptSchema.string),
|
|
191
|
+
block_number: s.m(S$RescriptSchema.$$int),
|
|
192
|
+
log_index: s.m(S$RescriptSchema.$$int),
|
|
193
|
+
src_address: s.m(Address.schema),
|
|
194
|
+
block_hash: s.m(S$RescriptSchema.string),
|
|
195
|
+
block_timestamp: s.m(S$RescriptSchema.$$int),
|
|
196
|
+
block_fields: s.m(S$RescriptSchema.json(false)),
|
|
197
|
+
transaction_fields: s.m(S$RescriptSchema.json(false)),
|
|
198
|
+
params: s.m(S$RescriptSchema.json(false))
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
var table$4 = Table.mkTable("raw_events", undefined, [
|
|
203
|
+
Table.mkField("chain_id", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
204
|
+
Table.mkField("event_id", "NUMERIC", S$RescriptSchema.bigint, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
205
|
+
Table.mkField("event_name", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
206
|
+
Table.mkField("contract_name", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
207
|
+
Table.mkField("block_number", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
208
|
+
Table.mkField("log_index", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
209
|
+
Table.mkField("src_address", "TEXT", Address.schema, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
210
|
+
Table.mkField("block_hash", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
211
|
+
Table.mkField("block_timestamp", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
212
|
+
Table.mkField("block_fields", "JSONB", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined),
|
|
213
|
+
Table.mkField("transaction_fields", "JSONB", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined),
|
|
214
|
+
Table.mkField("params", "JSONB", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined),
|
|
215
|
+
Table.mkField("db_write_timestamp", "TIMESTAMP", S$RescriptSchema.$$int, "CURRENT_TIMESTAMP", undefined, undefined, undefined, undefined, undefined),
|
|
216
|
+
Table.mkField("serial", "SERIAL", S$RescriptSchema.$$null(S$RescriptSchema.$$int), undefined, undefined, true, true, undefined, undefined)
|
|
217
|
+
]);
|
|
218
|
+
|
|
219
|
+
var RawEvents = {
|
|
220
|
+
schema: schema,
|
|
221
|
+
table: table$4
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
var name = "dynamic_contract_registry";
|
|
225
|
+
|
|
226
|
+
function makeId(chainId, contractAddress) {
|
|
227
|
+
return String(chainId) + "-" + contractAddress;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
var schema$1 = S$RescriptSchema.schema(function (s) {
|
|
231
|
+
return {
|
|
232
|
+
id: s.m(S$RescriptSchema.string),
|
|
233
|
+
chain_id: s.m(S$RescriptSchema.$$int),
|
|
234
|
+
registering_event_block_number: s.m(S$RescriptSchema.$$int),
|
|
235
|
+
registering_event_log_index: s.m(S$RescriptSchema.$$int),
|
|
236
|
+
registering_event_block_timestamp: s.m(S$RescriptSchema.$$int),
|
|
237
|
+
registering_event_contract_name: s.m(S$RescriptSchema.string),
|
|
238
|
+
registering_event_name: s.m(S$RescriptSchema.string),
|
|
239
|
+
registering_event_src_address: s.m(Address.schema),
|
|
240
|
+
contract_address: s.m(Address.schema),
|
|
241
|
+
contract_name: s.m(S$RescriptSchema.string)
|
|
242
|
+
};
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
var rowsSchema = S$RescriptSchema.array(schema$1);
|
|
246
|
+
|
|
247
|
+
var table$5 = Table.mkTable(name, undefined, [
|
|
248
|
+
Table.mkField("id", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, true, undefined, undefined),
|
|
249
|
+
Table.mkField("chain_id", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
250
|
+
Table.mkField("registering_event_block_number", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
251
|
+
Table.mkField("registering_event_log_index", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
252
|
+
Table.mkField("registering_event_block_timestamp", "INTEGER", S$RescriptSchema.$$int, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
253
|
+
Table.mkField("registering_event_contract_name", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
254
|
+
Table.mkField("registering_event_name", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
255
|
+
Table.mkField("registering_event_src_address", "TEXT", Address.schema, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
256
|
+
Table.mkField("contract_address", "TEXT", Address.schema, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
257
|
+
Table.mkField("contract_name", "TEXT", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
258
|
+
]);
|
|
259
|
+
|
|
260
|
+
var entityHistory = EntityHistory.fromTable(table$5, schema$1);
|
|
261
|
+
|
|
262
|
+
var config = {
|
|
263
|
+
name: name,
|
|
264
|
+
schema: schema$1,
|
|
265
|
+
rowsSchema: rowsSchema,
|
|
266
|
+
table: table$5,
|
|
267
|
+
entityHistory: entityHistory
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
var DynamicContractRegistry = {
|
|
271
|
+
name: name,
|
|
272
|
+
makeId: makeId,
|
|
273
|
+
schema: schema$1,
|
|
274
|
+
rowsSchema: rowsSchema,
|
|
275
|
+
table: table$5,
|
|
276
|
+
entityHistory: entityHistory,
|
|
277
|
+
config: config
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
var isPrimaryKey = true;
|
|
281
|
+
|
|
282
|
+
var isNullable = true;
|
|
283
|
+
|
|
284
|
+
var isIndex = true;
|
|
285
|
+
|
|
286
|
+
exports.isPrimaryKey = isPrimaryKey;
|
|
287
|
+
exports.isNullable = isNullable;
|
|
288
|
+
exports.isIndex = isIndex;
|
|
289
|
+
exports.EventSyncState = EventSyncState;
|
|
290
|
+
exports.Chains = Chains;
|
|
291
|
+
exports.PersistedState = PersistedState;
|
|
292
|
+
exports.EndOfBlockRangeScannedData = EndOfBlockRangeScannedData;
|
|
293
|
+
exports.RawEvents = RawEvents;
|
|
294
|
+
exports.DynamicContractRegistry = DynamicContractRegistry;
|
|
295
|
+
/* table Not a pure module */
|