envio 3.15.0-subgraph → 3.16.0

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.
Files changed (186) hide show
  1. package/README.md +40 -34
  2. package/evm.schema.json +3 -3
  3. package/fuel.schema.json +2 -2
  4. package/index.d.ts +3 -3
  5. package/licenses/README.md +1 -1
  6. package/package.json +9 -10
  7. package/src/Batch.res.mjs +5 -5
  8. package/src/BatchProcessing.res +1 -0
  9. package/src/BatchProcessing.res.mjs +1 -0
  10. package/src/Bin.res +0 -7
  11. package/src/Bin.res.mjs +0 -8
  12. package/src/ChainFetching.res +17 -456
  13. package/src/ChainFetching.res.mjs +33 -404
  14. package/src/ChainState.res +48 -83
  15. package/src/ChainState.res.mjs +83 -115
  16. package/src/ChainState.resi +0 -26
  17. package/src/Clock.res +57 -0
  18. package/src/Clock.res.mjs +72 -0
  19. package/src/Config.res +7 -16
  20. package/src/Config.res.mjs +4 -11
  21. package/src/ContractRegisterContext.res +6 -3
  22. package/src/ContractRegisterContext.res.mjs +2 -4
  23. package/src/Core.res +5 -136
  24. package/src/Core.res.mjs +1 -90
  25. package/src/CrossChainState.res +2 -8
  26. package/src/CrossChainState.res.mjs +3 -3
  27. package/src/Ecosystem.res +4 -7
  28. package/src/Ecosystem.res.mjs +8 -8
  29. package/src/EffectState.res +10 -2
  30. package/src/EffectState.res.mjs +8 -4
  31. package/src/EffectState.resi +3 -1
  32. package/src/EntityId.res +2 -7
  33. package/src/EntityId.res.mjs +1 -8
  34. package/src/EntityTables.res +4 -1
  35. package/src/EntityTables.res.mjs +1 -1
  36. package/src/Env.res +0 -16
  37. package/src/Env.res.mjs +0 -11
  38. package/src/EventProcessing.res +1 -38
  39. package/src/EventProcessing.res.mjs +1 -28
  40. package/src/FetchState.res +160 -319
  41. package/src/FetchState.res.mjs +182 -292
  42. package/src/FinalizeBackfill.res +2 -4
  43. package/src/FinalizeBackfill.res.mjs +3 -4
  44. package/src/HandlerLoader.res +15 -39
  45. package/src/HandlerLoader.res.mjs +8 -27
  46. package/src/HandlerRegister.res +0 -4
  47. package/src/HandlerRegister.res.mjs +2 -5
  48. package/src/HandlerRegister.resi +0 -2
  49. package/src/InMemoryTable.res +17 -16
  50. package/src/InMemoryTable.res.mjs +14 -15
  51. package/src/IndexerState.res +28 -4
  52. package/src/IndexerState.res.mjs +19 -6
  53. package/src/IndexerState.resi +4 -0
  54. package/src/Internal.res +0 -110
  55. package/src/Internal.res.mjs +1 -115
  56. package/src/LoadLayer.res +21 -47
  57. package/src/LoadLayer.res.mjs +47 -72
  58. package/src/LoadLayer.resi +0 -26
  59. package/src/Main.res +1 -14
  60. package/src/Main.res.mjs +3 -4
  61. package/src/Persistence.res +3 -23
  62. package/src/Persistence.res.mjs +3 -3
  63. package/src/Rollback.res +0 -1
  64. package/src/Rollback.res.mjs +1 -1
  65. package/src/RunScope.res +0 -3
  66. package/src/SafeCheckpointTracking.res +4 -4
  67. package/src/SafeCheckpointTracking.res.mjs +1 -1
  68. package/src/SimulateItems.res +26 -42
  69. package/src/SimulateItems.res.mjs +16 -40
  70. package/src/StagedRows.res +106 -0
  71. package/src/StagedRows.res.mjs +102 -0
  72. package/src/Staging.res +32 -14
  73. package/src/Staging.res.mjs +17 -20
  74. package/src/Storage.res +277 -998
  75. package/src/Storage.res.mjs +216 -731
  76. package/src/Supervisor.res +75 -56
  77. package/src/Supervisor.res.mjs +55 -26
  78. package/src/TestIndexer.res +22 -27
  79. package/src/TestIndexer.res.mjs +20 -17
  80. package/src/Throttler.res +15 -8
  81. package/src/Throttler.res.mjs +9 -6
  82. package/src/Throttler.resi +1 -1
  83. package/src/UserContext.res +46 -410
  84. package/src/UserContext.res.mjs +30 -318
  85. package/src/Utils.res +0 -23
  86. package/src/Utils.res.mjs +1 -17
  87. package/src/Writing.res +0 -1
  88. package/src/Writing.res.mjs +1 -1
  89. package/src/bindings/ClickHouse.res +0 -322
  90. package/src/bindings/ClickHouse.res.mjs +0 -338
  91. package/src/bindings/StorageClient.res +107 -175
  92. package/src/bindings/StorageClient.res.mjs +19 -8
  93. package/src/bindings/Vitest.res +0 -26
  94. package/src/bindings/Vitest.res.mjs +0 -3
  95. package/src/db/Table.res +24 -150
  96. package/src/db/Table.res.mjs +38 -272
  97. package/src/sources/AddressSet.res +0 -2
  98. package/src/sources/AddressStore.res +0 -3
  99. package/src/sources/ChainSources.res +2 -0
  100. package/src/sources/ChainSources.res.mjs +2 -2
  101. package/src/sources/EvmChain.res +4 -7
  102. package/src/sources/EvmChain.res.mjs +5 -4
  103. package/src/sources/EvmHyperSyncSource.res +2 -2
  104. package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
  105. package/src/sources/EvmRpcClient.res +13 -3
  106. package/src/sources/EvmRpcClient.res.mjs +4 -3
  107. package/src/sources/EvmRpcWs.res +4 -3
  108. package/src/sources/EvmRpcWs.res.mjs +2 -2
  109. package/src/sources/HeightFeed.res +31 -10
  110. package/src/sources/HeightFeed.res.mjs +10 -6
  111. package/src/sources/HeightStream.res +32 -17
  112. package/src/sources/HeightStream.res.mjs +10 -10
  113. package/src/sources/HyperSync.res +1 -2
  114. package/src/sources/HyperSync.res.mjs +1 -2
  115. package/src/sources/HyperSyncSSE.res +4 -6
  116. package/src/sources/HyperSyncSSE.res.mjs +2 -2
  117. package/src/sources/RpcSource.res +10 -1
  118. package/src/sources/RpcSource.res.mjs +4 -3
  119. package/src/sources/Source.res +3 -0
  120. package/src/sources/SourceManager.res +85 -104
  121. package/src/sources/SourceManager.res.mjs +18 -37
  122. package/src/sources/SourceManager.resi +3 -5
  123. package/src/sources/StartBlockResolver.res +1 -0
  124. package/src/sources/StartBlockResolver.res.mjs +4 -3
  125. package/src/sources/SvmHyperSyncSource.res +2 -2
  126. package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
  127. package/svm.schema.json +3 -3
  128. package/src/EffectCacheLookup.res +0 -98
  129. package/src/EffectCacheLookup.res.mjs +0 -116
  130. package/src/PgWriting.res +0 -36
  131. package/src/PgWriting.res.mjs +0 -34
  132. package/src/PreloadLookahead.res +0 -184
  133. package/src/PreloadLookahead.res.mjs +0 -197
  134. package/src/SubgraphLog.res +0 -19
  135. package/src/SubgraphLog.res.mjs +0 -26
  136. package/src/SyncWrites.res +0 -101
  137. package/src/SyncWrites.res.mjs +0 -98
  138. package/src/db/IndexDefinition.res +0 -47
  139. package/src/db/IndexDefinition.res.mjs +0 -60
  140. package/src/sources/CallSource.res +0 -274
  141. package/src/sources/CallSource.res.mjs +0 -196
  142. package/src/subgraph/abi-types.ts +0 -84
  143. package/src/subgraph/aggregations.ts +0 -745
  144. package/src/subgraph/as-package.ts +0 -143
  145. package/src/subgraph/assemblyscript-regex.ts +0 -67
  146. package/src/subgraph/assemblyscript.ts +0 -731
  147. package/src/subgraph/blocks.ts +0 -398
  148. package/src/subgraph/calls-source.ts +0 -702
  149. package/src/subgraph/calls.ts +0 -258
  150. package/src/subgraph/conformance.ts +0 -106
  151. package/src/subgraph/errors.ts +0 -85
  152. package/src/subgraph/graft.ts +0 -73
  153. package/src/subgraph/graph-cli-worker.mjs +0 -35
  154. package/src/subgraph/graph-cli.ts +0 -900
  155. package/src/subgraph/graph-node-decimal.ts +0 -199
  156. package/src/subgraph/graph-ts-enums.ts +0 -28
  157. package/src/subgraph/graph-ts-types/VERSION +0 -2
  158. package/src/subgraph/graph-ts-types/chain/arweave.d.ts +0 -70
  159. package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +0 -327
  160. package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +0 -233
  161. package/src/subgraph/graph-ts-types/chain/near.d.ts +0 -253
  162. package/src/subgraph/graph-ts-types/chain/starknet.d.ts +0 -32
  163. package/src/subgraph/graph-ts-types/common/collections.d.ts +0 -136
  164. package/src/subgraph/graph-ts-types/common/conversion.d.ts +0 -11
  165. package/src/subgraph/graph-ts-types/common/datasource.d.ts +0 -30
  166. package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
  167. package/src/subgraph/graph-ts-types/common/json.d.ts +0 -17
  168. package/src/subgraph/graph-ts-types/common/numbers.d.ts +0 -120
  169. package/src/subgraph/graph-ts-types/common/value.d.ts +0 -120
  170. package/src/subgraph/graph-ts-types/common/yaml.d.ts +0 -90
  171. package/src/subgraph/graph-ts-types/global/global.d.ts +0 -194
  172. package/src/subgraph/graph-ts-types/helper-functions.d.ts +0 -22
  173. package/src/subgraph/graph-ts-types/index.d.ts +0 -102
  174. package/src/subgraph/graph-ts.ts +0 -4280
  175. package/src/subgraph/hosts.ts +0 -554
  176. package/src/subgraph/log.ts +0 -28
  177. package/src/subgraph/receipts.ts +0 -184
  178. package/src/subgraph/register-slots.ts +0 -93
  179. package/src/subgraph/rollup.ts +0 -109
  180. package/src/subgraph/rpc.ts +0 -337
  181. package/src/subgraph/runtime.ts +0 -2060
  182. package/src/subgraph/scope.ts +0 -177
  183. package/src/subgraph/stats.ts +0 -42
  184. package/src/subgraph/template-instances.ts +0 -66
  185. package/src/subgraph/toolchain.ts +0 -327
  186. package/src/subgraph/transient.ts +0 -176
