Skip to content

PE-9103: Add block range filters to ID-based GraphQL queries#2139

Open
vilenarios wants to merge 4 commits into
devfrom
PE-9103-graphql-block-range-filters
Open

PE-9103: Add block range filters to ID-based GraphQL queries#2139
vilenarios wants to merge 4 commits into
devfrom
PE-9103-graphql-block-range-filters

Conversation

@vilenarios

@vilenarios vilenarios commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • LicenseAssertions, LicenseComposed: Added block: { min, max } filter parameters to avoid ClickHouse TOO_MANY_ROWS errors on turbo-gateway.com
  • TransactionStatuses: Added block: { max } filter (no min, since these are pending txs)
  • Dynamic chunk sizing: Computes safe chunk size based on block range instead of fixed size. Tight range (incremental sync) = bigger chunks, wide range (first sync) = smaller chunks
  • Min block estimation: Derives minBlockHeight from the earliest FileRevision.dateCreated using Arweave's ~2min block time, with a 5000-block safety margin

Problem

turbo-gateway.com uses ClickHouse which scans ~2.4 rows per block per tx ID. Without block filters, queries with 3+ IDs exceed the 10M row limit:

  • 2 IDs, no filter: ~9M rows (works)
  • 3 IDs, no filter: ~14M rows (fails)
  • 5 IDs, no filter: ~138M rows (fails)

With block range filters:

  • 50 IDs, 50k block range: works
  • 20 IDs, 200k block range: works

Impact

Scenario Before After
16k licenses, last year (~200k range) Fails (100 IDs/chunk) ~1,600 queries (10/chunk)
50 licenses, incremental sync (~5k range) Fails 1 query (50/chunk)
1 license, file details panel 1 query 1 query (unchanged)

License sync runs in the background (fire-and-forget) so query count doesn't block sync completion.

Test plan

  • Tested queries directly against turbo-gateway.com with various ID counts and block ranges
  • flutter analyze — no issues
  • Existing tests pass
  • Manual: sync with a drive that has licensed files, verify licenses appear in file details
  • Manual: check browser console for "License assertions/composed" log lines showing block range and chunk size

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor

    • Removed ARIO on Base from available payment token options
    • Removed Turbo fee indicator badge from token selection UI
    • Updated transaction and license data-fetching logic
  • Style

    • Adjusted crypto payment modal layouts and spacing

vilenarios and others added 2 commits June 22, 2026 21:44
- remove ARIO on AO, ARIO on Base, and ARIO via ETH from all token
  selection lists (token groups, inline payment dropdown, payment
  method selector, old token selection view)
- payment_method_selector dropdown now uses TokenGroup.allGroups
  instead of CryptoToken.values to avoid showing hidden tokens
- fix excessive vertical white space in crypto topup modals by
  replacing Expanded with Flexible in content wrappers and removing
  the fixed 600dp height from the modal container
- remove unused _BenefitChip widget

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
turbo-gateway.com's ClickHouse indexer scans ~2.4 rows per block per
tx ID. Without block filters, queries with 3+ IDs exceed the 10M row
limit and fail with TOO_MANY_ROWS.

Changes:
- LicenseAssertions, LicenseComposed: add block: { min, max } filter
- TransactionStatuses: add block: { max } filter (no min for pending txs)
- Estimate minBlockHeight from revision dates (~2min/block from genesis)
- Dynamic chunk sizing based on block range: tight range = bigger chunks
  e.g. 200k range → 10 IDs/chunk, 50k range → 41 IDs/chunk
- TransactionStatuses: fixed chunk size of 2 (no min block available)

For 16k licenses from the last year (~200k block range), this means
~1600 queries instead of 8000 (or 16000 with chunk=1). For incremental
syncs (~5k block range), a single query handles up to 50 licenses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@vilenarios, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 45 minutes and 10 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2c71ae3e-5f32-4f09-9b9a-d328fc1c2d8e

📥 Commits

Reviewing files that changed from the base of the PR and between c767ad1 and bcb65b0.

📒 Files selected for processing (2)
  • lib/services/arweave/arweave_service.dart
  • lib/sync/domain/repositories/sync_repository.dart
📝 Walkthrough

Note: range_848852 was referenced in the layer above but is not in <all_range_ids>; range_90a0d419c761 covers that checkpoint instead.

Walkthrough

