@subsquid/ponder 0.16.6
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/CHANGELOG.md +3452 -0
- package/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/esm/bin/commands/codegen.js +46 -0
- package/dist/esm/bin/commands/codegen.js.map +1 -0
- package/dist/esm/bin/commands/createViews.js +196 -0
- package/dist/esm/bin/commands/createViews.js.map +1 -0
- package/dist/esm/bin/commands/dev.js +430 -0
- package/dist/esm/bin/commands/dev.js.map +1 -0
- package/dist/esm/bin/commands/list.js +148 -0
- package/dist/esm/bin/commands/list.js.map +1 -0
- package/dist/esm/bin/commands/prune.js +223 -0
- package/dist/esm/bin/commands/prune.js.map +1 -0
- package/dist/esm/bin/commands/serve.js +198 -0
- package/dist/esm/bin/commands/serve.js.map +1 -0
- package/dist/esm/bin/commands/start.js +253 -0
- package/dist/esm/bin/commands/start.js.map +1 -0
- package/dist/esm/bin/isolatedController.js +200 -0
- package/dist/esm/bin/isolatedController.js.map +1 -0
- package/dist/esm/bin/isolatedWorker.js +146 -0
- package/dist/esm/bin/isolatedWorker.js.map +1 -0
- package/dist/esm/bin/ponder.js +137 -0
- package/dist/esm/bin/ponder.js.map +1 -0
- package/dist/esm/bin/utils/codegen.js +25 -0
- package/dist/esm/bin/utils/codegen.js.map +1 -0
- package/dist/esm/bin/utils/exit.js +100 -0
- package/dist/esm/bin/utils/exit.js.map +1 -0
- package/dist/esm/build/config.js +746 -0
- package/dist/esm/build/config.js.map +1 -0
- package/dist/esm/build/factory.js +82 -0
- package/dist/esm/build/factory.js.map +1 -0
- package/dist/esm/build/index.js +567 -0
- package/dist/esm/build/index.js.map +1 -0
- package/dist/esm/build/plugin.js +53 -0
- package/dist/esm/build/plugin.js.map +1 -0
- package/dist/esm/build/pre.js +83 -0
- package/dist/esm/build/pre.js.map +1 -0
- package/dist/esm/build/schema.js +202 -0
- package/dist/esm/build/schema.js.map +1 -0
- package/dist/esm/build/stacktrace.js +137 -0
- package/dist/esm/build/stacktrace.js.map +1 -0
- package/dist/esm/client/index.js +441 -0
- package/dist/esm/client/index.js.map +1 -0
- package/dist/esm/config/address.js +2 -0
- package/dist/esm/config/address.js.map +1 -0
- package/dist/esm/config/eventFilter.js +2 -0
- package/dist/esm/config/eventFilter.js.map +1 -0
- package/dist/esm/config/index.js +2 -0
- package/dist/esm/config/index.js.map +1 -0
- package/dist/esm/config/utilityTypes.js +2 -0
- package/dist/esm/config/utilityTypes.js.map +1 -0
- package/dist/esm/database/actions.js +445 -0
- package/dist/esm/database/actions.js.map +1 -0
- package/dist/esm/database/index.js +604 -0
- package/dist/esm/database/index.js.map +1 -0
- package/dist/esm/database/queryBuilder.js +314 -0
- package/dist/esm/database/queryBuilder.js.map +1 -0
- package/dist/esm/drizzle/bigint.js +38 -0
- package/dist/esm/drizzle/bigint.js.map +1 -0
- package/dist/esm/drizzle/bytes.js +47 -0
- package/dist/esm/drizzle/bytes.js.map +1 -0
- package/dist/esm/drizzle/hex.js +40 -0
- package/dist/esm/drizzle/hex.js.map +1 -0
- package/dist/esm/drizzle/index.js +28 -0
- package/dist/esm/drizzle/index.js.map +1 -0
- package/dist/esm/drizzle/json.js +123 -0
- package/dist/esm/drizzle/json.js.map +1 -0
- package/dist/esm/drizzle/kit/index.js +927 -0
- package/dist/esm/drizzle/kit/index.js.map +1 -0
- package/dist/esm/drizzle/onchain.js +184 -0
- package/dist/esm/drizzle/onchain.js.map +1 -0
- package/dist/esm/drizzle/text.js +61 -0
- package/dist/esm/drizzle/text.js.map +1 -0
- package/dist/esm/graphql/graphiql.html.js +59 -0
- package/dist/esm/graphql/graphiql.html.js.map +1 -0
- package/dist/esm/graphql/index.js +964 -0
- package/dist/esm/graphql/index.js.map +1 -0
- package/dist/esm/graphql/json.js +42 -0
- package/dist/esm/graphql/json.js.map +1 -0
- package/dist/esm/graphql/middleware.js +83 -0
- package/dist/esm/graphql/middleware.js.map +1 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/indexing/addStackTrace.js +54 -0
- package/dist/esm/indexing/addStackTrace.js.map +1 -0
- package/dist/esm/indexing/client.js +675 -0
- package/dist/esm/indexing/client.js.map +1 -0
- package/dist/esm/indexing/index.js +663 -0
- package/dist/esm/indexing/index.js.map +1 -0
- package/dist/esm/indexing/profile.js +584 -0
- package/dist/esm/indexing/profile.js.map +1 -0
- package/dist/esm/indexing-store/cache.js +666 -0
- package/dist/esm/indexing-store/cache.js.map +1 -0
- package/dist/esm/indexing-store/index.js +461 -0
- package/dist/esm/indexing-store/index.js.map +1 -0
- package/dist/esm/indexing-store/profile.js +428 -0
- package/dist/esm/indexing-store/profile.js.map +1 -0
- package/dist/esm/indexing-store/utils.js +111 -0
- package/dist/esm/indexing-store/utils.js.map +1 -0
- package/dist/esm/internal/common.js +2 -0
- package/dist/esm/internal/common.js.map +1 -0
- package/dist/esm/internal/errors.js +300 -0
- package/dist/esm/internal/errors.js.map +1 -0
- package/dist/esm/internal/logger.js +178 -0
- package/dist/esm/internal/logger.js.map +1 -0
- package/dist/esm/internal/metrics.js +1049 -0
- package/dist/esm/internal/metrics.js.map +1 -0
- package/dist/esm/internal/options.js +73 -0
- package/dist/esm/internal/options.js.map +1 -0
- package/dist/esm/internal/shutdown.js +24 -0
- package/dist/esm/internal/shutdown.js.map +1 -0
- package/dist/esm/internal/telemetry.js +200 -0
- package/dist/esm/internal/telemetry.js.map +1 -0
- package/dist/esm/internal/types.js +2 -0
- package/dist/esm/internal/types.js.map +1 -0
- package/dist/esm/rpc/actions.js +987 -0
- package/dist/esm/rpc/actions.js.map +1 -0
- package/dist/esm/rpc/http.js +130 -0
- package/dist/esm/rpc/http.js.map +1 -0
- package/dist/esm/rpc/index.js +749 -0
- package/dist/esm/rpc/index.js.map +1 -0
- package/dist/esm/runtime/events.js +664 -0
- package/dist/esm/runtime/events.js.map +1 -0
- package/dist/esm/runtime/filter.js +443 -0
- package/dist/esm/runtime/filter.js.map +1 -0
- package/dist/esm/runtime/fragments.js +478 -0
- package/dist/esm/runtime/fragments.js.map +1 -0
- package/dist/esm/runtime/historical.js +953 -0
- package/dist/esm/runtime/historical.js.map +1 -0
- package/dist/esm/runtime/index.js +316 -0
- package/dist/esm/runtime/index.js.map +1 -0
- package/dist/esm/runtime/isolated.js +463 -0
- package/dist/esm/runtime/isolated.js.map +1 -0
- package/dist/esm/runtime/multichain.js +510 -0
- package/dist/esm/runtime/multichain.js.map +1 -0
- package/dist/esm/runtime/omnichain.js +545 -0
- package/dist/esm/runtime/omnichain.js.map +1 -0
- package/dist/esm/runtime/realtime.js +724 -0
- package/dist/esm/runtime/realtime.js.map +1 -0
- package/dist/esm/server/error.js +56 -0
- package/dist/esm/server/error.js.map +1 -0
- package/dist/esm/server/index.js +121 -0
- package/dist/esm/server/index.js.map +1 -0
- package/dist/esm/sync-historical/index.js +711 -0
- package/dist/esm/sync-historical/index.js.map +1 -0
- package/dist/esm/sync-historical/portal-transform.js +104 -0
- package/dist/esm/sync-historical/portal-transform.js.map +1 -0
- package/dist/esm/sync-historical/portal.js +592 -0
- package/dist/esm/sync-historical/portal.js.map +1 -0
- package/dist/esm/sync-realtime/bloom.js +76 -0
- package/dist/esm/sync-realtime/bloom.js.map +1 -0
- package/dist/esm/sync-realtime/index.js +917 -0
- package/dist/esm/sync-realtime/index.js.map +1 -0
- package/dist/esm/sync-store/encode.js +105 -0
- package/dist/esm/sync-store/encode.js.map +1 -0
- package/dist/esm/sync-store/index.js +885 -0
- package/dist/esm/sync-store/index.js.map +1 -0
- package/dist/esm/sync-store/migrations.js +1595 -0
- package/dist/esm/sync-store/migrations.js.map +1 -0
- package/dist/esm/sync-store/schema.js +181 -0
- package/dist/esm/sync-store/schema.js.map +1 -0
- package/dist/esm/types/db.js +2 -0
- package/dist/esm/types/db.js.map +1 -0
- package/dist/esm/types/eth.js +2 -0
- package/dist/esm/types/eth.js.map +1 -0
- package/dist/esm/types/utils.js +2 -0
- package/dist/esm/types/utils.js.map +1 -0
- package/dist/esm/types/virtual.js +2 -0
- package/dist/esm/types/virtual.js.map +1 -0
- package/dist/esm/ui/app.js +157 -0
- package/dist/esm/ui/app.js.map +1 -0
- package/dist/esm/ui/index.js +29 -0
- package/dist/esm/ui/index.js.map +1 -0
- package/dist/esm/ui/patch.js +140 -0
- package/dist/esm/ui/patch.js.map +1 -0
- package/dist/esm/utils/abi.js +55 -0
- package/dist/esm/utils/abi.js.map +1 -0
- package/dist/esm/utils/bigint.js +37 -0
- package/dist/esm/utils/bigint.js.map +1 -0
- package/dist/esm/utils/chains.js +21 -0
- package/dist/esm/utils/chains.js.map +1 -0
- package/dist/esm/utils/checkpoint.js +139 -0
- package/dist/esm/utils/checkpoint.js.map +1 -0
- package/dist/esm/utils/chunk.js +8 -0
- package/dist/esm/utils/chunk.js.map +1 -0
- package/dist/esm/utils/copy.js +129 -0
- package/dist/esm/utils/copy.js.map +1 -0
- package/dist/esm/utils/date.js +27 -0
- package/dist/esm/utils/date.js.map +1 -0
- package/dist/esm/utils/debug.js +2 -0
- package/dist/esm/utils/debug.js.map +1 -0
- package/dist/esm/utils/decodeAbiParameters.js +290 -0
- package/dist/esm/utils/decodeAbiParameters.js.map +1 -0
- package/dist/esm/utils/decodeEventLog.js +75 -0
- package/dist/esm/utils/decodeEventLog.js.map +1 -0
- package/dist/esm/utils/dedupe.js +29 -0
- package/dist/esm/utils/dedupe.js.map +1 -0
- package/dist/esm/utils/duplicates.js +19 -0
- package/dist/esm/utils/duplicates.js.map +1 -0
- package/dist/esm/utils/estimate.js +6 -0
- package/dist/esm/utils/estimate.js.map +1 -0
- package/dist/esm/utils/finality.js +38 -0
- package/dist/esm/utils/finality.js.map +1 -0
- package/dist/esm/utils/format.js +20 -0
- package/dist/esm/utils/format.js.map +1 -0
- package/dist/esm/utils/generators.js +121 -0
- package/dist/esm/utils/generators.js.map +1 -0
- package/dist/esm/utils/hash.js +11 -0
- package/dist/esm/utils/hash.js.map +1 -0
- package/dist/esm/utils/interval.js +171 -0
- package/dist/esm/utils/interval.js.map +1 -0
- package/dist/esm/utils/lowercase.js +7 -0
- package/dist/esm/utils/lowercase.js.map +1 -0
- package/dist/esm/utils/mutex.js +26 -0
- package/dist/esm/utils/mutex.js.map +1 -0
- package/dist/esm/utils/never.js +4 -0
- package/dist/esm/utils/never.js.map +1 -0
- package/dist/esm/utils/offset.js +101 -0
- package/dist/esm/utils/offset.js.map +1 -0
- package/dist/esm/utils/order.js +18 -0
- package/dist/esm/utils/order.js.map +1 -0
- package/dist/esm/utils/partition.js +46 -0
- package/dist/esm/utils/partition.js.map +1 -0
- package/dist/esm/utils/pg.js +175 -0
- package/dist/esm/utils/pg.js.map +1 -0
- package/dist/esm/utils/pglite.js +80 -0
- package/dist/esm/utils/pglite.js.map +1 -0
- package/dist/esm/utils/port.js +30 -0
- package/dist/esm/utils/port.js.map +1 -0
- package/dist/esm/utils/print.js +24 -0
- package/dist/esm/utils/print.js.map +1 -0
- package/dist/esm/utils/promiseAllSettledWithThrow.js +19 -0
- package/dist/esm/utils/promiseAllSettledWithThrow.js.map +1 -0
- package/dist/esm/utils/promiseWithResolvers.js +13 -0
- package/dist/esm/utils/promiseWithResolvers.js.map +1 -0
- package/dist/esm/utils/queue.js +150 -0
- package/dist/esm/utils/queue.js.map +1 -0
- package/dist/esm/utils/range.js +8 -0
- package/dist/esm/utils/range.js.map +1 -0
- package/dist/esm/utils/result.js +10 -0
- package/dist/esm/utils/result.js.map +1 -0
- package/dist/esm/utils/sql-parse.js +1326 -0
- package/dist/esm/utils/sql-parse.js.map +1 -0
- package/dist/esm/utils/timer.js +9 -0
- package/dist/esm/utils/timer.js.map +1 -0
- package/dist/esm/utils/truncate.js +15 -0
- package/dist/esm/utils/truncate.js.map +1 -0
- package/dist/esm/utils/wait.js +10 -0
- package/dist/esm/utils/wait.js.map +1 -0
- package/dist/esm/utils/zipper.js +67 -0
- package/dist/esm/utils/zipper.js.map +1 -0
- package/dist/types/bin/commands/codegen.d.ts +5 -0
- package/dist/types/bin/commands/codegen.d.ts.map +1 -0
- package/dist/types/bin/commands/createViews.d.ts +8 -0
- package/dist/types/bin/commands/createViews.d.ts.map +1 -0
- package/dist/types/bin/commands/dev.d.ts +5 -0
- package/dist/types/bin/commands/dev.d.ts.map +1 -0
- package/dist/types/bin/commands/list.d.ts +5 -0
- package/dist/types/bin/commands/list.d.ts.map +1 -0
- package/dist/types/bin/commands/prune.d.ts +5 -0
- package/dist/types/bin/commands/prune.d.ts.map +1 -0
- package/dist/types/bin/commands/serve.d.ts +5 -0
- package/dist/types/bin/commands/serve.d.ts.map +1 -0
- package/dist/types/bin/commands/start.d.ts +19 -0
- package/dist/types/bin/commands/start.d.ts.map +1 -0
- package/dist/types/bin/isolatedController.d.ts +13 -0
- package/dist/types/bin/isolatedController.d.ts.map +1 -0
- package/dist/types/bin/isolatedWorker.d.ts +9 -0
- package/dist/types/bin/isolatedWorker.d.ts.map +1 -0
- package/dist/types/bin/ponder.d.ts +37 -0
- package/dist/types/bin/ponder.d.ts.map +1 -0
- package/dist/types/bin/utils/codegen.d.ts +6 -0
- package/dist/types/bin/utils/codegen.d.ts.map +1 -0
- package/dist/types/bin/utils/exit.d.ts +10 -0
- package/dist/types/bin/utils/exit.d.ts.map +1 -0
- package/dist/types/build/config.d.ts +97 -0
- package/dist/types/build/config.d.ts.map +1 -0
- package/dist/types/build/factory.d.ts +9 -0
- package/dist/types/build/factory.d.ts.map +1 -0
- package/dist/types/build/index.d.ts +84 -0
- package/dist/types/build/index.d.ts.map +1 -0
- package/dist/types/build/plugin.d.ts +4 -0
- package/dist/types/build/plugin.d.ts.map +1 -0
- package/dist/types/build/pre.d.ts +29 -0
- package/dist/types/build/pre.d.ts.map +1 -0
- package/dist/types/build/schema.d.ts +20 -0
- package/dist/types/build/schema.d.ts.map +1 -0
- package/dist/types/build/stacktrace.d.ts +13 -0
- package/dist/types/build/stacktrace.d.ts.map +1 -0
- package/dist/types/client/index.d.ts +27 -0
- package/dist/types/client/index.d.ts.map +1 -0
- package/dist/types/config/address.d.ts +35 -0
- package/dist/types/config/address.d.ts.map +1 -0
- package/dist/types/config/eventFilter.d.ts +18 -0
- package/dist/types/config/eventFilter.d.ts.map +1 -0
- package/dist/types/config/index.d.ts +150 -0
- package/dist/types/config/index.d.ts.map +1 -0
- package/dist/types/config/utilityTypes.d.ts +43 -0
- package/dist/types/config/utilityTypes.d.ts.map +1 -0
- package/dist/types/database/actions.d.ts +99 -0
- package/dist/types/database/actions.d.ts.map +1 -0
- package/dist/types/database/index.d.ts +493 -0
- package/dist/types/database/index.d.ts.map +1 -0
- package/dist/types/database/queryBuilder.d.ts +65 -0
- package/dist/types/database/queryBuilder.d.ts.map +1 -0
- package/dist/types/drizzle/bigint.d.ts +25 -0
- package/dist/types/drizzle/bigint.d.ts.map +1 -0
- package/dist/types/drizzle/bytes.d.ts +31 -0
- package/dist/types/drizzle/bytes.d.ts.map +1 -0
- package/dist/types/drizzle/hex.d.ts +25 -0
- package/dist/types/drizzle/hex.d.ts.map +1 -0
- package/dist/types/drizzle/index.d.ts +6 -0
- package/dist/types/drizzle/index.d.ts.map +1 -0
- package/dist/types/drizzle/json.d.ts +51 -0
- package/dist/types/drizzle/json.d.ts.map +1 -0
- package/dist/types/drizzle/kit/index.d.ts +187 -0
- package/dist/types/drizzle/kit/index.d.ts.map +1 -0
- package/dist/types/drizzle/onchain.d.ts +298 -0
- package/dist/types/drizzle/onchain.d.ts.map +1 -0
- package/dist/types/drizzle/text.d.ts +29 -0
- package/dist/types/drizzle/text.d.ts.map +1 -0
- package/dist/types/graphql/graphiql.html.d.ts +2 -0
- package/dist/types/graphql/graphiql.html.d.ts.map +1 -0
- package/dist/types/graphql/index.d.ts +12 -0
- package/dist/types/graphql/index.d.ts.map +1 -0
- package/dist/types/graphql/json.d.ts +3 -0
- package/dist/types/graphql/json.d.ts.map +1 -0
- package/dist/types/graphql/middleware.d.ts +29 -0
- package/dist/types/graphql/middleware.d.ts.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/indexing/addStackTrace.d.ts +3 -0
- package/dist/types/indexing/addStackTrace.d.ts.map +1 -0
- package/dist/types/indexing/client.d.ts +154 -0
- package/dist/types/indexing/client.d.ts.map +1 -0
- package/dist/types/indexing/index.d.ts +72 -0
- package/dist/types/indexing/index.d.ts.map +1 -0
- package/dist/types/indexing/profile.d.ts +16 -0
- package/dist/types/indexing/profile.d.ts.map +1 -0
- package/dist/types/indexing-store/cache.d.ts +115 -0
- package/dist/types/indexing-store/cache.d.ts.map +1 -0
- package/dist/types/indexing-store/index.d.ts +24 -0
- package/dist/types/indexing-store/index.d.ts.map +1 -0
- package/dist/types/indexing-store/profile.d.ts +7 -0
- package/dist/types/indexing-store/profile.d.ts.map +1 -0
- package/dist/types/indexing-store/utils.d.ts +19 -0
- package/dist/types/indexing-store/utils.d.ts.map +1 -0
- package/dist/types/internal/common.d.ts +15 -0
- package/dist/types/internal/common.d.ts.map +1 -0
- package/dist/types/internal/errors.d.ts +101 -0
- package/dist/types/internal/errors.d.ts.map +1 -0
- package/dist/types/internal/logger.d.ts +37 -0
- package/dist/types/internal/logger.d.ts.map +1 -0
- package/dist/types/internal/metrics.d.ts +120 -0
- package/dist/types/internal/metrics.d.ts.map +1 -0
- package/dist/types/internal/options.d.ts +62 -0
- package/dist/types/internal/options.d.ts.map +1 -0
- package/dist/types/internal/shutdown.d.ts +8 -0
- package/dist/types/internal/shutdown.d.ts.map +1 -0
- package/dist/types/internal/telemetry.d.ts +43 -0
- package/dist/types/internal/telemetry.d.ts.map +1 -0
- package/dist/types/internal/types.d.ts +435 -0
- package/dist/types/internal/types.d.ts.map +1 -0
- package/dist/types/rpc/actions.d.ts +360 -0
- package/dist/types/rpc/actions.d.ts.map +1 -0
- package/dist/types/rpc/http.d.ts +17 -0
- package/dist/types/rpc/http.d.ts.map +1 -0
- package/dist/types/rpc/index.d.ts +43 -0
- package/dist/types/rpc/index.d.ts.map +1 -0
- package/dist/types/runtime/events.d.ts +40 -0
- package/dist/types/runtime/events.d.ts.map +1 -0
- package/dist/types/runtime/filter.d.ts +87 -0
- package/dist/types/runtime/filter.d.ts.map +1 -0
- package/dist/types/runtime/fragments.d.ts +30 -0
- package/dist/types/runtime/fragments.d.ts.map +1 -0
- package/dist/types/runtime/historical.d.ts +123 -0
- package/dist/types/runtime/historical.d.ts.map +1 -0
- package/dist/types/runtime/index.d.ts +89 -0
- package/dist/types/runtime/index.d.ts.map +1 -0
- package/dist/types/runtime/isolated.d.ts +14 -0
- package/dist/types/runtime/isolated.d.ts.map +1 -0
- package/dist/types/runtime/multichain.d.ts +13 -0
- package/dist/types/runtime/multichain.d.ts.map +1 -0
- package/dist/types/runtime/omnichain.d.ts +23 -0
- package/dist/types/runtime/omnichain.d.ts.map +1 -0
- package/dist/types/runtime/realtime.d.ts +93 -0
- package/dist/types/runtime/realtime.d.ts.map +1 -0
- package/dist/types/server/error.d.ts +5 -0
- package/dist/types/server/error.d.ts.map +1 -0
- package/dist/types/server/index.d.ts +13 -0
- package/dist/types/server/index.d.ts.map +1 -0
- package/dist/types/sync-historical/index.d.ts +36 -0
- package/dist/types/sync-historical/index.d.ts.map +1 -0
- package/dist/types/sync-historical/portal-transform.d.ts +50 -0
- package/dist/types/sync-historical/portal-transform.d.ts.map +1 -0
- package/dist/types/sync-historical/portal.d.ts +31 -0
- package/dist/types/sync-historical/portal.d.ts.map +1 -0
- package/dist/types/sync-realtime/bloom.d.ts +18 -0
- package/dist/types/sync-realtime/bloom.d.ts.map +1 -0
- package/dist/types/sync-realtime/index.d.ts +47 -0
- package/dist/types/sync-realtime/index.d.ts.map +1 -0
- package/dist/types/sync-store/encode.d.ts +25 -0
- package/dist/types/sync-store/encode.d.ts.map +1 -0
- package/dist/types/sync-store/index.d.ts +135 -0
- package/dist/types/sync-store/index.d.ts.map +1 -0
- package/dist/types/sync-store/migrations.d.ts +8 -0
- package/dist/types/sync-store/migrations.d.ts.map +1 -0
- package/dist/types/sync-store/schema.d.ts +1828 -0
- package/dist/types/sync-store/schema.d.ts.map +1 -0
- package/dist/types/types/db.d.ts +213 -0
- package/dist/types/types/db.d.ts.map +1 -0
- package/dist/types/types/eth.d.ts +196 -0
- package/dist/types/types/eth.d.ts.map +1 -0
- package/dist/types/types/utils.d.ts +38 -0
- package/dist/types/types/utils.d.ts.map +1 -0
- package/dist/types/types/virtual.d.ts +99 -0
- package/dist/types/types/virtual.d.ts.map +1 -0
- package/dist/types/ui/app.d.ts +22 -0
- package/dist/types/ui/app.d.ts.map +1 -0
- package/dist/types/ui/index.d.ts +5 -0
- package/dist/types/ui/index.d.ts.map +1 -0
- package/dist/types/ui/patch.d.ts +7 -0
- package/dist/types/ui/patch.d.ts.map +1 -0
- package/dist/types/utils/abi.d.ts +23 -0
- package/dist/types/utils/abi.d.ts.map +1 -0
- package/dist/types/utils/bigint.d.ts +15 -0
- package/dist/types/utils/bigint.d.ts.map +1 -0
- package/dist/types/utils/chains.d.ts +42 -0
- package/dist/types/utils/chains.d.ts.map +1 -0
- package/dist/types/utils/checkpoint.d.ts +52 -0
- package/dist/types/utils/checkpoint.d.ts.map +1 -0
- package/dist/types/utils/chunk.d.ts +2 -0
- package/dist/types/utils/chunk.d.ts.map +1 -0
- package/dist/types/utils/copy.d.ts +16 -0
- package/dist/types/utils/copy.d.ts.map +1 -0
- package/dist/types/utils/date.d.ts +7 -0
- package/dist/types/utils/date.d.ts.map +1 -0
- package/dist/types/utils/debug.d.ts +105 -0
- package/dist/types/utils/debug.d.ts.map +1 -0
- package/dist/types/utils/decodeAbiParameters.d.ts +28 -0
- package/dist/types/utils/decodeAbiParameters.d.ts.map +1 -0
- package/dist/types/utils/decodeEventLog.d.ts +12 -0
- package/dist/types/utils/decodeEventLog.d.ts.map +1 -0
- package/dist/types/utils/dedupe.d.ts +20 -0
- package/dist/types/utils/dedupe.d.ts.map +1 -0
- package/dist/types/utils/duplicates.d.ts +7 -0
- package/dist/types/utils/duplicates.d.ts.map +1 -0
- package/dist/types/utils/estimate.d.ts +11 -0
- package/dist/types/utils/estimate.d.ts.map +1 -0
- package/dist/types/utils/finality.d.ts +12 -0
- package/dist/types/utils/finality.d.ts.map +1 -0
- package/dist/types/utils/format.d.ts +3 -0
- package/dist/types/utils/format.d.ts.map +1 -0
- package/dist/types/utils/generators.d.ts +42 -0
- package/dist/types/utils/generators.d.ts.map +1 -0
- package/dist/types/utils/hash.d.ts +11 -0
- package/dist/types/utils/hash.d.ts.map +1 -0
- package/dist/types/utils/interval.d.ts +53 -0
- package/dist/types/utils/interval.d.ts.map +1 -0
- package/dist/types/utils/lowercase.d.ts +5 -0
- package/dist/types/utils/lowercase.d.ts.map +1 -0
- package/dist/types/utils/mutex.d.ts +5 -0
- package/dist/types/utils/mutex.d.ts.map +1 -0
- package/dist/types/utils/never.d.ts +2 -0
- package/dist/types/utils/never.d.ts.map +1 -0
- package/dist/types/utils/offset.d.ts +8 -0
- package/dist/types/utils/offset.d.ts.map +1 -0
- package/dist/types/utils/order.d.ts +2 -0
- package/dist/types/utils/order.d.ts.map +1 -0
- package/dist/types/utils/partition.d.ts +22 -0
- package/dist/types/utils/partition.d.ts.map +1 -0
- package/dist/types/utils/pg.d.ts +8 -0
- package/dist/types/utils/pg.d.ts.map +1 -0
- package/dist/types/utils/pglite.d.ts +25 -0
- package/dist/types/utils/pglite.d.ts.map +1 -0
- package/dist/types/utils/port.d.ts +5 -0
- package/dist/types/utils/port.d.ts.map +1 -0
- package/dist/types/utils/print.d.ts +4 -0
- package/dist/types/utils/print.d.ts.map +1 -0
- package/dist/types/utils/promiseAllSettledWithThrow.d.ts +8 -0
- package/dist/types/utils/promiseAllSettledWithThrow.d.ts.map +1 -0
- package/dist/types/utils/promiseWithResolvers.d.ts +10 -0
- package/dist/types/utils/promiseWithResolvers.d.ts.map +1 -0
- package/dist/types/utils/queue.d.ts +33 -0
- package/dist/types/utils/queue.d.ts.map +1 -0
- package/dist/types/utils/range.d.ts +8 -0
- package/dist/types/utils/range.d.ts.map +1 -0
- package/dist/types/utils/result.d.ts +17 -0
- package/dist/types/utils/result.d.ts.map +1 -0
- package/dist/types/utils/sql-parse.d.ts +21 -0
- package/dist/types/utils/sql-parse.d.ts.map +1 -0
- package/dist/types/utils/timer.d.ts +6 -0
- package/dist/types/utils/timer.d.ts.map +1 -0
- package/dist/types/utils/truncate.d.ts +9 -0
- package/dist/types/utils/truncate.d.ts.map +1 -0
- package/dist/types/utils/wait.d.ts +6 -0
- package/dist/types/utils/wait.d.ts.map +1 -0
- package/dist/types/utils/zipper.d.ts +36 -0
- package/dist/types/utils/zipper.d.ts.map +1 -0
- package/package.json +117 -0
- package/src/bin/commands/codegen.ts +56 -0
- package/src/bin/commands/createViews.ts +318 -0
- package/src/bin/commands/dev.ts +490 -0
- package/src/bin/commands/list.ts +208 -0
- package/src/bin/commands/prune.ts +322 -0
- package/src/bin/commands/serve.ts +236 -0
- package/src/bin/commands/start.ts +319 -0
- package/src/bin/isolatedController.ts +300 -0
- package/src/bin/isolatedWorker.ts +192 -0
- package/src/bin/ponder.ts +208 -0
- package/src/bin/utils/codegen.ts +32 -0
- package/src/bin/utils/exit.ts +112 -0
- package/src/build/config.ts +1142 -0
- package/src/build/factory.ts +125 -0
- package/src/build/index.ts +790 -0
- package/src/build/plugin.ts +58 -0
- package/src/build/pre.ts +114 -0
- package/src/build/schema.ts +358 -0
- package/src/build/stacktrace.ts +137 -0
- package/src/client/index.ts +551 -0
- package/src/config/address.ts +46 -0
- package/src/config/eventFilter.ts +33 -0
- package/src/config/index.ts +246 -0
- package/src/config/utilityTypes.ts +152 -0
- package/src/database/actions.ts +873 -0
- package/src/database/index.ts +1029 -0
- package/src/database/queryBuilder.ts +537 -0
- package/src/drizzle/bigint.ts +57 -0
- package/src/drizzle/bytes.ts +68 -0
- package/src/drizzle/hex.ts +58 -0
- package/src/drizzle/index.ts +40 -0
- package/src/drizzle/json.ts +159 -0
- package/src/drizzle/kit/index.ts +1348 -0
- package/src/drizzle/onchain.ts +476 -0
- package/src/drizzle/text.ts +77 -0
- package/src/graphql/graphiql.html.ts +59 -0
- package/src/graphql/index.ts +1390 -0
- package/src/graphql/json.ts +62 -0
- package/src/graphql/middleware.ts +115 -0
- package/src/index.ts +139 -0
- package/src/indexing/addStackTrace.ts +69 -0
- package/src/indexing/client.ts +1184 -0
- package/src/indexing/index.ts +976 -0
- package/src/indexing/profile.ts +771 -0
- package/src/indexing-store/cache.ts +1057 -0
- package/src/indexing-store/index.ts +630 -0
- package/src/indexing-store/profile.ts +557 -0
- package/src/indexing-store/utils.ts +164 -0
- package/src/internal/common.ts +15 -0
- package/src/internal/errors.ts +228 -0
- package/src/internal/logger.ts +252 -0
- package/src/internal/metrics.ts +1030 -0
- package/src/internal/options.ts +130 -0
- package/src/internal/shutdown.ts +32 -0
- package/src/internal/telemetry.ts +303 -0
- package/src/internal/types.ts +598 -0
- package/src/rpc/actions.ts +1343 -0
- package/src/rpc/http.ts +164 -0
- package/src/rpc/index.ts +959 -0
- package/src/runtime/events.ts +875 -0
- package/src/runtime/filter.ts +664 -0
- package/src/runtime/fragments.ts +674 -0
- package/src/runtime/historical.ts +1512 -0
- package/src/runtime/index.ts +569 -0
- package/src/runtime/isolated.ts +778 -0
- package/src/runtime/multichain.ts +860 -0
- package/src/runtime/omnichain.ts +920 -0
- package/src/runtime/realtime.ts +1166 -0
- package/src/server/error.ts +68 -0
- package/src/server/index.ts +173 -0
- package/src/sync-historical/index.ts +1072 -0
- package/src/sync-historical/portal-transform.ts +114 -0
- package/src/sync-historical/portal.ts +539 -0
- package/src/sync-realtime/bloom.ts +102 -0
- package/src/sync-realtime/index.ts +1298 -0
- package/src/sync-store/encode.ts +153 -0
- package/src/sync-store/index.ts +1633 -0
- package/src/sync-store/migrations.ts +1801 -0
- package/src/sync-store/schema.ts +248 -0
- package/src/types/db.ts +292 -0
- package/src/types/eth.ts +216 -0
- package/src/types/utils.ts +47 -0
- package/src/types/virtual.ts +244 -0
- package/src/types.d.ts +38 -0
- package/src/ui/app.ts +207 -0
- package/src/ui/index.ts +37 -0
- package/src/ui/patch.ts +204 -0
- package/src/utils/abi.ts +103 -0
- package/src/utils/bigint.ts +41 -0
- package/src/utils/chains.ts +22 -0
- package/src/utils/checkpoint.ts +203 -0
- package/src/utils/chunk.ts +7 -0
- package/src/utils/copy.ts +151 -0
- package/src/utils/date.ts +26 -0
- package/src/utils/debug.ts +110 -0
- package/src/utils/decodeAbiParameters.ts +428 -0
- package/src/utils/decodeEventLog.ts +100 -0
- package/src/utils/dedupe.ts +32 -0
- package/src/utils/duplicates.ts +19 -0
- package/src/utils/estimate.ts +27 -0
- package/src/utils/finality.ts +40 -0
- package/src/utils/format.ts +22 -0
- package/src/utils/generators.ts +157 -0
- package/src/utils/hash.ts +22 -0
- package/src/utils/interval.ts +212 -0
- package/src/utils/lowercase.ts +6 -0
- package/src/utils/mutex.ts +33 -0
- package/src/utils/never.ts +3 -0
- package/src/utils/offset.ts +133 -0
- package/src/utils/order.ts +16 -0
- package/src/utils/partition.ts +53 -0
- package/src/utils/pg.ts +230 -0
- package/src/utils/pglite.ts +97 -0
- package/src/utils/port.ts +34 -0
- package/src/utils/print.ts +34 -0
- package/src/utils/promiseAllSettledWithThrow.ts +27 -0
- package/src/utils/promiseWithResolvers.ts +20 -0
- package/src/utils/queue.ts +258 -0
- package/src/utils/range.ts +8 -0
- package/src/utils/result.ts +26 -0
- package/src/utils/sql-parse.ts +1477 -0
- package/src/utils/timer.ts +8 -0
- package/src/utils/truncate.ts +15 -0
- package/src/utils/wait.ts +8 -0
- package/src/utils/zipper.ts +80 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { getChildAddress, isAddressFactory, isAddressMatched, isBlockFilterMatched, isLogFactoryMatched, isTraceFilterMatched, isTransactionFilterMatched, isTransferFilterMatched, } from '../runtime/filter.js';
|
|
3
|
+
import {} from "viem";
|
|
4
|
+
import { createHistoricalSync } from "./index.js";
|
|
5
|
+
import { hx, isFinalityGap, toSyncLog, toSyncBlockHeader, toSyncTransaction, toSyncReceipt, parityToCallFrame, cmpTraceAddr, traceSafeChunkBlocks } from "./portal-transform.js";
|
|
6
|
+
const PORTAL_MAX_ADDRESSES = 1000;
|
|
7
|
+
const CHUNK_BLOCKS = Number(process.env.PORTAL_CHUNK_BLOCKS ?? 500000);
|
|
8
|
+
const READAHEAD = Number(process.env.PORTAL_READAHEAD ?? 6);
|
|
9
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
10
|
+
const asArr = (t) => {
|
|
11
|
+
if (t === null || t === undefined)
|
|
12
|
+
return undefined;
|
|
13
|
+
return (Array.isArray(t) ? t : [t]).map((x) => x.toLowerCase());
|
|
14
|
+
};
|
|
15
|
+
export const createPortalHistoricalSync = (args) => {
|
|
16
|
+
const portalUrl = args.chain.portal.replace(/\/$/, "");
|
|
17
|
+
const log = args.common.logger;
|
|
18
|
+
const baseHeaders = { "content-type": "application/json", "accept-encoding": "gzip" };
|
|
19
|
+
if (process.env.PORTAL_API_KEY)
|
|
20
|
+
baseHeaders["x-api-key"] = process.env.PORTAL_API_KEY;
|
|
21
|
+
const stats = { dataChunks: 0, discChunks: 0, http: 0, logs: 0, errors: 0, retries: 0, bytes: 0, cacheHits: 0, inflight: 0, maxInflight: 0, blocks: 0, txs: 0, receipts: 0, traces: 0, rpcFallback: 0 };
|
|
22
|
+
const dataCache = new Map(); // keyed by chunk index
|
|
23
|
+
const discCache = new Map(); // keyed by chunk index
|
|
24
|
+
const stash = new Map();
|
|
25
|
+
const ikey = (i) => `${i[0]}-${i[1]}`;
|
|
26
|
+
let chunkBlocks = CHUNK_BLOCKS;
|
|
27
|
+
let chunkSizeP;
|
|
28
|
+
const idxOf = (n) => Math.floor(n / chunkBlocks);
|
|
29
|
+
let discStartIdx; // factory deploy chunk — discovery floor (fixes from-0 scan)
|
|
30
|
+
// finality-gap fallback: Portal serves only finalized data, and its finalized head can
|
|
31
|
+
// (rarely) lag Ponder's target. Any interval reaching past Portal's head is delegated
|
|
32
|
+
// whole to the stock RPC historical sync. PORTAL_FINALIZED_HEAD overrides for tests/ops.
|
|
33
|
+
let portalHead = process.env.PORTAL_FINALIZED_HEAD ? Number(process.env.PORTAL_FINALIZED_HEAD) : undefined;
|
|
34
|
+
let rpcFallbackInstance;
|
|
35
|
+
const rpcFallback = () => (rpcFallbackInstance ??= createHistoricalSync(args));
|
|
36
|
+
const delegated = new Set(); // interval keys routed to RPC
|
|
37
|
+
const refreshPortalHead = async () => {
|
|
38
|
+
if (process.env.PORTAL_FINALIZED_HEAD)
|
|
39
|
+
return (portalHead = Number(process.env.PORTAL_FINALIZED_HEAD));
|
|
40
|
+
try {
|
|
41
|
+
const h = await fetch(`${portalUrl}/finalized-head`, { headers: baseHeaders }).then((r) => r.json());
|
|
42
|
+
if (typeof h?.number === "number")
|
|
43
|
+
portalHead = h.number;
|
|
44
|
+
}
|
|
45
|
+
catch { /* keep prior */ }
|
|
46
|
+
return portalHead ?? Number.POSITIVE_INFINITY;
|
|
47
|
+
};
|
|
48
|
+
// instrumentation: per-chain backfill metrics → PORTAL_METRICS_FILE.<chainId> (for the bench harness)
|
|
49
|
+
const METRICS_FILE = process.env.PORTAL_METRICS_FILE;
|
|
50
|
+
let startTime = 0;
|
|
51
|
+
const writeMetrics = () => {
|
|
52
|
+
if (!METRICS_FILE)
|
|
53
|
+
return;
|
|
54
|
+
try {
|
|
55
|
+
writeFileSync(`${METRICS_FILE}.${args.chain.id}`, JSON.stringify({
|
|
56
|
+
chain: args.chain.name, chainId: args.chain.id, wallMs: startTime ? Date.now() - startTime : 0,
|
|
57
|
+
chunkBlocks, portalFinalizedHead: portalHead ?? null,
|
|
58
|
+
fetch: { dataChunks: stats.dataChunks, discChunks: stats.discChunks, http: stats.http, bytes: stats.bytes, errors: stats.errors, retries: stats.retries, cacheHits: stats.cacheHits, maxInflight: stats.maxInflight },
|
|
59
|
+
inserted: { logs: stats.logs, blocks: stats.blocks, txs: stats.txs, receipts: stats.receipts, traces: stats.traces },
|
|
60
|
+
rpcFallbackIntervals: stats.rpcFallback,
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
catch { /* best-effort */ }
|
|
64
|
+
};
|
|
65
|
+
// Scale chunk size by the chain's block density. High-block-rate chains (Arbitrum
|
|
66
|
+
// ~478M blocks ≈ 19× Ethereum) otherwise need 19× more 500k-block chunks = 19× more
|
|
67
|
+
// latency-bound round-trips. CU is charged per Portal data-chunk (data-density based),
|
|
68
|
+
// so larger BLOCK-chunks don't cost more CU — they just cut round-trips. PORTAL_CHUNK_FIXED=1 disables.
|
|
69
|
+
const ensureChunkSize = () => (chunkSizeP ??= (async () => {
|
|
70
|
+
if (process.env.PORTAL_CHUNK_FIXED)
|
|
71
|
+
return;
|
|
72
|
+
try {
|
|
73
|
+
const h = await fetch(`${portalUrl}/finalized-head`, { headers: baseHeaders }).then((r) => r.json());
|
|
74
|
+
const density = Math.max(1, Math.round(h.number / 25000000));
|
|
75
|
+
chunkBlocks = Math.min(CHUNK_BLOCKS * density, 25000000);
|
|
76
|
+
log.debug({ service: "portal", msg: `Portal ${args.chain.name}: head=${h.number} → chunkBlocks=${chunkBlocks} (${density}× density)` });
|
|
77
|
+
}
|
|
78
|
+
catch { /* keep default */ }
|
|
79
|
+
})());
|
|
80
|
+
// transient = retry: HTTP 503/529/429 AND network/socket errors (parallel load
|
|
81
|
+
// makes "other side closed" / ECONNRESET / fetch failed routine).
|
|
82
|
+
const isNetworkError = (err) => {
|
|
83
|
+
const m = `${err?.message ?? ""} ${err?.cause?.message ?? ""} ${err?.cause?.code ?? ""}`.toLowerCase();
|
|
84
|
+
return /socket|closed|econnreset|fetch failed|terminated|timeout|network|epipe|und_err/.test(m) || err?.name === "AbortError";
|
|
85
|
+
};
|
|
86
|
+
// one POST+drain; returns blocks or "done" (204); throws (with .retryAfterMs on 503-class).
|
|
87
|
+
async function fetchBatch(body, cursor) {
|
|
88
|
+
stats.inflight++;
|
|
89
|
+
stats.maxInflight = Math.max(stats.maxInflight, stats.inflight);
|
|
90
|
+
try {
|
|
91
|
+
const res = await fetch(`${portalUrl}/finalized-stream`, { method: "POST", headers: baseHeaders, body });
|
|
92
|
+
stats.http++;
|
|
93
|
+
if (res.status === 204)
|
|
94
|
+
return "done";
|
|
95
|
+
if (res.status === 503 || res.status === 529 || res.status === 429) {
|
|
96
|
+
await res.body?.cancel().catch(() => { });
|
|
97
|
+
const ra = Number(res.headers.get("retry-after"));
|
|
98
|
+
const e = new Error(`Portal ${res.status}`);
|
|
99
|
+
e.retryAfterMs = Number.isFinite(ra) ? ra * 1000 : undefined;
|
|
100
|
+
throw e;
|
|
101
|
+
}
|
|
102
|
+
if (!res.ok)
|
|
103
|
+
throw new Error(`Portal ${res.status} @ ${cursor}: ${(await res.text()).slice(0, 200)}`);
|
|
104
|
+
const reader = res.body.getReader();
|
|
105
|
+
const dec = new TextDecoder();
|
|
106
|
+
let buf = "", last = cursor;
|
|
107
|
+
const blocks = [];
|
|
108
|
+
const onLine = (line) => { if (!line)
|
|
109
|
+
return; const b = JSON.parse(line); blocks.push(b); if (b.header?.number > last)
|
|
110
|
+
last = b.header.number; };
|
|
111
|
+
for (;;) {
|
|
112
|
+
const { done, value } = await reader.read();
|
|
113
|
+
if (done)
|
|
114
|
+
break;
|
|
115
|
+
stats.bytes += value.byteLength;
|
|
116
|
+
buf += dec.decode(value, { stream: true });
|
|
117
|
+
let nl;
|
|
118
|
+
while ((nl = buf.indexOf("\n")) >= 0) {
|
|
119
|
+
onLine(buf.slice(0, nl));
|
|
120
|
+
buf = buf.slice(nl + 1);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
buf += dec.decode();
|
|
124
|
+
if (buf)
|
|
125
|
+
onLine(buf);
|
|
126
|
+
return { blocks, last };
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
stats.inflight--;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async function* stream(query, from, to) {
|
|
133
|
+
let cursor = from;
|
|
134
|
+
while (cursor <= to) {
|
|
135
|
+
const body = JSON.stringify({ ...query, fromBlock: cursor, toBlock: to });
|
|
136
|
+
let attempt = 0;
|
|
137
|
+
let batch;
|
|
138
|
+
while (batch === undefined) {
|
|
139
|
+
try {
|
|
140
|
+
batch = await fetchBatch(body, cursor);
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
const retryable = err?.retryAfterMs !== undefined || isNetworkError(err);
|
|
144
|
+
if (!retryable || attempt++ >= 10)
|
|
145
|
+
throw err;
|
|
146
|
+
stats.errors++;
|
|
147
|
+
stats.retries++;
|
|
148
|
+
await sleep(err?.retryAfterMs !== undefined ? Math.min(err.retryAfterMs, 30000) : Math.min(500 * 2 ** attempt, 30000));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (batch === "done")
|
|
152
|
+
return;
|
|
153
|
+
yield batch.blocks;
|
|
154
|
+
if (batch.last < cursor)
|
|
155
|
+
throw new Error(`Portal no progress @ ${cursor}`);
|
|
156
|
+
cursor = batch.last + 1;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function logRequestsFor(filter) {
|
|
160
|
+
const base = {};
|
|
161
|
+
if (filter.topic0)
|
|
162
|
+
base.topic0 = asArr(filter.topic0);
|
|
163
|
+
if (filter.topic1)
|
|
164
|
+
base.topic1 = asArr(filter.topic1);
|
|
165
|
+
if (filter.topic2)
|
|
166
|
+
base.topic2 = asArr(filter.topic2);
|
|
167
|
+
if (filter.topic3)
|
|
168
|
+
base.topic3 = asArr(filter.topic3);
|
|
169
|
+
let addresses;
|
|
170
|
+
if (isAddressFactory(filter.address)) {
|
|
171
|
+
addresses = Array.from(args.childAddresses.get(filter.address.id)?.keys() ?? []);
|
|
172
|
+
if (addresses.length === 0)
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
else if (filter.address === undefined)
|
|
176
|
+
return [base];
|
|
177
|
+
else
|
|
178
|
+
addresses = (Array.isArray(filter.address) ? filter.address : [filter.address]).map((a) => a.toLowerCase());
|
|
179
|
+
const out = [];
|
|
180
|
+
for (let i = 0; i < addresses.length; i += PORTAL_MAX_ADDRESSES)
|
|
181
|
+
out.push({ ...base, address: addresses.slice(i, i + PORTAL_MAX_ADDRESSES) });
|
|
182
|
+
return out;
|
|
183
|
+
}
|
|
184
|
+
// FILTER/PROJECTION STRATEGY (max Portal leverage): every row filter is pushed to
|
|
185
|
+
// Portal's native server-side filters — logs by address+topics (logRequestsFor),
|
|
186
|
+
// traces by callTo/callFrom/callSighash (tracePortalRequests), account txs by from/to
|
|
187
|
+
// (txPortalRequests). Field projection below requests exactly the columns the sync
|
|
188
|
+
// store persists and no more. The only client-side row filter is block-interval
|
|
189
|
+
// (Portal has no modulo filter), and receipt fields are added only on demand.
|
|
190
|
+
const REQUIRED_BLOCK_FIELDS = ["number", "hash", "parentHash", "timestamp", "logsBloom", "miner", "gasUsed", "gasLimit", "stateRoot", "receiptsRoot", "transactionsRoot", "size", "difficulty", "extraData"];
|
|
191
|
+
const NULLABLE_BLOCK_FIELDS = ["baseFeePerGas", "nonce", "mixHash", "sha3Uncles", "totalDifficulty"];
|
|
192
|
+
const LOG_FIELDS = { address: true, topics: true, data: true, transactionHash: true, transactionIndex: true, logIndex: true };
|
|
193
|
+
// Ponder's event profiler probes event.transaction.hash, so we pull each matched
|
|
194
|
+
// log's parent transaction (Portal `transaction` relation) and store it.
|
|
195
|
+
const TX_FIELDS = { transactionIndex: true, hash: true, from: true, to: true, input: true, value: true, nonce: true, gas: true, gasPrice: true, maxFeePerGas: true, maxPriorityFeePerGas: true, type: true, r: true, s: true, v: true, yParity: true };
|
|
196
|
+
// receipt fields ride on Portal's transaction object (no separate receipt entity)
|
|
197
|
+
const RECEIPT_FIELDS = { status: true, cumulativeGasUsed: true, effectiveGasPrice: true, gasUsed: true, contractAddress: true, logsBloom: true };
|
|
198
|
+
let needReceipts = false; // set from filters on first syncBlockRangeData (stable per chain)
|
|
199
|
+
// trace fields: request both flattened selectors (some Portal builds) AND rely on
|
|
200
|
+
// nested action/result in the response — the transform reads whichever is present.
|
|
201
|
+
const TRACE_FIELDS = {
|
|
202
|
+
transactionIndex: true, traceAddress: true, type: true, subtraces: true, error: true, revertReason: true,
|
|
203
|
+
callFrom: true, callTo: true, callValue: true, callGas: true, callInput: true, callSighash: true, callCallType: true, callResultGasUsed: true, callResultOutput: true,
|
|
204
|
+
createFrom: true, createValue: true, createGas: true, createInit: true, createResultGasUsed: true, createResultCode: true, createResultAddress: true,
|
|
205
|
+
suicideAddress: true, suicideRefundAddress: true, suicideBalance: true,
|
|
206
|
+
};
|
|
207
|
+
let needTraces = false;
|
|
208
|
+
let traceFilters = [];
|
|
209
|
+
let transferFilters = [];
|
|
210
|
+
let needBlocks = false;
|
|
211
|
+
let blockFilters = [];
|
|
212
|
+
let needTxFilter = false;
|
|
213
|
+
let transactionFilters = [];
|
|
214
|
+
const blockFieldsFor = (filters) => {
|
|
215
|
+
const inc = new Set();
|
|
216
|
+
for (const f of filters)
|
|
217
|
+
for (const i of f.include ?? [])
|
|
218
|
+
if (i.startsWith("block."))
|
|
219
|
+
inc.add(i.slice(6));
|
|
220
|
+
const fields = {};
|
|
221
|
+
for (const k of REQUIRED_BLOCK_FIELDS)
|
|
222
|
+
fields[k] = true;
|
|
223
|
+
for (const k of NULLABLE_BLOCK_FIELDS)
|
|
224
|
+
if (inc.has(k))
|
|
225
|
+
fields[k] = true;
|
|
226
|
+
return fields;
|
|
227
|
+
};
|
|
228
|
+
// ---- discovery: one sparse stream per chunk, accumulating children (memoized) ----
|
|
229
|
+
function discoverChunk(idx, factories) {
|
|
230
|
+
let p = discCache.get(idx);
|
|
231
|
+
if (p)
|
|
232
|
+
return p;
|
|
233
|
+
p = (async () => {
|
|
234
|
+
stats.discChunks++;
|
|
235
|
+
const from = idx * chunkBlocks, to = from + chunkBlocks - 1;
|
|
236
|
+
for (const factory of factories) {
|
|
237
|
+
const needsData = factory.childAddressLocation.startsWith("offset");
|
|
238
|
+
const q = { type: "evm", fields: { block: { number: true }, log: { address: true, topics: true, data: needsData } }, logs: [{ address: factory.address ? (Array.isArray(factory.address) ? factory.address : [factory.address]).map((a) => a.toLowerCase()) : undefined, topic0: [factory.eventSelector.toLowerCase()] }] };
|
|
239
|
+
const rec = args.childAddresses.get(factory.id);
|
|
240
|
+
for await (const blocks of stream(q, from, to)) {
|
|
241
|
+
for (const b of blocks)
|
|
242
|
+
for (const raw of b.logs ?? []) {
|
|
243
|
+
const sl = { address: raw.address?.toLowerCase(), topics: raw.topics ?? [], data: raw.data ?? "0x", blockNumber: hx(b.header.number) };
|
|
244
|
+
if (isLogFactoryMatched({ factory, log: sl })) {
|
|
245
|
+
const child = getChildAddress({ log: sl, factory }).toLowerCase();
|
|
246
|
+
const bn = b.header.number;
|
|
247
|
+
const prev = rec.get(child);
|
|
248
|
+
if (prev === undefined || prev > bn)
|
|
249
|
+
rec.set(child, bn);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
})();
|
|
255
|
+
discCache.set(idx, p);
|
|
256
|
+
return p;
|
|
257
|
+
}
|
|
258
|
+
// discovery complete THROUGH chunk idx (children of all chunks ≤ idx are known)
|
|
259
|
+
function ensureDiscoveredThrough(idx, factories) {
|
|
260
|
+
if (factories.length === 0 || discStartIdx === undefined)
|
|
261
|
+
return Promise.resolve();
|
|
262
|
+
const ps = [];
|
|
263
|
+
for (let i = discStartIdx; i <= idx; i++)
|
|
264
|
+
ps.push(discoverChunk(i, factories));
|
|
265
|
+
return Promise.all(ps);
|
|
266
|
+
}
|
|
267
|
+
// ---- data chunk: gated on discovery-through-this-chunk, then ONE big data stream ----
|
|
268
|
+
function dataChunk(idx, factories, filters) {
|
|
269
|
+
let p = dataCache.get(idx);
|
|
270
|
+
if (p) {
|
|
271
|
+
stats.cacheHits++;
|
|
272
|
+
return p;
|
|
273
|
+
}
|
|
274
|
+
p = (async () => {
|
|
275
|
+
await ensureDiscoveredThrough(idx, factories); // correctness: children ≤ this chunk are known
|
|
276
|
+
stats.dataChunks++;
|
|
277
|
+
const from = idx * chunkBlocks, to = from + chunkBlocks - 1;
|
|
278
|
+
const logRequests = filters.flatMap((f) => logRequestsFor(f)).map((r) => ({ ...r, transaction: true }));
|
|
279
|
+
const data = { headers: new Map(), logs: new Map(), txs: new Map(), traceBlocks: new Map(), blockHeaders: new Map(), txBlocks: new Map() };
|
|
280
|
+
if (logRequests.length > 0) {
|
|
281
|
+
const q = { type: "evm", fields: { block: blockFieldsFor(filters), log: LOG_FIELDS, transaction: needReceipts ? { ...TX_FIELDS, ...RECEIPT_FIELDS } : TX_FIELDS }, logs: logRequests };
|
|
282
|
+
for await (const blocks of stream(q, from, to)) {
|
|
283
|
+
for (const b of blocks)
|
|
284
|
+
if (b.logs?.length) {
|
|
285
|
+
data.headers.set(b.header.number, b.header);
|
|
286
|
+
data.logs.set(b.header.number, (data.logs.get(b.header.number) ?? []).concat(b.logs));
|
|
287
|
+
if (b.transactions?.length)
|
|
288
|
+
data.txs.set(b.header.number, (data.txs.get(b.header.number) ?? []).concat(b.transactions));
|
|
289
|
+
stats.logs += b.logs.length;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (needTraces) {
|
|
294
|
+
const tq = { type: "evm", fields: { block: blockFieldsFor(filters), trace: TRACE_FIELDS, transaction: { transactionIndex: true, hash: true, from: true, to: true, input: true, value: true, nonce: true, gas: true, gasPrice: true, type: true, r: true, s: true, v: true } }, traces: tracePortalRequests() };
|
|
295
|
+
for await (const blocks of stream(tq, from, to)) {
|
|
296
|
+
for (const b of blocks)
|
|
297
|
+
if (b.traces?.length) {
|
|
298
|
+
const ex = data.traceBlocks.get(b.header.number);
|
|
299
|
+
if (ex) {
|
|
300
|
+
ex.traces.push(...b.traces);
|
|
301
|
+
if (b.transactions)
|
|
302
|
+
ex.txs.push(...b.transactions);
|
|
303
|
+
}
|
|
304
|
+
else
|
|
305
|
+
data.traceBlocks.set(b.header.number, { header: b.header, traces: b.traces, txs: b.transactions ?? [] });
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// block-interval sources: includeAllBlocks range-scan (Portal has no modulo filter),
|
|
310
|
+
// keep only headers matching a BlockFilter's interval/offset.
|
|
311
|
+
if (needBlocks) {
|
|
312
|
+
const bq = { type: "evm", includeAllBlocks: true, fields: { block: blockFieldsFor(blockFilters) } };
|
|
313
|
+
for await (const blocks of stream(bq, from, to)) {
|
|
314
|
+
for (const b of blocks) {
|
|
315
|
+
const bn = b.header.number;
|
|
316
|
+
if (blockFilters.some((f) => isBlockFilterMatched({ filter: f, block: { number: BigInt(bn) } })))
|
|
317
|
+
data.blockHeaders.set(bn, b.header);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// account transaction sources: Portal transactions[] from/to filter pushed server-side
|
|
322
|
+
if (needTxFilter) {
|
|
323
|
+
const txReqs = txPortalRequests();
|
|
324
|
+
if (txReqs.length) {
|
|
325
|
+
const tq = { type: "evm", fields: { block: blockFieldsFor(transactionFilters), transaction: needReceipts ? { ...TX_FIELDS, ...RECEIPT_FIELDS } : TX_FIELDS }, transactions: txReqs };
|
|
326
|
+
for await (const blocks of stream(tq, from, to)) {
|
|
327
|
+
for (const b of blocks)
|
|
328
|
+
if (b.transactions?.length) {
|
|
329
|
+
const ex = data.txBlocks.get(b.header.number);
|
|
330
|
+
if (ex)
|
|
331
|
+
ex.txs.push(...b.transactions);
|
|
332
|
+
else
|
|
333
|
+
data.txBlocks.set(b.header.number, { header: b.header, txs: b.transactions });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return data;
|
|
339
|
+
})();
|
|
340
|
+
dataCache.set(idx, p);
|
|
341
|
+
return p;
|
|
342
|
+
}
|
|
343
|
+
const factoryAddrOk = (filterAddr, addr, bn) => !isAddressFactory(filterAddr) || isAddressMatched({ address: addr, blockNumber: bn, childAddresses: args.childAddresses.get(filterAddr.id) });
|
|
344
|
+
const traceMatched = (frame, bn) => {
|
|
345
|
+
const blk = { number: BigInt(bn) };
|
|
346
|
+
for (const f of transferFilters)
|
|
347
|
+
if (isTransferFilterMatched({ filter: f, trace: frame, block: blk }) && factoryAddrOk(f.fromAddress, frame.from, bn) && factoryAddrOk(f.toAddress, frame.to, bn))
|
|
348
|
+
return true;
|
|
349
|
+
for (const f of traceFilters)
|
|
350
|
+
if (isTraceFilterMatched({ filter: f, trace: frame, block: blk }) && factoryAddrOk(f.fromAddress, frame.from, bn) && factoryAddrOk(f.toAddress, frame.to, bn))
|
|
351
|
+
return true;
|
|
352
|
+
return false;
|
|
353
|
+
};
|
|
354
|
+
const buildTraces = (cd, lo, hi) => {
|
|
355
|
+
const out = [];
|
|
356
|
+
for (const [bn, tb] of cd.traceBlocks) {
|
|
357
|
+
if (bn < lo || bn > hi || !tb.traces?.length)
|
|
358
|
+
continue;
|
|
359
|
+
const block = toSyncBlockHeader(tb.header); // encodeTrace only reads block.number
|
|
360
|
+
const txByIdx = new Map();
|
|
361
|
+
for (const tx of tb.txs ?? [])
|
|
362
|
+
txByIdx.set(tx.transactionIndex, tx);
|
|
363
|
+
const byTx = new Map();
|
|
364
|
+
for (const t of tb.traces) {
|
|
365
|
+
const k = t.transactionIndex ?? 0;
|
|
366
|
+
if (!byTx.has(k))
|
|
367
|
+
byTx.set(k, []);
|
|
368
|
+
byTx.get(k).push(t);
|
|
369
|
+
}
|
|
370
|
+
for (const [txIndex, traces] of byTx) {
|
|
371
|
+
traces.sort((x, y) => cmpTraceAddr(x.traceAddress ?? [], y.traceAddress ?? []));
|
|
372
|
+
const rawTx = txByIdx.get(txIndex);
|
|
373
|
+
traces.forEach((t, i) => {
|
|
374
|
+
const frame = parityToCallFrame(t, i);
|
|
375
|
+
if (!frame || !traceMatched(frame, bn))
|
|
376
|
+
return;
|
|
377
|
+
out.push({ trace: { trace: frame, transactionHash: rawTx?.hash }, block, transaction: rawTx ? toSyncTransaction(rawTx, tb.header) : { transactionIndex: hx(txIndex) } });
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return out;
|
|
382
|
+
};
|
|
383
|
+
// push the trace/transfer filters' addresses to Portal (resolving factories → children)
|
|
384
|
+
const tracePortalRequests = () => {
|
|
385
|
+
const reqs = [];
|
|
386
|
+
const addrsOf = (a) => {
|
|
387
|
+
if (a === undefined)
|
|
388
|
+
return undefined;
|
|
389
|
+
if (isAddressFactory(a))
|
|
390
|
+
return Array.from(args.childAddresses.get(a.id)?.keys() ?? []);
|
|
391
|
+
return (Array.isArray(a) ? a : [a]).map((x) => x.toLowerCase());
|
|
392
|
+
};
|
|
393
|
+
for (const f of [...traceFilters, ...transferFilters]) {
|
|
394
|
+
const req = {};
|
|
395
|
+
const to = addrsOf(f.toAddress);
|
|
396
|
+
if (to?.length)
|
|
397
|
+
req.callTo = to;
|
|
398
|
+
const from = addrsOf(f.fromAddress);
|
|
399
|
+
if (from?.length)
|
|
400
|
+
req.callFrom = from;
|
|
401
|
+
if (f.functionSelector)
|
|
402
|
+
req.callSighash = (Array.isArray(f.functionSelector) ? f.functionSelector : [f.functionSelector]).map((s) => s.toLowerCase());
|
|
403
|
+
req.transaction = true;
|
|
404
|
+
reqs.push(req);
|
|
405
|
+
}
|
|
406
|
+
return reqs.length ? reqs : [{ transaction: true }];
|
|
407
|
+
};
|
|
408
|
+
// push account TransactionFilters (from/to) to Portal's transactions[] (server-side row filter)
|
|
409
|
+
const txPortalRequests = () => {
|
|
410
|
+
const reqs = [];
|
|
411
|
+
const addrsOf = (a) => {
|
|
412
|
+
if (a === undefined)
|
|
413
|
+
return undefined;
|
|
414
|
+
if (isAddressFactory(a))
|
|
415
|
+
return Array.from(args.childAddresses.get(a.id)?.keys() ?? []);
|
|
416
|
+
return (Array.isArray(a) ? a : [a]).map((x) => x.toLowerCase());
|
|
417
|
+
};
|
|
418
|
+
for (const f of transactionFilters) {
|
|
419
|
+
const req = {};
|
|
420
|
+
const from = addrsOf(f.fromAddress);
|
|
421
|
+
if (from?.length)
|
|
422
|
+
req.from = from;
|
|
423
|
+
const to = addrsOf(f.toAddress);
|
|
424
|
+
if (to?.length)
|
|
425
|
+
req.to = to;
|
|
426
|
+
if (req.from || req.to)
|
|
427
|
+
reqs.push(req); // skip match-all (never fetch every tx)
|
|
428
|
+
}
|
|
429
|
+
return reqs;
|
|
430
|
+
};
|
|
431
|
+
return {
|
|
432
|
+
async syncBlockRangeData(params) {
|
|
433
|
+
const { interval, requiredIntervals, requiredFactoryIntervals, syncStore } = params;
|
|
434
|
+
if (!startTime)
|
|
435
|
+
startTime = Date.now();
|
|
436
|
+
// finality gap: if this interval reaches past Portal's finalized head, re-confirm
|
|
437
|
+
// (Portal advances) and, if still beyond, delegate the whole interval to RPC.
|
|
438
|
+
if (portalHead === undefined)
|
|
439
|
+
await refreshPortalHead();
|
|
440
|
+
if (isFinalityGap(interval[1], portalHead)) {
|
|
441
|
+
await refreshPortalHead(); // Portal advances — re-confirm before falling back
|
|
442
|
+
if (isFinalityGap(interval[1], portalHead)) {
|
|
443
|
+
delegated.add(ikey(interval));
|
|
444
|
+
stats.rpcFallback++;
|
|
445
|
+
log.debug({ service: "portal", msg: `Portal ${args.chain.name} [${interval[0]},${interval[1]}] past finalized head ${portalHead} → RPC fallback` });
|
|
446
|
+
return rpcFallback().syncBlockRangeData(params);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
await ensureChunkSize(); // scale chunk to chain block-density before any idxOf()
|
|
450
|
+
const filters = requiredIntervals.map((r) => r.filter).filter((f) => f.type === "log");
|
|
451
|
+
const factories = [...new Map(requiredFactoryIntervals.map((r) => [r.factory.id, r.factory])).values()];
|
|
452
|
+
needReceipts ||= requiredIntervals.some((r) => r.filter.hasTransactionReceipt === true);
|
|
453
|
+
if (!needBlocks && requiredIntervals.some((r) => r.filter.type === "block")) {
|
|
454
|
+
blockFilters = requiredIntervals.filter((r) => r.filter.type === "block").map((r) => r.filter);
|
|
455
|
+
needBlocks = blockFilters.length > 0;
|
|
456
|
+
}
|
|
457
|
+
if (!needTxFilter && requiredIntervals.some((r) => r.filter.type === "transaction")) {
|
|
458
|
+
transactionFilters = requiredIntervals.filter((r) => r.filter.type === "transaction").map((r) => r.filter);
|
|
459
|
+
needTxFilter = transactionFilters.length > 0;
|
|
460
|
+
}
|
|
461
|
+
if (!needTraces && requiredIntervals.some((r) => r.filter.type === "trace" || r.filter.type === "transfer")) {
|
|
462
|
+
traceFilters = requiredIntervals.filter((r) => r.filter.type === "trace").map((r) => r.filter);
|
|
463
|
+
transferFilters = requiredIntervals.filter((r) => r.filter.type === "transfer").map((r) => r.filter);
|
|
464
|
+
needTraces = traceFilters.length + transferFilters.length > 0;
|
|
465
|
+
}
|
|
466
|
+
// cap the chunk grid BEFORE any idxOf() for DENSE sources (traces fetch every trace;
|
|
467
|
+
// block sources includeAllBlocks-scan the WHOLE chunk range) — bounds memory + overfetch.
|
|
468
|
+
const capped = traceSafeChunkBlocks(chunkBlocks, needTraces || needBlocks);
|
|
469
|
+
if (capped !== chunkBlocks) {
|
|
470
|
+
chunkBlocks = capped;
|
|
471
|
+
dataCache.clear();
|
|
472
|
+
discCache.clear();
|
|
473
|
+
discStartIdx = undefined;
|
|
474
|
+
log.debug({ service: "portal", msg: `Portal ${args.chain.name}: dense sources → chunkBlocks capped to ${chunkBlocks} (grid reset)` });
|
|
475
|
+
}
|
|
476
|
+
// pin the discovery floor at the factory's real start (NOT block 0) — after any chunk cap
|
|
477
|
+
if (discStartIdx === undefined && factories.length > 0) {
|
|
478
|
+
const starts = requiredFactoryIntervals.map((r) => r.interval[0]).concat(interval[0]);
|
|
479
|
+
discStartIdx = idxOf(Math.min(...starts));
|
|
480
|
+
}
|
|
481
|
+
const startIdx = idxOf(interval[0]), endIdx = idxOf(interval[1]);
|
|
482
|
+
const idxs = [];
|
|
483
|
+
for (let i = startIdx; i <= endIdx; i++)
|
|
484
|
+
idxs.push(i);
|
|
485
|
+
const data = await Promise.all(idxs.map((i) => dataChunk(i, factories, filters)));
|
|
486
|
+
// PARALLEL read-ahead: prefetch the next READAHEAD chunks concurrently
|
|
487
|
+
for (let d = 1; d <= READAHEAD; d++)
|
|
488
|
+
void dataChunk(endIdx + d, factories, filters).catch(() => { });
|
|
489
|
+
const syncLogs = [];
|
|
490
|
+
const blocksByNumber = new Map();
|
|
491
|
+
const syncTxs = [];
|
|
492
|
+
const syncReceipts = [];
|
|
493
|
+
const seenTx = new Set();
|
|
494
|
+
for (const cd of data)
|
|
495
|
+
for (const [bn, hdr] of cd.headers) {
|
|
496
|
+
if (bn < interval[0] || bn > interval[1])
|
|
497
|
+
continue;
|
|
498
|
+
const logs = cd.logs.get(bn) ?? [];
|
|
499
|
+
if (logs.length) {
|
|
500
|
+
blocksByNumber.set(bn, toSyncBlockHeader(hdr));
|
|
501
|
+
for (const raw of logs)
|
|
502
|
+
syncLogs.push(toSyncLog(raw, hdr));
|
|
503
|
+
for (const tx of cd.txs.get(bn) ?? [])
|
|
504
|
+
if (!seenTx.has(tx.hash)) {
|
|
505
|
+
seenTx.add(tx.hash);
|
|
506
|
+
syncTxs.push(toSyncTransaction(tx, hdr));
|
|
507
|
+
if (needReceipts)
|
|
508
|
+
syncReceipts.push(toSyncReceipt(tx, hdr));
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
// block-interval sources: ensure each matched block is in the blocks table
|
|
513
|
+
if (needBlocks)
|
|
514
|
+
for (const cd of data)
|
|
515
|
+
for (const [bn, hdr] of cd.blockHeaders) {
|
|
516
|
+
if (bn >= interval[0] && bn <= interval[1] && !blocksByNumber.has(bn))
|
|
517
|
+
blocksByNumber.set(bn, toSyncBlockHeader(hdr));
|
|
518
|
+
}
|
|
519
|
+
// account transaction sources: re-match Portal's from/to-filtered txs (+ factory + range), insert tx/receipt/block
|
|
520
|
+
if (needTxFilter)
|
|
521
|
+
for (const cd of data)
|
|
522
|
+
for (const [bn, tb] of cd.txBlocks) {
|
|
523
|
+
if (bn < interval[0] || bn > interval[1])
|
|
524
|
+
continue;
|
|
525
|
+
for (const raw of tb.txs) {
|
|
526
|
+
if (seenTx.has(raw.hash))
|
|
527
|
+
continue;
|
|
528
|
+
const tx = toSyncTransaction(raw, tb.header);
|
|
529
|
+
if (!transactionFilters.some((f) => isTransactionFilterMatched({ filter: f, transaction: tx }) && factoryAddrOk(f.fromAddress, tx.from, bn) && factoryAddrOk(f.toAddress, (tx.to ?? undefined), bn)))
|
|
530
|
+
continue;
|
|
531
|
+
seenTx.add(raw.hash);
|
|
532
|
+
blocksByNumber.set(bn, toSyncBlockHeader(tb.header));
|
|
533
|
+
syncTxs.push(tx);
|
|
534
|
+
if (needReceipts)
|
|
535
|
+
syncReceipts.push(toSyncReceipt(raw, tb.header));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
for (const i of dataCache.keys())
|
|
539
|
+
if ((i + 1) * chunkBlocks <= interval[0])
|
|
540
|
+
dataCache.delete(i); // evict behind
|
|
541
|
+
const syncTraces = needTraces ? data.flatMap((cd) => buildTraces(cd, interval[0], interval[1])) : [];
|
|
542
|
+
let closest;
|
|
543
|
+
if (blocksByNumber.size > 0)
|
|
544
|
+
closest = blocksByNumber.get(Math.max(...blocksByNumber.keys()));
|
|
545
|
+
await syncStore.insertLogs({ logs: syncLogs, chainId: args.chain.id });
|
|
546
|
+
stash.set(ikey(interval), { blocks: [...blocksByNumber.values()], txs: syncTxs, receipts: syncReceipts, traces: syncTraces, closest });
|
|
547
|
+
log.debug({ service: "portal", msg: `Portal ${args.chain.name} [${interval[0]},${interval[1]}]: ${syncLogs.length} logs (dataChunks=${stats.dataChunks} discChunks=${stats.discChunks} http=${stats.http} hits=${stats.cacheHits} inflight=${stats.maxInflight} err=${stats.errors})` });
|
|
548
|
+
return syncLogs;
|
|
549
|
+
},
|
|
550
|
+
async syncBlockData(params) {
|
|
551
|
+
const { interval, syncStore } = params;
|
|
552
|
+
if (delegated.has(ikey(interval))) {
|
|
553
|
+
delegated.delete(ikey(interval));
|
|
554
|
+
return rpcFallback().syncBlockData(params);
|
|
555
|
+
}
|
|
556
|
+
const s = stash.get(ikey(interval));
|
|
557
|
+
stash.delete(ikey(interval));
|
|
558
|
+
if (!s)
|
|
559
|
+
return undefined;
|
|
560
|
+
const chainId = args.chain.id;
|
|
561
|
+
// merge log blocks/txs with trace blocks/txs (a trace-only block isn't in the log set)
|
|
562
|
+
const blocks = new Map();
|
|
563
|
+
for (const b of s.blocks)
|
|
564
|
+
blocks.set(b.number, b);
|
|
565
|
+
const txs = new Map();
|
|
566
|
+
for (const t of s.txs)
|
|
567
|
+
txs.set(t.hash, t);
|
|
568
|
+
for (const { block, transaction } of s.traces) {
|
|
569
|
+
blocks.set(block.number, block);
|
|
570
|
+
if (transaction?.hash)
|
|
571
|
+
txs.set(transaction.hash, transaction);
|
|
572
|
+
}
|
|
573
|
+
const blockArr = [...blocks.values()];
|
|
574
|
+
if (blockArr.length === 0)
|
|
575
|
+
return s.closest;
|
|
576
|
+
await syncStore.insertBlocks({ blocks: blockArr, chainId });
|
|
577
|
+
if (txs.size)
|
|
578
|
+
await syncStore.insertTransactions({ transactions: [...txs.values()], chainId });
|
|
579
|
+
if (s.receipts.length)
|
|
580
|
+
await syncStore.insertTransactionReceipts({ transactionReceipts: s.receipts, chainId });
|
|
581
|
+
if (s.traces.length)
|
|
582
|
+
await syncStore.insertTraces({ traces: s.traces, chainId });
|
|
583
|
+
stats.blocks += blockArr.length;
|
|
584
|
+
stats.txs += txs.size;
|
|
585
|
+
stats.receipts += s.receipts.length;
|
|
586
|
+
stats.traces += s.traces.length;
|
|
587
|
+
writeMetrics();
|
|
588
|
+
return s.closest;
|
|
589
|
+
},
|
|
590
|
+
};
|
|
591
|
+
};
|
|
592
|
+
//# sourceMappingURL=portal.js.map
|