@@ -1,26 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
-
4
- let listeners = [];
5
-
6
- function onLog(listener) {
7
- listeners.push(listener);
8
- return () => {
9
- let index = listeners.indexOf(listener);
10
- if (index !== -1) {
11
- listeners.splice(index, 1);
12
- return;
13
- }
14
- };
15
- }
16
-
17
- function notify(level, message) {
18
- listeners.forEach(listener => listener(level, message));
19
- }
20
-
21
- export {
22
- listeners,
23
- onLog,
24
- notify,
25
- }
26
- /* No side effect */
@@ -1,101 +0,0 @@
1
- // The writes one round of a synchronous handler has made. A round that
2
- // suspends is replayed from the top, so its writes are held here rather than
3
- // applied: the replay has to see the store exactly as the first round did, or a
4
- // read-modify-write lands once per round.
5
-
6
- type table = {
7
- entityConfig: Internal.entityConfig,
8
- scope: Internal.chainScope,
9
- changes: dict<Change.t<Internal.entity>>,
10
- }
11
-
12
- // A handler runs on one chain, so an entity's scope is fixed for the whole
13
- // round and the entity name is enough to key its table.
14
- type t = dict<table>
15
-
16
- let make = (): t => Dict.make()
17
-
18
- let record = (writes: t, ~entityConfig: Internal.entityConfig, ~scope, change) => {
19
- let table = switch writes->Utils.Dict.dangerouslyGetNonOption(entityConfig.name) {
20
- | Some(table) => table
21
- | None =>
22
- let table = {entityConfig, scope, changes: Dict.make()}
23
- writes->Dict.set(entityConfig.name, table)
24
- table
25
- }
26
- table.changes->Dict.set(change->Change.getEntityId->EntityId.toKey, change)
27
- }
28
-
29
- let changesOf = (writes: t, ~entityConfig: Internal.entityConfig) =>
30
- switch writes->Utils.Dict.dangerouslyGetNonOption(entityConfig.name) {
31
- | Some({changes}) => Some(changes)
32
- | None => None
33
- }
34
-
35
- // `Some(None)` is a delete this round made: the entity is known not to exist.
36
- let getById = (writes: t, ~entityConfig, ~entityId: string) =>
37
- switch writes->changesOf(~entityConfig) {
38
- | Some(changes) =>
39
- changes
40
- ->Utils.Dict.dangerouslyGetNonOption(entityId)
41
- ->Option.map(InMemoryTable.Entity.mapChangeToEntity)
42
- | None => None
43
- }
44
-
45
- // What the store answered, as it reads once this round's writes land: a row
46
- // the round rewrote is re-tested against the filter, and one it created joins.
47
- let overlayFilter = (
48
- writes: t,
49
- entities: array<Internal.entity>,
50
- ~entityConfig: Internal.entityConfig,
51
- ~filter: EntityFilter.t,
52
- ) =>
53
- switch writes->changesOf(~entityConfig) {
54
- | None => entities
55
- | Some(changes) =>
56
- let matches = filter->EntityFilter.makeMatcher(~table=entityConfig.table)
57
- let untouched =
58
- entities->Array.filter(entity =>
59
- !(changes->Dict.has(entity->InMemoryTable.Entity.getEntityIdUnsafe))
60
- )
61
- let written =
62
- changes
63
- ->Dict.valuesToArray
64
- ->Array.filterMap(change =>
65
- switch change->InMemoryTable.Entity.mapChangeToEntity {
66
- | Some(entity) if matches(entity) => Some(entity)
67
- | _ => None
68
- }
69
- )
70
- untouched->Array.concat(written)
71
- }
72
-
73
- // How a change lands in the in-memory store, whether written directly or
74
- // committed at the end of a round.
75
- let write = (indexerState, ~entityConfig: Internal.entityConfig, ~scope, change) => {
76
- switch change {
77
- | Change.Set({entityId}) =>
78
- PreloadLookahead.onSet(
79
- ~entityName=entityConfig.name,
80
- ~scope,
81
- ~entityId=entityId->EntityId.toKey,
82
- )
83
- | Delete(_) => ()
84
- }
85
- indexerState
86
- ->InMemoryStore.getInMemTable(~entityConfig, ~scope)
87
- ->InMemoryTable.Entity.set(
88
- ~committedCheckpointId=indexerState->IndexerState.committedCheckpointIdFor(~scope),
89
- change,
90
- )
91
- }
92
-
93
- let forEachChange = (writes: t, fn) =>
94
- writes->Utils.Dict.forEach(({entityConfig, scope, changes}) =>
95
- changes->Utils.Dict.forEach(change => fn(~entityConfig, ~scope, change))
96
- )
97
-
98
- let commit = (writes: t, ~indexerState) =>
99
- writes->Utils.Dict.forEach(({entityConfig, scope, changes}) =>
100
- changes->Utils.Dict.forEach(change => indexerState->write(~entityConfig, ~scope, change))
101
- )
@@ -1,98 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Utils from "./Utils.res.mjs";
4
- import * as EntityId from "./EntityId.res.mjs";
5
- import * as EntityFilter from "./db/EntityFilter.res.mjs";
6
- import * as IndexerState from "./IndexerState.res.mjs";
7
- import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
8
- import * as InMemoryStore from "./InMemoryStore.res.mjs";
9
- import * as InMemoryTable from "./InMemoryTable.res.mjs";
10
- import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
11
- import * as PreloadLookahead from "./PreloadLookahead.res.mjs";
12
-
13
- function make() {
14
- return {};
15
- }
16
-
17
- function record(writes, entityConfig, scope, change) {
18
- let table = writes[entityConfig.name];
19
- let table$1;
20
- if (table !== undefined) {
21
- table$1 = table;
22
- } else {
23
- let table_changes = {};
24
- let table$2 = {
25
- entityConfig: entityConfig,
26
- scope: scope,
27
- changes: table_changes
28
- };
29
- writes[entityConfig.name] = table$2;
30
- table$1 = table$2;
31
- }
32
- table$1.changes[EntityId.toKey(change.entityId)] = change;
33
- }
34
-
35
- function changesOf(writes, entityConfig) {
36
- let match = writes[entityConfig.name];
37
- if (match !== undefined) {
38
- return match.changes;
39
- }
40
- }
41
-
42
- function getById(writes, entityConfig, entityId) {
43
- let changes = changesOf(writes, entityConfig);
44
- if (changes !== undefined) {
45
- return Stdlib_Option.map(changes[entityId], InMemoryTable.Entity.mapChangeToEntity);
46
- }
47
- }
48
-
49
- function overlayFilter(writes, entities, entityConfig, filter) {
50
- let changes = changesOf(writes, entityConfig);
51
- if (changes === undefined) {
52
- return entities;
53
- }
54
- let matches = EntityFilter.makeMatcher(filter, entityConfig.table);
55
- let untouched = entities.filter(entity => !(InMemoryTable.Entity.getEntityIdUnsafe(entity) in changes));
56
- let written = Stdlib_Array.filterMap(Object.values(changes), change => {
57
- let entity = InMemoryTable.Entity.mapChangeToEntity(change);
58
- if (entity !== undefined && matches(entity)) {
59
- return entity;
60
- }
61
- });
62
- return untouched.concat(written);
63
- }
64
-
65
- function write(indexerState, entityConfig, scope, change) {
66
- if (change.type === "SET") {
67
- PreloadLookahead.onSet(entityConfig.name, scope, EntityId.toKey(change.entityId));
68
- }
69
- InMemoryTable.Entity.set(InMemoryStore.getInMemTable(indexerState, entityConfig, scope), IndexerState.committedCheckpointIdFor(indexerState, scope), change);
70
- }
71
-
72
- function forEachChange(writes, fn) {
73
- Utils.Dict.forEach(writes, param => {
74
- let scope = param.scope;
75
- let entityConfig = param.entityConfig;
76
- Utils.Dict.forEach(param.changes, change => fn(entityConfig, scope, change));
77
- });
78
- }
79
-
80
- function commit(writes, indexerState) {
81
- Utils.Dict.forEach(writes, param => {
82
- let scope = param.scope;
83
- let entityConfig = param.entityConfig;
84
- Utils.Dict.forEach(param.changes, change => write(indexerState, entityConfig, scope, change));
85
- });
86
- }
87
-
88
- export {
89
- make,
90
- record,
91
- changesOf,
92
- getById,
93
- overlayFilter,
94
- write,
95
- forEachChange,
96
- commit,
97
- }
98
- /* Utils Not a pure module */
@@ -1,47 +0,0 @@
1
- // What the indexer wants an index to be: a table, its ordered key columns with
2
- // their directions, and an access method. The addon names it, matches it
3
- // against what PostgreSQL holds and builds it.
4
-
5
- type column = {
6
- name: string,
7
- direction: Table.indexFieldDirection,
8
- }
9
-
10
- type t = {
11
- tableName: string,
12
- columns: array<column>,
13
- method: string,
14
- }
15
-
16
- let make = (~tableName, ~columns, ~method="btree") => {tableName, columns, method}
17
-
18
- let single = (~tableName, ~column) =>
19
- make(~tableName, ~columns=[{name: column, direction: Table.Asc}])
20
-
21
- let fromIndexFields = (~tableName, ~indexFields: array<Table.compositeIndexField>) =>
22
- make(
23
- ~tableName,
24
- ~columns=indexFields->Array.map(({fieldName, direction}) => {name: fieldName, direction}),
25
- )
26
-
27
- let toInput = ({tableName, columns, method}: t): Core.pgIndexInput => {
28
- tableName,
29
- columns: columns->Array.map(({name, direction}): Core.pgIndexColumnInput => {
30
- name,
31
- direction: switch direction {
32
- | Table.Asc => "Asc"
33
- | Desc => "Desc"
34
- },
35
- }),
36
- method,
37
- }
38
-
39
- let describe = (definition: t) =>
40
- `${definition.tableName}(${definition.columns
41
- ->Array.map(({name, direction}) =>
42
- switch direction {
43
- | Asc => name
44
- | Desc => `${name} DESC`
45
- }
46
- )
47
- ->Array.joinUnsafe(", ")}) using ${definition.method}`
@@ -1,60 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
-
4
- function make(tableName, columns, methodOpt) {
5
- let method = methodOpt !== undefined ? methodOpt : "btree";
6
- return {
7
- tableName: tableName,
8
- columns: columns,
9
- method: method
10
- };
11
- }
12
-
13
- function single(tableName, column) {
14
- return make(tableName, [{
15
- name: column,
16
- direction: "Asc"
17
- }], undefined);
18
- }
19
-
20
- function fromIndexFields(tableName, indexFields) {
21
- return make(tableName, indexFields.map(param => ({
22
- name: param.fieldName,
23
- direction: param.direction
24
- })), undefined);
25
- }
26
-
27
- function toInput(param) {
28
- return {
29
- tableName: param.tableName,
30
- columns: param.columns.map(param => {
31
- let tmp;
32
- tmp = param.direction === "Asc" ? "Asc" : "Desc";
33
- return {
34
- name: param.name,
35
- direction: tmp
36
- };
37
- }),
38
- method: param.method
39
- };
40
- }
41
-
42
- function describe(definition) {
43
- return definition.tableName + `(` + definition.columns.map(param => {
44
- let name = param.name;
45
- if (param.direction === "Asc") {
46
- return name;
47
- } else {
48
- return name + ` DESC`;
49
- }
50
- }).join(", ") + `) using ` + definition.method;
51
- }
52
-
53
- export {
54
- make,
55
- single,
56
- fromIndexFields,
57
- toInput,
58
- describe,
59
- }
60
- /* No side effect */
@@ -1,274 +0,0 @@
1
- // Subgraph mode only. A subgraph's call handlers run on calls, which a log
2
- // source never sees, so each source of a chain is wrapped: it fetches the logs
3
- // of a query as before, and the calls of the same block range from a trace
4
- // backend (`subgraph/calls-source.ts`). A call comes back as the event item it
5
- // travels as for the rest of envio — partitioning, ordering, the register
6
- // pass and rollback never tell it from a log.
7
-
8
- type callRegistration = {
9
- index: int,
10
- contractName: string,
11
- eventName: string,
12
- selector: Nullable.t<string>,
13
- rank: int,
14
- isWildcard: bool,
15
- startBlock: Nullable.t<int>,
16
- }
17
-
18
- type request = {
19
- chainId: ChainId.t,
20
- fromBlock: int,
21
- toBlock: int,
22
- registrations: array<callRegistration>,
23
- addresses: dict<array<string>>,
24
- rpcUrls: array<string>,
25
- }
26
-
27
- type callItem = {
28
- registrationIndex: int,
29
- blockNumber: int,
30
- transactionIndex: int,
31
- traceAddress: array<int>,
32
- payload: Internal.eventPayload,
33
- }
34
-
35
- type response = {
36
- items: array<callItem>,
37
- latestFetchedBlockNumber: int,
38
- blocks: array<BlockStore.inputBlock>,
39
- knownHeight: Nullable.t<int>,
40
- }
41
-
42
- type installed = {
43
- fetchCalls: request => promise<response>,
44
- rpcUrls: array<string>,
45
- }
46
-
47
- let installed: ref<option<installed>> = ref(None)
48
-
49
- let install = (~fetchCalls, ~rpcUrls) => {
50
- installed := Some({fetchCalls, rpcUrls})
51
- }
52
-
53
- // The block range one call query covers when the partition's own is open-ended.
54
- let openEndedSpan = 1_000_000
55
-
56
- let callRankOf = (registration: Internal.onEventRegistration) =>
57
- Internal.callRankOfEventName(registration.eventConfig.name)
58
-
59
- // `__envio_call_<8 hex digits>_<function>`
60
- let selectorOf = (registration: Internal.onEventRegistration) =>
61
- switch registration->callRankOf {
62
- | Some(1) =>
63
- Nullable.Value(
64
- "0x" ++ registration.eventConfig.name->String.slice(~start=13, ~end=21)->String.toLowerCase,
65
- )
66
- | _ => Nullable.null
67
- }
68
-
69
- let wrap = (
70
- source: Source.t,
71
- ~addressStore: AddressStore.t,
72
- ~ecosystem: Ecosystem.name,
73
- installed: installed,
74
- ): Source.t => {
75
- ...source,
76
- getItemsOrThrow: async (
77
- ~fromBlock,
78
- ~toBlock,
79
- ~addressSet,
80
- ~reorgableFrom,
81
- ~knownHeight,
82
- ~partitionId,
83
- ~selection: FetchState.selection,
84
- ~itemsTarget,
85
- ~retry,
86
- ~logger,
87
- ) => {
88
- let callRegistrations =
89
- selection.onEventRegistrations->Array.filter(registration =>
90
- registration->callRankOf->Option.isSome
91
- )
92
- if callRegistrations->Utils.Array.isEmpty {
93
- await source.getItemsOrThrow(
94
- ~fromBlock,
95
- ~toBlock,
96
- ~addressSet,
97
- ~reorgableFrom,
98
- ~knownHeight,
99
- ~partitionId,
100
- ~selection,
101
- ~itemsTarget,
102
- ~retry,
103
- ~logger,
104
- )
105
- } else {
106
- let logRegistrations =
107
- selection.onEventRegistrations->Array.filter(registration =>
108
- registration->callRankOf->Option.isNone
109
- )
110
- let logs = if (
111
- logRegistrations->Utils.Array.isEmpty && selection.onBlockRegistrations->Utils.Array.isEmpty
112
- ) {
113
- None
114
- } else {
115
- Some(
116
- await source.getItemsOrThrow(
117
- ~fromBlock,
118
- ~toBlock,
119
- ~addressSet,
120
- ~reorgableFrom,
121
- ~knownHeight,
122
- ~partitionId,
123
- ~selection={...selection, onEventRegistrations: logRegistrations},
124
- ~itemsTarget,
125
- ~retry,
126
- ~logger,
127
- ),
128
- )
129
- }
130
-
131
- // Calls are asked for only as far as the logs were: a source may stop a
132
- // page short, and the two have to agree on where the answer ends.
133
- let rangeEnd = switch (logs, toBlock) {
134
- | (Some(logs), _) => logs.latestFetchedBlockNumber
135
- | (None, Some(toBlock)) => toBlock
136
- | (None, None) => Math.Int.min(knownHeight, fromBlock + openEndedSpan)
137
- }
138
-
139
- let clientFiltered = contractName =>
140
- switch selection.clientFilteredContracts {
141
- | Some(contractNames) => contractNames->Array.includes(contractName)
142
- | None => false
143
- }
144
- let addresses = Dict.make()
145
- callRegistrations->Array.forEach(registration => {
146
- let contractName = registration.eventConfig.contractName
147
- if !registration.isWildcard && addresses->Dict.get(contractName)->Option.isNone {
148
- addresses->Dict.set(
149
- contractName,
150
- clientFiltered(contractName)
151
- ? addressStore->AddressStore.contractAddresses(contractName, ~shouldChecksum=false)
152
- : addressSet->AddressSet.addressesOf(contractName),
153
- )
154
- }
155
- })
156
-
157
- let startedAt = Performance.now()
158
- let response = try await installed.fetchCalls({
159
- chainId: source.chainId,
160
- fromBlock,
161
- toBlock: rangeEnd,
162
- registrations: callRegistrations->Array.map(registration => {
163
- index: registration.index,
164
- contractName: registration.eventConfig.contractName,
165
- eventName: registration.eventConfig.name,
166
- selector: registration->selectorOf,
167
- rank: registration->callRankOf->Option.getOr(1),
168
- isWildcard: registration.isWildcard,
169
- startBlock: registration.startBlock->Nullable.fromOption,
170
- }),
171
- addresses: addresses->(Utils.magic: dict<array<Address.t>> => dict<array<string>>),
172
- rpcUrls: installed.rpcUrls,
173
- }) catch {
174
- | exn =>
175
- throw(
176
- Source.GetItemsError(
177
- Source.FailedGettingItems({
178
- exn,
179
- attemptedToBlock: rangeEnd,
180
- retry: WithBackoff({
181
- message: `Failed reading the calls of blocks ${fromBlock->Int.toString} to ${rangeEnd->Int.toString}. Attempt a retry.`,
182
- backoffMillis: switch retry {
183
- | 0 => 500
184
- | _ => 1000 * retry
185
- },
186
- }),
187
- requestStats: [],
188
- }),
189
- ),
190
- )
191
- }
192
- let callSeconds = startedAt->Performance.secondsSince
193
-
194
- let registrationByIndex = Dict.make()
195
- callRegistrations->Array.forEach(registration =>
196
- registrationByIndex->Dict.set(registration.index->Int.toString, registration)
197
- )
198
- let latest = response.latestFetchedBlockNumber
199
- let callItems = response.items->Array.filterMap(callItem => {
200
- let registration =
201
- registrationByIndex->Dict.getUnsafe(callItem.registrationIndex->Int.toString)
202
- let contractName = registration.eventConfig.contractName
203
- // The partition's own slice of the contract's addresses, as a log's
204
- // router applies it; a client-filtered contract answers to the store.
205
- let ownsCall =
206
- registration.isWildcard || {
207
- let address = callItem.payload->Internal.getPayloadSrcAddress
208
- if clientFiltered(contractName) {
209
- addressStore->AddressStore.isIndexedAt(address, contractName, callItem.blockNumber)
210
- } else {
211
- addressSet->AddressSet.containsAt(address, contractName, callItem.blockNumber)
212
- }
213
- }
214
- if callItem.blockNumber <= latest && ownsCall {
215
- let item = Internal.Event({
216
- onEventRegistration: registration,
217
- chainId: source.chainId,
218
- blockNumber: callItem.blockNumber,
219
- logIndex: 0,
220
- orderPath: callItem.traceAddress,
221
- transactionIndex: callItem.transactionIndex,
222
- payload: callItem.payload,
223
- })
224
- item->Internal.markItemCall(~rank=registration->callRankOf->Option.getOr(1))
225
- Some(item)
226
- } else {
227
- None
228
- }
229
- })
230
-
231
- let callBlocks = BlockStore.fromJs(response.blocks, ~ecosystem)
232
- let callRequestStat = {Source.method: "getCalls", seconds: callSeconds}
233
- switch logs {
234
- | Some(logs) =>
235
- logs.blockStore->BlockStore.appendPage(callBlocks)
236
- {
237
- ...logs,
238
- parsedQueueItems: Array.concat(
239
- logs.parsedQueueItems->Array.filter(item =>
240
- item->Internal.getItemBlockNumber <= latest
241
- ),
242
- callItems,
243
- ),
244
- latestFetchedBlockNumber: Math.Int.min(logs.latestFetchedBlockNumber, latest),
245
- requestStats: Array.concat(logs.requestStats, [callRequestStat]),
246
- }
247
- | None => {
248
- Source.knownHeight: response.knownHeight->Nullable.getOr(knownHeight),
249
- parsedQueueItems: callItems,
250
- transactionStore: None,
251
- blockStore: callBlocks,
252
- latestFetchedBlockNumber: latest,
253
- stats: {totalTimeElapsed: callSeconds},
254
- requestStats: [callRequestStat],
255
- }
256
- }
257
- }
258
- },
259
- }
260
-
261
- // Wraps every source of a chain when its registrations hold a call trigger
262
- // and the subgraph runtime has installed the backend that reads them.
263
- let wrapSources = (
264
- sources: array<Source.t>,
265
- ~onEventRegistrations: array<Internal.onEventRegistration>,
266
- ~addressStore,
267
- ~ecosystem,
268
- ) =>
269
- switch installed.contents {
270
- | Some(installed)
271
- if onEventRegistrations->Array.some(registration => registration->callRankOf->Option.isSome) =>
272
- sources->Array.map(source => source->wrap(~addressStore, ~ecosystem, installed))
273
- | _ => sources
274
- }