Skip to content

Handle Solana skipped slots in block fetching and unfinalized block t…#30

Merged
ianhe8x merged 6 commits into
mainfrom
skip-block
Jun 17, 2026
Merged

Handle Solana skipped slots in block fetching and unfinalized block t…#30
ianhe8x merged 6 commits into
mainfrom
skip-block

Conversation

@ianhe8x

@ianhe8x ianhe8x commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

…racking

getBlock throws a SolanaError (block not available / slot skipped) for skipped slots instead of returning null, which was crashing the node. Convert these to BlockUnavailableError in fetchBlock and getHeaderByHeight, and allow non-consecutive heights when registering unfinalized blocks.

Description

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Fixes # (issue)

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist

  • I have tested locally
  • I have performed a self review of my changes
  • Updated any relevant documentation
  • Linked to any relevant issues
  • I have added tests relevant to my changes
  • Any dependent changes have been merged and published in downstream modules
  • My code is up to date with the base branch
  • I have updated relevant changelogs. We suggest using chan

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved handling of skipped blocks and non-consecutive unfinalized heights on Solana networks, allowing indexing to continue without strict sequential assumptions.
    • Improved header construction by honoring the originally requested slot, including clearer normalization when blocks are unavailable due to skipped-slot conditions.
    • Added safer backfilling across skipped slots while correctly detecting and rolling back on forks or mismatched parents.
  • Chores

    • Added an additional runtime dependency to enhance error handling.

…racking

getBlock throws a SolanaError (block not available / slot skipped) for
skipped slots instead of returning null, which was crashing the node.
Convert these to BlockUnavailableError in fetchBlock and getHeaderByHeight,
and allow non-consecutive heights when registering unfinalized blocks.
@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Coverage report

Caution

Test run failed

St.
Category Percentage Covered / Total
🔴 Statements 55.96% 2442/4364
🟡 Branches 69.06% 250/362
🔴 Functions 49.76% 103/207
🔴 Lines 55.96% 2442/4364

Test suite run failed