Block-height bounds are added to three Arweave GraphQL queries and their service methods via optional minBlockHeight/maxBlockHeight parameters; a _safeChunkSize helper drives dynamic batching. SyncRepository propagates currentBlockHeight as maxBlockHeight into license and transaction-status sync paths and estimates minBlockHeight from revision timestamps. Separately, CryptoToken.arioBase is removed from all Turbo topup token lists and several modal layouts switch from Expanded to Flexible.

Changes

Arweave Block-Range Bounded Sync

Layer / File(s) Summary
GraphQL query signatures: block-height variables
lib/services/arweave/graphql/queries/LicenseAssertions.graphql, lib/services/arweave/graphql/queries/LicenseDataBundled.graphql, lib/services/arweave/graphql/queries/TransactionStatuses.graphql
All three queries gain optional $minBlockHeight/$maxBlockHeight variables and a block filter argument on their transactions selections.
ArweaveService: dynamic chunking and block-range forwarding
lib/services/arweave/arweave_service.dart
New _safeChunkSize(minBlock, maxBlock) helper computes chunk size in [1,50]; getLicenseAssertions and getLicenseComposed accept optional block-range params and use it; getTransactionConfirmations accepts maxBlockHeight, drops chunk size from 100 to 2, and forwards the bound into TransactionStatusesArguments.
SyncRepository: threading block bounds into license and tx-status sync
lib/sync/domain/repositories/sync_repository.dart
Adds _estimateMinBlock(DateTime) helper; _updateLicenses computes minBlockHeight from earliest revision date and passes both bounds to license fetches; _updateTransactionStatusesForDrive and _updateTransactionStatuses gain an optional maxBlockHeight param forwarded to getTransactionConfirmations; all four call sites in syncAllDrives/syncSingleDrive pass currentBlockHeight.

ARIO Token Removal and Turbo UI Layout Fixes

Layer / File(s) Summary
ARIO Base token removal from model and views
lib/turbo/topup/models/crypto_token.dart, lib/turbo/topup/views/crypto_topup/token_selection_view.dart, lib/turbo/topup/views/unified/inline_crypto_payment.dart, lib/turbo/topup/components/payment_method_selector.dart
CryptoToken.arioBase removed from the Ethereum-wallet TokenGroup, from the Base Network token list, from the inline dropdown, and from the recommended section; payment_method_selector switches token enumeration to TokenGroup.allGroups and drops the noTurboFee badge.
Modal and view layout adjustments
lib/turbo/topup/views/crypto_topup/crypto_topup_modal.dart, lib/turbo/topup/views/unified/crypto_confirmation_view.dart, lib/turbo/topup/views/unified/crypto_processing_view.dart, lib/turbo/topup/views/unified/wallet_connection_view.dart
CryptoTopupModal uses contentPadding: EdgeInsets.zero and content-driven height; _SessionExpiredView and _ConcurrentSessionView remove Expanded wrappers; crypto_confirmation_view, crypto_processing_view, and wallet_connection_view switch from Expanded to Flexible; wallet_connection_view removes a 48px spacer.

Sequence Diagram(s)

sequenceDiagram
  participant SyncRepository
  participant ArweaveService
  participant GraphQL

  rect rgba(30, 100, 200, 0.5)
    Note over SyncRepository,GraphQL: License sync with block bounds
    SyncRepository->>SyncRepository: _estimateMinBlock(earliestRevisionDate) → minBlockHeight
    SyncRepository->>ArweaveService: getLicenseAssertions(ids, minBlockHeight, maxBlockHeight)
    ArweaveService->>ArweaveService: _safeChunkSize(min, max) → chunkSize [1..50]
    ArweaveService->>GraphQL: LicenseAssertions(ids_chunk, block:{min,max})
    GraphQL-->>ArweaveService: assertion results
    ArweaveService-->>SyncRepository: yield assertions
    SyncRepository->>ArweaveService: getLicenseComposed(ids, minBlockHeight, maxBlockHeight)
    ArweaveService->>GraphQL: LicenseComposed(ids_chunk, block:{min,max})
    GraphQL-->>ArweaveService: composed results
    ArweaveService-->>SyncRepository: yield composed
  end

  rect rgba(200, 80, 30, 0.5)
    Note over SyncRepository,GraphQL: Tx confirmations with block bound
    SyncRepository->>ArweaveService: getTransactionConfirmations(ids, maxBlockHeight)
    ArweaveService->>GraphQL: TransactionStatuses(ids_chunk=2, block:{max})
    GraphQL-->>ArweaveService: statuses
    ArweaveService-->>SyncRepository: confirmations map
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • ardriveapp/ardrive-web#2116: Directly overlaps on ARIO/AO token disabling in the same lib/turbo/topup/models/crypto_token.dart and lib/turbo/topup/views/... files.
  • ardriveapp/ardrive-web#2136: Modifies the same _updateLicenses call sites inside syncAllDrives/syncSingleDrive in sync_repository.dart, running them fire-and-forget — directly adjacent to this PR's block-height wiring at those same call sites.

