Skip to content

Offline networking worker#1026

Open
tomusdrw wants to merge 1 commit into
mainfrom
td-mock-networking-worker
Open

Offline networking worker#1026
tomusdrw wants to merge 1 commit into
mainfrom
td-mock-networking-worker

Conversation

@tomusdrw

Copy link
Copy Markdown
Member

No description provided.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a browser-safe crypto entry point and updates JAM block imports to use it. Introduces the @typeberry/networking-offline package, shared networking messages, an offline controller, lifecycle handling, and end-to-end tests. Replaces the listener emitter with typed eventemitter3 events, adjusts deferred callbacks, and adds related tests. Package exports, workspace configuration, documentation, and examples are updated.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: mateuszsikora

Poem

I’m a rabbit with packets tucked neat,
Browser-safe bytes make the bundle complete.
Blocks hop in and headers hop out,
Tickets announce what tests sing about.
When finish arrives, I wiggle my nose—
The offline network gently dozes.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No author description was provided, so the PR intent isn't described in a meaningful way. Add a brief PR description summarizing the new offline networking worker, its exports, and key behavior changes.
✅ Passed checks (3 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding an offline networking worker.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch td-mock-networking-worker

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 `@bin/lib/README.md`:
- Around line 123-134: Make the README example self-contained by replacing the
two assert.strictEqual calls around importedBlocks and announcedHeader with
explicit browser-safe equality checks, or define an appropriate assertion
dependency within the example. Preserve both validations: each value must equal
the expected block or header.

In `@packages/core/crypto/browser.test.ts`:
- Around line 1-2: Replace the node:assert and node:test imports in
browser.test.ts with the repository’s runtime-neutral test and assertion
utilities. Keep the test compatible with both Node and web runtimes without
renaming it or introducing separate runtime-specific files.

In `@packages/core/crypto/README.md`:
- Around line 6-10: Update the description of the `@typeberry/crypto/browser.js`
entry point to say it is for code that only needs the sizes of encoded
keys/signatures, leaving the surrounding documentation unchanged.

In `@packages/core/listener/index.test.ts`:
- Around line 1-2: Make the test files runtime-neutral by replacing the
Node-only imports in packages/core/listener/index.test.ts (lines 1-2),
packages/jam/networking-offline/index.test.ts (lines 1-2), and
bin/lib/examples/networking-offline.test.ts (lines 1-2) with the repository’s
browser-compatible test and assertion utilities. Keep each file named *.test.ts
so it remains compatible with both Node and web environments; do not rename them
to a Node-only convention.

In `@packages/jam/networking-offline/index.ts`:
- Around line 88-90: Replace assertActive’s exception-based inactive-state
handling with the repository’s Result/tagged-union convention, and update
submitBlock, submitBlocks, and submitTickets to return the tagged lifecycle
failure through their promise results. Adjust the related test to assert the
Result variant rather than a message-specific rejected Error, while preserving
successful active-state behavior.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a5457743-8d8d-4afe-b4e7-71e18b0f8a98

📥 Commits

Reviewing files that changed from the base of the PR and between 9d838d3 and 30a4c24.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • bin/lib/README.md
  • bin/lib/examples/networking-offline.test.ts
  • bin/lib/exports/crypto-browser.ts
  • bin/lib/exports/networking-offline.ts
  • bin/lib/index.ts
  • bin/lib/package.json
  • package.json
  • packages/core/crypto/README.md
  • packages/core/crypto/browser.test.ts
  • packages/core/crypto/browser.ts
  • packages/core/listener/index.test.ts
  • packages/core/listener/index.ts
  • packages/core/listener/package.json
  • packages/core/utils/test.ts
  • packages/jam/block/assurances.ts
  • packages/jam/block/disputes.ts
  • packages/jam/block/guarantees.ts
  • packages/jam/block/header.ts
  • packages/jam/block/tickets.ts
  • packages/jam/networking-offline/README.md
  • packages/jam/networking-offline/index.test.ts
  • packages/jam/networking-offline/index.ts
  • packages/jam/networking-offline/package.json
  • packages/workers/api/channel.ts
  • packages/workers/comms-authorship-network/protocol.ts
  • packages/workers/comms-authorship-network/tickets-message.ts
  • packages/workers/jam-network/messages.ts
  • packages/workers/jam-network/protocol.ts

Comment thread bin/lib/README.md
Comment on lines +123 to +134
const block = reencodeAsView(Block.Codec, emptyBlock(), tinyChainSpec);
await worker.offline.submitBlock(block);
assert.strictEqual(importedBlocks[0], block);

// Outgoing online-network announcements are observable programmatically.
let announcedHeader: unknown = null;
worker.offline.announcedHeaders.once((header) => {
announcedHeader = header;
});
const header = WithHash.new(Bytes.zero(HASH_SIZE).asOpaque<HeaderHash>(), block.header.view());
await worker.network.sendNewHeader(header);
assert.strictEqual(announcedHeader, header);

Copy link
Copy Markdown
Contributor

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

Make the README example self-contained.

Lines [125] and [134] call assert.strictEqual, but this snippet never imports or defines assert, and browsers do not provide it globally. Use explicit checks or add an environment-appropriate assertion import.

Proposed browser-safe replacement
-assert.strictEqual(importedBlocks[0], block);
+if (importedBlocks[0] !== block) {
+  throw new Error("Offline networking did not deliver the block");
+}
...
-assert.strictEqual(announcedHeader, header);
+if (announcedHeader !== header) {
+  throw new Error("Header announcement was not observed");
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const block = reencodeAsView(Block.Codec, emptyBlock(), tinyChainSpec);
await worker.offline.submitBlock(block);
assert.strictEqual(importedBlocks[0], block);
// Outgoing online-network announcements are observable programmatically.
let announcedHeader: unknown = null;
worker.offline.announcedHeaders.once((header) => {
announcedHeader = header;
});
const header = WithHash.new(Bytes.zero(HASH_SIZE).asOpaque<HeaderHash>(), block.header.view());
await worker.network.sendNewHeader(header);
assert.strictEqual(announcedHeader, header);
const block = reencodeAsView(Block.Codec, emptyBlock(), tinyChainSpec);
await worker.offline.submitBlock(block);
if (importedBlocks[0] !== block) {
throw new Error("Offline networking did not deliver the block");
}
// Outgoing online-network announcements are observable programmatically.
let announcedHeader: unknown = null;
worker.offline.announcedHeaders.once((header) => {
announcedHeader = header;
});
const header = WithHash.new(Bytes.zero(HASH_SIZE).asOpaque<HeaderHash>(), block.header.view());
await worker.network.sendNewHeader(header);
if (announcedHeader !== header) {
throw new Error("Header announcement was not observed");
}
🤖 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 `@bin/lib/README.md` around lines 123 - 134, Make the README example
self-contained by replacing the two assert.strictEqual calls around
importedBlocks and announcedHeader with explicit browser-safe equality checks,
or define an appropriate assertion dependency within the example. Preserve both
validations: each value must equal the expected block or header.

Comment on lines +1 to +2
import assert from "node:assert";
import { describe, it } from "node:test";

Copy link
Copy Markdown
Contributor

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

Keep this shared test runtime-neutral.

node:assert and node:test make browser.test.ts Node-only. Use the repository’s cross-runtime test/assertion utilities, or split this into explicit Node and web test files.

As per path instructions, *.test.ts files must remain compatible with both Node and web unless they use an explicit *.node.ts / *.web.ts convention.

🤖 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/core/crypto/browser.test.ts` around lines 1 - 2, Replace the
node:assert and node:test imports in browser.test.ts with the repository’s
runtime-neutral test and assertion utilities. Keep the test compatible with both
Node and web runtimes without renaming it or introducing separate
runtime-specific files.

Source: Path instructions

Comment on lines +6 to +10
`@typeberry/crypto/browser.js` is the dependency-light entry point for code
which only needs encoded key/signature sizes and their opaque TypeScript types.
It has no runtime imports and does not expose cryptographic operations. Its
constants intentionally mirror the canonical values in `ed25519.ts` and
`bandersnatch.ts`; their literal type annotations and unit test catch drift.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Clarify the encoded-size wording.

Replace “only needs encoded key/signature sizes” with “only needs the sizes of encoded keys/signatures” to avoid ambiguity.

🧰 Tools
🪛 LanguageTool

[style] ~7-~7: The double modal “needs encoded” is nonstandard (only accepted in certain dialects). Consider “to be encoded”.
Context: ...t entry point for code which only needs encoded key/signature sizes and their opaque Ty...

(NEEDS_FIXED)

🤖 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/core/crypto/README.md` around lines 6 - 10, Update the description
of the `@typeberry/crypto/browser.js` entry point to say it is for code that only
needs the sizes of encoded keys/signatures, leaving the surrounding
documentation unchanged.

Source: Linters/SAST tools

Comment on lines +1 to +2
import assert from "node:assert";
import { describe, it } from "node:test";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Make the new generic test files runtime-neutral.

These *.test.ts files import Node-only node:test and node:assert, so they cannot run in the required web environment. Use the repository’s browser-compatible test/assertion pattern, or explicitly designate each test as Node-only if that is intentional.

  • packages/core/listener/index.test.ts#L1-L2: replace Node-only test/assertion imports or rename to the explicit Node-only convention.
  • packages/jam/networking-offline/index.test.ts#L1-L2: replace Node-only test/assertion imports or rename to the explicit Node-only convention.
  • bin/lib/examples/networking-offline.test.ts#L1-L2: replace Node-only test/assertion imports or rename to the explicit Node-only convention.

As per path instructions, “Treat *.test.ts as test files and keep them compatible with both Node and web unless the file has an explicit *.node.ts / *.web.ts convention.”

📍 Affects 3 files
  • packages/core/listener/index.test.ts#L1-L2 (this comment)
  • packages/jam/networking-offline/index.test.ts#L1-L2
  • bin/lib/examples/networking-offline.test.ts#L1-L2
🤖 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/core/listener/index.test.ts` around lines 1 - 2, Make the test files
runtime-neutral by replacing the Node-only imports in
packages/core/listener/index.test.ts (lines 1-2),
packages/jam/networking-offline/index.test.ts (lines 1-2), and
bin/lib/examples/networking-offline.test.ts (lines 1-2) with the repository’s
browser-compatible test and assertion utilities. Keep each file named *.test.ts
so it remains compatible with both Node and web environments; do not rename them
to a Node-only convention.

Source: Path instructions

Comment on lines +88 to +90
private assertActive(): void {
if (this.isFinished) {
throw new Error("Offline networking has finished");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Return a tagged lifecycle result instead of throwing.

submitBlock, submitBlocks, and submitTickets expose the finished-state failure as a rejected promise with a message-specific Error; the test also binds callers to that exception contract. Model the inactive state with the repository’s Result/tagged-union convention instead.

As per path instructions, “Use Result/tagged unions for error handling; avoid relying on specific thrown exceptions.”

🤖 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/jam/networking-offline/index.ts` around lines 88 - 90, Replace
assertActive’s exception-based inactive-state handling with the repository’s
Result/tagged-union convention, and update submitBlock, submitBlocks, and
submitTickets to return the tagged lifecycle failure through their promise
results. Adjust the related test to assert the Result variant rather than a
message-specific rejected Error, while preserving successful active-state
behavior.

Source: Path instructions

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