Failed tests: 4/57. Failed suites: 1/8.
  ● test solana project.yaml › could get options in template from its deployment

    expect(received).toContain(expected) // indexOf

    Expected substring: "abi: Pool"
    Received string:    "dataSources:
      - kind: solana/Runtime
        mapping:
          file: ./dist/index.js
          handlers:
            - filter: {}
              handler: handlePoolCreated
              kind: solana/LogHandler
        startBlock: 12369621
      - kind: solana/Runtime
        mapping:
          file: ./dist/index.js
          handlers:
            - filter: {}
              handler: handleIncreaseLiquidity
              kind: solana/LogHandler
            - filter: {}
              handler: handleDecreaseLiquidity
              kind: solana/LogHandler
            - filter: {}
              handler: handleCollect
              kind: solana/LogHandler
            - filter: {}
              handler: handleTransfer
              kind: solana/LogHandler
        startBlock: 12369651
    network:
      chainId: '1'
    runner:
      node:
        name: '@subql/node-solana'
        version: '*'
      query:
        name: '@subql/query'
        version: '*'
    schema:
      file: ./schema.graphql
    specVersion: 1.0.0
    templates:
      - kind: solana/Runtime
        mapping:
          file: ./dist/index.js
          handlers:
            - filter: {}
              handler: handleInitialize
              kind: solana/LogHandler
            - filter: {}
              handler: handleSwap
              kind: solana/LogHandler
            - filter: {}
              handler: handleMint
              kind: solana/LogHandler
            - filter: {}
              handler: handleBurn
              kind: solana/LogHandler
            - filter: {}
              handler: handleFlash
              kind: solana/LogHandler
        name: Pool
    "

      41 |     const manifest = loadSolanaProjectManifest(path.join(projectsDir, 'project_1.0.0.yaml'));
      42 |     const deployment = manifest.toDeployment();
    > 43 |     expect(deployment).toContain('abi: Pool');
         |                        ^
      44 |   });
      45 | });
      46 |

      at Object.<anonymous> (packages/common-solana/src/project/project.spec.ts:43:24)

  ● project.yaml › can validate project.yaml

    Not implemented

      48 |   it('can validate project.yaml', () => {
      49 |     // TODO this should catch a specific error, the file doesn't currently exist
    > 50 |     throw new Error('Not implemented');
         |           ^
      51 |     expect(() => loadSolanaProjectManifest(path.join(projectsDir, 'project_falsy.yaml'))).toThrow();
      52 |     expect(() => loadSolanaProjectManifest(path.join(projectsDir, 'project_falsy_array.yaml'))).toThrow();
      53 |   });

      at Object.<anonymous> (packages/common-solana/src/project/project.spec.ts:50:11)

  ● project.yaml › can fail validation if version not supported

    Not implemented

      55 |   it('can fail validation if version not supported', () => {
      56 |     // TODO this should catch a specific error, the file doesn't currently exist
    > 57 |     throw new Error('Not implemented');
         |           ^
      58 |     expect(() => loadSolanaProjectManifest(path.join(projectsDir, 'project_invalid_version.yaml'))).toThrow('');
      59 |   });
      60 |

      at Object.<anonymous> (packages/common-solana/src/project/project.spec.ts:57:11)

  ● project.yaml › get v1.0.0 deployment mapping filter

    expect(received).toContain(expected) // indexOf

    Expected substring: "Transfer (address from, address to, uint256 tokenId)"
    Received string:    "dataSources:
      - kind: solana/Runtime
        mapping:
          file: ./dist/index.js
          handlers:
            - filter: {}
              handler: handlePoolCreated
              kind: solana/LogHandler
        startBlock: 12369621
      - kind: solana/Runtime
        mapping:
          file: ./dist/index.js
          handlers:
            - filter: {}
              handler: handleIncreaseLiquidity
              kind: solana/LogHandler
            - filter: {}
              handler: handleDecreaseLiquidity
              kind: solana/LogHandler
            - filter: {}
              handler: handleCollect
              kind: solana/LogHandler
            - filter: {}
              handler: handleTransfer
              kind: solana/LogHandler
        startBlock: 12369651
    network:
      chainId: '1'
    runner:
      node:
        name: '@subql/node-solana'
        version: '*'
      query:
        name: '@subql/query'
        version: '*'
    schema:
      file: ./schema.graphql
    specVersion: 1.0.0
    templates:
      - kind: solana/Runtime
        mapping:
          file: ./dist/index.js
          handlers:
            - filter: {}
              handler: handleInitialize
              kind: solana/LogHandler
            - filter: {}
              handler: handleSwap
              kind: solana/LogHandler
            - filter: {}
              handler: handleMint
              kind: solana/LogHandler
            - filter: {}
              handler: handleBurn
              kind: solana/LogHandler
            - filter: {}
              handler: handleFlash
              kind: solana/LogHandler
        name: Pool
    "

      70 |     const deploymentString = manifestVersioned.toDeployment();
      71 |     expect(filter).not.toBeNull();
    > 72 |     expect(deploymentString).toContain('Transfer (address from, address to, uint256 tokenId)');
         |                              ^
      73 |   });
      74 |
      75 |   it('can convert genesis hash in v1.0.0 to chainId in deployment', () => {

      at Object.<anonymous> (packages/common-solana/src/project/project.spec.ts:72:30)

Report generated by 🧪jest coverage report action from 82c99e9

BLOCK_NOT_AVAILABLE and LONG_TERM_STORAGE_SLOT_SKIPPED don't reliably
mean a slot was skipped (the former can be a transient node-lag signal,
the latter an archival backfill gap), so silently converting them to
BlockUnavailableError risked masking real blocks instead of just
crashing on them.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a3905c18c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (
lastUnfinalizedHeight !== undefined &&
lastUnfinalizedHeight + 1 !== header.blockHeight
lastUnfinalizedHeight >= header.blockHeight

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve actual slots before allowing gaps

After a skipped slot, Solana's next block has parentSlot set to the last produced ancestor, while our solanaBlockToHeader still reports blockHeight as parentSlot + 1. For example, if slot 103 is skipped then fetching slot 104 produces a header at 103; this relaxed >= check then lets slot 105 register after that bogus 103, so unfinalized metadata drifts from the actual slot numbers instead of failing fast. Please carry the requested slot into the header before allowing non-consecutive heights.

Useful? React with 👍 / 👎.

Comment thread packages/node/src/solana/api.solana.ts Outdated
return (
isSolanaError(
e,
SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Retry block-not-available responses before skipping

When an RPC node is lagging or load-balanced, -32004 means the block is not retrievable from that node yet, not necessarily that the slot is permanently skipped; the existing getFinalizedBlockHeader comment even relies on retrying this case. Including BLOCK_NOT_AVAILABLE here converts those transient responses into BlockUnavailableError, bypassing handleError/backoff and letting callers treat a real slot as skipped. Restrict this helper to the permanent skipped-slot codes, or retry -32004 before mapping it to unavailable.

Useful? React with 👍 / 👎.

ianhe8x added 2 commits June 17, 2026 21:06
getBlock responses don't include their own slot, only the parent's.
Deriving blockHeight as parentSlot + 1 is wrong whenever the previous
slot was skipped, which let bogus heights into unfinalized block
tracking. fetchBlock and getHeaderByHeight now pass the slot they
actually requested through to the header.
BaseWorkerService.fetchBlock calls toBlockResponse with the unwrapped
BlockContent, not the IBlock, so the requested slot couldn't be passed
through the same way as fetchBlock/getHeaderByHeight. Track the
requested slot per block in a WeakMap set in fetchChainBlock and read
it back in toBlockResponse, so worker-threaded mode reports the same
correct height as the non-worker path.
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds skipped-slot handling for Solana: solanaBlockToHeader and formatBlockUtil accept an optional slot parameter for correct blockHeight derivation; api.solana.ts uses @solana/errors to detect and map skipped-slot RPC errors to BlockUnavailableError; WorkerService tracks the requested slot per block via a WeakMap; the unfinalized block ordering check is relaxed from consecutive to monotonic; and a new backfillSkippedSlots helper reconstructs intermediate headers for gaps.

Changes

Solana Skipped Slot Handling

Layer / File(s) Summary
Block header slot propagation contract
packages/node/src/solana/block.solana.ts
solanaBlockToHeader and formatBlockUtil gain an optional slot parameter; blockHeight uses the provided slot or falls back to parentSlot + 1.
Skipped-slot RPC detection and BlockUnavailableError mapping
packages/node/package.json, packages/node/src/solana/api.solana.ts
Adds @solana/errors dependency, isSkippedSlotError helper, and updates getHeaderByHeight and fetchBlock to catch skipped-slot RPC errors, throw BlockUnavailableError, and forward the known slot to header conversion functions.
Worker slot tracking and pass-through
packages/node/src/indexer/worker/worker.service.ts
WorkerService uses a WeakMap<BlockContent, number> to track the originally requested slot and passes it to solanaBlockToHeader in toBlockResponse.
Unfinalized block monotonic ordering and skipped-slot backfill
packages/node/src/indexer/unfinalizedBlocks.service.ts
registerUnfinalizedBlock replaces strict consecutive-height check with monotonic-increase check, attempts to backfill intermediate headers via new backfillSkippedSlots method when gaps are detected, and returns a forked header early if found during backfill. processUnfinalizedBlockHeader captures the optional forked header from registerUnfinalizedBlock.
Test coverage for skipped slots and unfinalized backfill
packages/node/src/indexer/unfinalizedBlocks.service.spec.ts
Mock blockchain now supports configurable skipped slots, derives parentHash from nearest non-skipped produced parent, and throws BlockUnavailableError for skipped heights. Existing fork test updated; new tests verify parent-chain rebuilding across gaps, rollback on incorrect backfilled parent, and rollback on failed connection.

Sequence Diagram(s)

sequenceDiagram
  participant Worker as WorkerService
  participant API as SolanaApi
  participant RPC as Solana RPC
  participant Header as solanaBlockToHeader
  participant Unfinalized as UnfinalizedBlocksService

  Worker->>API: fetchChainBlock(heights)
  API->>RPC: getBlock(slot)
  alt slot skipped
    RPC-->>API: JSON-RPC slot skipped error
    API->>API: isSkippedSlotError(err)
    API-->>Worker: throw BlockUnavailableError
  else block returned
    RPC-->>API: BlockResponse
    API-->>Worker: BlockContent
    Worker->>Worker: blockSlots.set(block, heights)
    Worker->>Header: solanaBlockToHeader(block, slot)
    Header-->>Worker: Header { blockHeight: slot }
    Worker->>Unfinalized: registerUnfinalizedBlock(header)
    alt height gap detected
      Unfinalized->>API: backfill intermediate headers
      API->>RPC: getBlock(missingHeight)
      RPC-->>API: BlockResponse or skipped error
      API-->>Unfinalized: Header or BlockUnavailableError
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 Hop, hop, a slot was skipped today,
The blockchain leapt and went on its way,
No panic, no crash, just a graceful throw,
BlockUnavailableError steals the show.
With backfill logic, WeakMap, and slot in mind,
This rabbit leaves no missing block behind! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: handling Solana skipped slots in block fetching and unfinalized block tracking.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch skip-block

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


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

@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: 1

🤖 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 `@packages/node/src/solana/block.solana.ts`:
- Around line 266-273: The formatBlockUtil function in solanaDictionaryV2.ts is
being called without providing the slot parameter, which prevents
solanaBlockToHeader from correctly calculating block heights when slots are
skipped. Locate the call to formatBlockUtil(parseBlock(...)) in
solanaDictionaryV2.ts and ensure the slot parameter is passed to formatBlockUtil
so that solanaBlockToHeader can properly determine the correct blockHeight
instead of incorrectly deriving it via parentSlot + 1 when prior slots are
skipped.
🪄 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: ea694e58-52ec-4017-9d2b-1fed6d4debd3

📥 Commits

Reviewing files that changed from the base of the PR and between ee90747 and f301b2b.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • packages/node/package.json
  • packages/node/src/indexer/unfinalizedBlocks.service.ts
  • packages/node/src/indexer/worker/worker.service.ts
  • packages/node/src/solana/api.solana.ts
  • packages/node/src/solana/block.solana.ts

Comment on lines 266 to 273
export function formatBlockUtil<B extends SolanaBlock = SolanaBlock>(
block: B,
slot?: number,
): IBlock<B> {
return {
block,
getHeader: () => solanaBlockToHeader(block),
getHeader: () => solanaBlockToHeader(block, slot),
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Skipped-slot correctness is still bypassed in one known call path.

solanaBlockToHeader is only correct on skipped slots when slot is propagated, but packages/node/src/indexer/dictionary/v2/solanaDictionaryV2.ts still calls formatBlockUtil(parseBlock(...)) without slot and then uses getHeader().blockHeight for lastBufferedHeight. That path can still derive incorrect heights via parentSlot + 1 when prior slots are skipped.

Also applies to: 281-283

🤖 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 `@packages/node/src/solana/block.solana.ts` around lines 266 - 273, The
formatBlockUtil function in solanaDictionaryV2.ts is being called without
providing the slot parameter, which prevents solanaBlockToHeader from correctly
calculating block heights when slots are skipped. Locate the call to
formatBlockUtil(parseBlock(...)) in solanaDictionaryV2.ts and ensure the slot
parameter is passed to formatBlockUtil so that solanaBlockToHeader can properly
determine the correct blockHeight instead of incorrectly deriving it via
parentSlot + 1 when prior slots are skipped.

ianhe8x added 2 commits June 18, 2026 10:26
…build-breaking expression

removeUnfinalizedBelowSafeHeight pruned records using a fixed distance
from the current head rather than the finalized height. When
finalization lags more than UNFINALIZED_THRESHOLD behind the head
(exactly the condition this service exists to guard against), it could
delete the only record hasForked() needed at or below the finalized
height, silently skipping fork detection. deleteFinalizedBlock already
prunes safely once a fork check has passed, so the extra pruning is
removed rather than re-targeted at finalizedBlockNumber.

Also fixes a build failure: api.solana.spec.ts and decoder.spec.ts had
`process.env.HTTP_ENDPOINT ?? '<literal>' ?? '<literal>'`, where the
second `??` is always non-nullish, making the third operand dead code.
The currently used TypeScript version flags this as an error
(TS2881), which broke @subql/node-solana's build.
Covers: forks behind missed slots, rebuilding the parent chain across
real and skipped slots, and rolling back when a backfilled or new
block doesn't connect to the expected parent.

@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.

🧹 Nitpick comments (2)
packages/node/src/solana/api.solana.spec.ts (2)

22-22: ⚡ Quick win

Clarify or update the API key comment.

The comment suggests an API key is required, but the endpoint on line 24 doesn't include one. If an API key should be added via process.env.HTTP_ENDPOINT, consider updating the comment to clarify this (e.g., "// Set HTTP_ENDPOINT env var with API key to avoid rate limits"). If no API key is needed for basic testing, consider removing the comment to avoid confusion.

🤖 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 `@packages/node/src/solana/api.solana.spec.ts` at line 22, Update the comment
on line 22 to clarify the actual approach for handling API keys. Either update
it to explain that an API key should be provided via the HTTP_ENDPOINT
environment variable (e.g., "Set HTTP_ENDPOINT env var with API key to avoid
rate limits"), or remove the comment entirely if no API key is required for
basic testing. Ensure the comment accurately reflects whether and how the
HTTP_ENDPOINT endpoint on the following line uses authentication.

23-24: Endpoint used for general block tests; verify if standardization across test files is needed.

This file's HTTP_ENDPOINT is used for general block and transaction parsing tests (e.g., fetching block 325922873), not for testing skipped-slot error handling. The codebase does use inconsistent endpoints across test files: api.solana.spec.ts and decoder.spec.ts use mainnet-beta, while blockchain.service.test.ts, api.service.solana.spec.ts, and solanaDictionaryV2.spec.ts use onfinality. If standardizing test endpoints is desired for maintainability, consider aligning them across all spec files.

🤖 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 `@packages/node/src/solana/api.solana.spec.ts` around lines 23 - 24, The
HTTP_ENDPOINT constant in this file uses mainnet-beta, but other test files
across the codebase use inconsistent endpoints (mainnet-beta in some files,
onfinality in others like blockchain.service.test.ts and
api.service.solana.spec.ts). Standardize the HTTP_ENDPOINT values by choosing a
single endpoint configuration and updating all test spec files
(api.solana.spec.ts, decoder.spec.ts, blockchain.service.test.ts,
api.service.solana.spec.ts, and solanaDictionaryV2.spec.ts) to use the same
endpoint value for consistency and maintainability across the test suite.
🤖 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.

Nitpick comments:
In `@packages/node/src/solana/api.solana.spec.ts`:
- Line 22: Update the comment on line 22 to clarify the actual approach for
handling API keys. Either update it to explain that an API key should be
provided via the HTTP_ENDPOINT environment variable (e.g., "Set HTTP_ENDPOINT
env var with API key to avoid rate limits"), or remove the comment entirely if
no API key is required for basic testing. Ensure the comment accurately reflects
whether and how the HTTP_ENDPOINT endpoint on the following line uses
authentication.
- Around line 23-24: The HTTP_ENDPOINT constant in this file uses mainnet-beta,
but other test files across the codebase use inconsistent endpoints
(mainnet-beta in some files, onfinality in others like
blockchain.service.test.ts and api.service.solana.spec.ts). Standardize the
HTTP_ENDPOINT values by choosing a single endpoint configuration and updating
all test spec files (api.solana.spec.ts, decoder.spec.ts,
blockchain.service.test.ts, api.service.solana.spec.ts, and
solanaDictionaryV2.spec.ts) to use the same endpoint value for consistency and
maintainability across the test suite.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74bf70b0-1e55-4dc2-8bbb-ba11af4200fb

📥 Commits

Reviewing files that changed from the base of the PR and between f301b2b and 82c99e9.

📒 Files selected for processing (4)
  • packages/node/src/indexer/unfinalizedBlocks.service.spec.ts
  • packages/node/src/indexer/unfinalizedBlocks.service.ts
  • packages/node/src/solana/api.solana.spec.ts
  • packages/node/src/solana/decoder.spec.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/node/src/solana/decoder.spec.ts

@ianhe8x ianhe8x merged commit 4fce726 into main Jun 17, 2026
2 of 3 checks passed
@ianhe8x ianhe8x deleted the skip-block branch June 17, 2026 22:46
@ianhe8x ianhe8x mentioned this pull request Jun 17, 2026
1 task
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