Poem

🐇 Hop, hop through the blocks I go,
Slicing chunks with a safe hello,
Min and max keep the query neat,
ARIO Base? No longer on this street!
Flexible now where Expanded stood,
This bunny synced the blockchain good! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely captures the main objective of the PR: adding block range filters to ID-based GraphQL queries to optimize performance.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch PE-9103-graphql-block-range-filters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/services/arweave/arweave_service.dart (2)

1238-1260: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not treat bounded misses as globally missing transactions.

With maxBlockHeight applied, a missing edge only proves the transaction was not returned within that bounded view. Because the map is prefilled with -1, downstream status updates can mark a transaction as failed even if it was mined after maxBlockHeight.

Proposed fix
-    final transactionConfirmations = {
-      for (final transactionId in transactionIds) transactionId: -1
-    };
+    final transactionConfirmations = <String?, int>{};
+    if (maxBlockHeight == null) {
+      for (final transactionId in transactionIds) {
+        transactionConfirmations[transactionId] = -1;
+      }
+    }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/services/arweave/arweave_service.dart` around lines 1238 - 1260, The
issue is that the transactionConfirmations map is prefilled with -1 for all
transactionIds, which causes bounded misses (transactions not found within the
maxBlockHeight range) to be treated as globally missing transactions. When
processing the query results from the GraphQL retry with the maxBlockHeight
filter applied, transactions that are missing from the result should not
automatically be marked as failed since they may have been mined after
maxBlockHeight. Instead of initializing all transactions with -1, only update
the map with transaction confirmations that are actually returned from the query
results, and leave transactions that aren't found in the bounded query unset so
they can be properly distinguished from globally confirmed missing transactions.

1242-1277: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Avoid fanning out every 2-ID status chunk concurrently.

For a 5000-ID page, chunkSize = 2 creates up to 2500 simultaneous GraphQL requests. That can overload the gateway/client and make the 5-second caller timeout much more likely.

Proposed fix
-    final confirmationFutures = <Future<void>>[];
-
     for (var i = 0; i < transactionIds.length; i += chunkSize) {
-      confirmationFutures.add(() async {
-        final chunkEnd = (i + chunkSize < transactionIds.length)
-            ? i + chunkSize
-            : transactionIds.length;
+      final chunkEnd = (i + chunkSize < transactionIds.length)
+          ? i + chunkSize
+          : transactionIds.length;
+      final chunk = transactionIds
+          .sublist(i, chunkEnd)
+          .whereType<String>()
+          .toList(growable: false);
+
+      if (chunk.isEmpty) {
+        continue;
+      }
 
-        final query = await graphQLRetry.execute(
-          TransactionStatusesQuery(
-            variables: TransactionStatusesArguments(
-              transactionIds:
-                  transactionIds.sublist(i, chunkEnd) as List<String>?,
-              maxBlockHeight: maxBlockHeight,
-            ),
+      final query = await graphQLRetry.execute(
+        TransactionStatusesQuery(
+          variables: TransactionStatusesArguments(
+            transactionIds: chunk,
+            maxBlockHeight: maxBlockHeight,
           ),
-        );
+        ),
+      );
 
-        final currentBlockHeight = query.data!.blocks.edges.first.node.height;
+      final currentBlockHeight = query.data!.blocks.edges.first.node.height;
 
-        for (final transaction
-            in query.data!.transactions.edges.map((e) => e.node)) {
-          if (transaction.block == null) {
-            transactionConfirmations[transaction.id] = 0;
-            continue;
-          }
+      for (final transaction
+          in query.data!.transactions.edges.map((e) => e.node)) {
+        if (transaction.block == null) {
+          transactionConfirmations[transaction.id] = 0;
+          continue;
+        }
 
-          transactionConfirmations[transaction.id] =
-              currentBlockHeight - transaction.block!.height + 1;
-        }
-      }());
-    }
-
-    try {
-      await Future.wait(confirmationFutures);
-    } catch (e) {
-      logger.e('Error getting transactions confirmations on exception', e);
-      rethrow;
+        transactionConfirmations[transaction.id] =
+            currentBlockHeight - transaction.block!.height + 1;
+      }
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/services/arweave/arweave_service.dart` around lines 1242 - 1277, The code
currently creates a Future for every 2-ID chunk and adds all of them to the
confirmationFutures list without any concurrency control, resulting in up to
2500 simultaneous GraphQL requests for a 5000-ID page. Implement concurrency
limiting by batching the futures instead of adding all at once—for example,
create a smaller batch of futures (e.g., 10-50 concurrent requests), await them
to completion, then process the next batch. This can be done by modifying the
loop structure to either await futures in groups using Future.wait with a limit,
or by adding futures conditionally and awaiting them when a concurrent limit is
reached, keeping the graphQLRetry.execute calls within the
TransactionStatusesQuery execution under control.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/sync/domain/repositories/sync_repository.dart`:
- Around line 1576-1579: The minBlockHeight calculated from _estimateMinBlock
can exceed the maxBlockHeight when dateCreated is in the future, resulting in an
invalid bounded query range. After calculating minBlockHeight using
_estimateMinBlock with earliestDate, clamp the value to ensure it does not
exceed the maxBlockHeight to keep the range valid before passing it to the
GraphQL query.

In `@lib/turbo/topup/views/crypto_topup/crypto_topup_modal.dart`:
- Around line 303-325: The icon and message block containing the
timer_off_outlined icon and text messages are currently left-aligned because
they reside in a Column with crossAxisAlignment set to CrossAxisAlignment.start,
despite the Text widgets using TextAlign.center. To fix this, apply a centering
wrapper (such as a Center widget) around the icon and message block to ensure
both the icon and text are horizontally centered. Apply the same centering
pattern to the corresponding icon/message block in the _ConcurrentSessionView
widget as well.

---

Outside diff comments:
In `@lib/services/arweave/arweave_service.dart`:
- Around line 1238-1260: The issue is that the transactionConfirmations map is
prefilled with -1 for all transactionIds, which causes bounded misses
(transactions not found within the maxBlockHeight range) to be treated as
globally missing transactions. When processing the query results from the
GraphQL retry with the maxBlockHeight filter applied, transactions that are
missing from the result should not automatically be marked as failed since they
may have been mined after maxBlockHeight. Instead of initializing all
transactions with -1, only update the map with transaction confirmations that
are actually returned from the query results, and leave transactions that aren't
found in the bounded query unset so they can be properly distinguished from
globally confirmed missing transactions.
- Around line 1242-1277: The code currently creates a Future for every 2-ID
chunk and adds all of them to the confirmationFutures list without any
concurrency control, resulting in up to 2500 simultaneous GraphQL requests for a
5000-ID page. Implement concurrency limiting by batching the futures instead of
adding all at once—for example, create a smaller batch of futures (e.g., 10-50
concurrent requests), await them to completion, then process the next batch.
This can be done by modifying the loop structure to either await futures in
groups using Future.wait with a limit, or by adding futures conditionally and
awaiting them when a concurrent limit is reached, keeping the
graphQLRetry.execute calls within the TransactionStatusesQuery execution under
control.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0cffc497-a420-4037-8787-4e69a2e9ac0b

📥 Commits

Reviewing files that changed from the base of the PR and between f880abb and c767ad1.

📒 Files selected for processing (13)
  • lib/services/arweave/arweave_service.dart
  • lib/services/arweave/graphql/queries/LicenseAssertions.graphql
  • lib/services/arweave/graphql/queries/LicenseDataBundled.graphql
  • lib/services/arweave/graphql/queries/TransactionStatuses.graphql
  • lib/sync/domain/repositories/sync_repository.dart
  • lib/turbo/topup/components/payment_method_selector.dart
  • lib/turbo/topup/models/crypto_token.dart
  • lib/turbo/topup/views/crypto_topup/crypto_topup_modal.dart
  • lib/turbo/topup/views/crypto_topup/token_selection_view.dart
  • lib/turbo/topup/views/unified/crypto_confirmation_view.dart
  • lib/turbo/topup/views/unified/crypto_processing_view.dart
  • lib/turbo/topup/views/unified/inline_crypto_payment.dart
  • lib/turbo/topup/views/unified/wallet_connection_view.dart
💤 Files with no reviewable changes (3)
  • lib/turbo/topup/models/crypto_token.dart
  • lib/turbo/topup/views/crypto_topup/token_selection_view.dart
  • lib/turbo/topup/views/unified/inline_crypto_payment.dart

Comment thread lib/sync/domain/repositories/sync_repository.dart Outdated
Comment on lines +303 to +325
// Icon and message
Icon(
Icons.timer_off_outlined,
size: 64,
color: colors.themeWarningFg,
),
const SizedBox(height: 24),
Text(
'Your session has expired due to inactivity.',
style: typography.paragraphLarge(
color: colors.themeFgDefault,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
'Please start a new payment to continue.',
style: typography.paragraphNormal(
color: colors.themeFgMuted,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 24),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Center alignment regressed for status icon/message blocks.

After removing Center/Expanded, these widgets now sit in Column(crossAxisAlignment: CrossAxisAlignment.start), so the icon and message block render left-aligned even though text uses TextAlign.center.

Suggested fix
-        Icon(
-          Icons.timer_off_outlined,
-          size: 64,
-          color: colors.themeWarningFg,
-        ),
-        const SizedBox(height: 24),
-        Text(
-          'Your session has expired due to inactivity.',
-          ...
-          textAlign: TextAlign.center,
-        ),
-        const SizedBox(height: 8),
-        Text(
-          'Please start a new payment to continue.',
-          ...
-          textAlign: TextAlign.center,
-        ),
+        Center(
+          child: Column(
+            children: [
+              Icon(
+                Icons.timer_off_outlined,
+                size: 64,
+                color: colors.themeWarningFg,
+              ),
+              const SizedBox(height: 24),
+              Text(
+                'Your session has expired due to inactivity.',
+                ...
+                textAlign: TextAlign.center,
+              ),
+              const SizedBox(height: 8),
+              Text(
+                'Please start a new payment to continue.',
+                ...
+                textAlign: TextAlign.center,
+              ),
+            ],
+          ),
+        ),

Apply the same centering pattern to the _ConcurrentSessionView icon/message block.

Also applies to: 393-415

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/turbo/topup/views/crypto_topup/crypto_topup_modal.dart` around lines 303
- 325, The icon and message block containing the timer_off_outlined icon and
text messages are currently left-aligned because they reside in a Column with
crossAxisAlignment set to CrossAxisAlignment.start, despite the Text widgets
using TextAlign.center. To fix this, apply a centering wrapper (such as a Center
widget) around the icon and message block to ensure both the icon and text are
horizontally centered. Apply the same centering pattern to the corresponding
icon/message block in the _ConcurrentSessionView widget as well.

vilenarios and others added 2 commits June 23, 2026 00:06
Pending transactions older than 1 day are now marked failed locally
before any GraphQL queries fire. This prevents zombie pending txs
from firing TransactionStatuses queries every sync — especially when
the queries time out and the txs never get their status updated.

Also adds early return when there are no pending transactions to
avoid unnecessary work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Reverted two approaches that had data integrity risks:

1. Block height estimation from FileRevision.dateCreated — this is ArFS
   metadata (client-set), not an Arweave block timestamp. License
   assertion txs can be at different blocks than the file revision.
   An overestimated minBlockHeight would silently miss licenses.

2. Marking stale pending txs as failed without checking the chain —
   a successfully mined tx that took >1 day would be incorrectly
   marked as failed.

Safe changes retained:
- maxBlockHeight filter on all ID-based queries (accurate, from
  getCurrentBlockHeight)
- Fixed chunk size of 2 IDs per query (tested safe on turbo-gateway)
- Early return when no pending transactions exist
- block filter params remain in .graphql schemas for future use when
  a reliable minBlockHeight source is available

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit bcb65b0):

https://ardrive-web--pr2139-pe-9103-graphql-bloc-42hfwiag.web.app

(expires Tue, 30 Jun 2026 04:26:04 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: a224ebaee2f0939e7665e7630e7d3d6cd7d0f8b0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant