Skip to content

Fix Work Exec Result Kind#583

Merged
tomusdrw merged 3 commits intomainfrom
td-work-exec
Sep 5, 2025
Merged

Fix Work Exec Result Kind#583
tomusdrw merged 3 commits intomainfrom
td-work-exec

Conversation

@tomusdrw
Copy link
Copy Markdown
Member

@tomusdrw tomusdrw commented Sep 4, 2025

And some extra fixes for running conformance failed cases.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 4, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added new execution result statuses for invalid exports and oversized digests, improving diagnostics and compatibility with newer protocol versions.
  • Bug Fixes

    • Block loading is now resilient: invalid or unreadable block files are skipped without failing the process; genesis blocks continue to load reliably.
  • Tests

    • Updated state-transition tests to detect and assert rejected blocks with no state changes.
    • Switched state entries comparison to plain objects for clearer, more stable diffs in test outputs.

Walkthrough

Adds per-file try-catch to block loading, adjusts state-transition tests to detect and assert rejected blocks based on unchanged state roots, and updates WorkExecResultKind enum with version-gated variants and shifted discriminants. Also changes StateEntries test-comparison method to return a plain object from entries.

Changes

Cohort / File(s) Summary of changes
Test runner: state-transition flow
bin/test-runner/state-transition/state-transition.ts
Wraps per-file parsing in try-catch to skip bad blocks; maintains special handling for genesis. Introduces shouldBlockBeRejected when pre and post state roots match; asserts non-ok result and no state change, short-circuiting before other error-path logic.
Work results enum version-gating
packages/jam/block/work-result.ts
Adds enum members incorrectNumberOfExports and digestTooBig gated by GpVersion.V0_6_7. Shifts discriminants for badCode and codeOversize for newer versions. Imports Compatibility and GpVersion. No other runtime logic changed.
State entries test comparator
packages/jam/state-merkleization/state-entries.ts
[TEST_COMPARE_USING] now returns Object.fromEntries(this.entries) instead of the dictionary, altering the comparison representation to a plain object.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant TR as Test Runner
  participant BL as Block Loader
  participant ST as StateTransition

  rect rgba(230,245,255,0.6)
  note over BL: Load blocks
  TR->>BL: loadBlocks(files)
  loop for each file
    BL->>BL: try parse
    alt genesis.json
      BL-->>TR: StateTransitionGenesis.fromJson(...)
    else non-genesis
      BL-->>TR: StateTransition.fromJson(...)
    else parse error
      BL-->>TR: skip (ignored)
    end
  end
  end

  rect rgba(235,255,235,0.6)
  note over TR,ST: Execute state transition test
  TR->>ST: runStateTransition(pre, tx)
  ST-->>TR: result, post
  alt pre.state_root == post.state_root
    note over TR: shouldBlockBeRejected=true
    TR->>TR: assert !result.ok<br/>assert pre==post
    TR-->>TR: return
  else result.ok
    TR->>TR: assert success path
  else error path
    TR->>TR: assert error handling
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I nibbled through the code so neat,
Skipped bad blocks with dancer’s feet.
New enums hop by version signs,
Roots unchanged? Rejection lines.
Entries flattened, crisp and clear—
Thump! The tests all draw in near.
Another carrot-coded cheer! 🥕🐇


🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@tomusdrw tomusdrw marked this pull request as ready for review September 4, 2025 19:12
@tomusdrw tomusdrw requested a review from skoszuta September 4, 2025 19:12
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/jam/state-merkleization/state-entries.ts (1)

69-71: Avoid Object.fromEntries here: risk of proto-pollution and key-collision; return a Map of stringified keys instead.

Object.fromEntries() on non-string keys coerces them via toString and allows "proto" to mutate the prototype. For test comparisons, deepEqual already special-cases Map, so returning a Map<string, BytesBlob> is both safer and stable.

Apply this diff:

   /** When comparing, we can safely ignore `trieCache` and just use entries. */
   [TEST_COMPARE_USING]() {
-    return Object.fromEntries(this.entries);
+    // Use Map to avoid proto-pollution and preserve key semantics.
+    const mapped = new Map<string, BytesBlob>();
+    for (const [k, v] of this.entries) {
+      mapped.set(String(k), v);
+    }
+    return mapped;
   }

Alternative (if you must keep a plain object):

const out: Record<string, BytesBlob> = Object.create(null);
for (const [k, v] of this.entries) out[String(k)] = v;
return out;
bin/test-runner/state-transition/state-transition.ts (1)

134-141: Good early return on rejection; minor nit: assert on isError for clarity.

The block is properly asserted as rejected and state/root invariants are rechecked. Consider asserting stfResult.isError to be explicit.

Optional tweak:

-  assert.strictEqual(stfResult.isOk, false, "The block should be rejected, yet we imported it.");
+  assert.strictEqual(stfResult.isError, true, "The block should be rejected, yet we imported it.");
packages/jam/block/work-result.ts (1)

17-29: Consider using a MAX_KIND guard to future-proof the decoder bounds check.

Since codeOversize shifts with versions, a single source of truth for the maximum discriminant can improve readability and reduce mistakes if more variants arrive.

Example (no diff needed, just illustrating the pattern):

const MAX_KIND = Compatibility.selectIfGreaterOrEqual({
  fallback: WorkExecResultKind.codeOversize, // <0.6.7 -> 4
  versions: { [GpVersion.V0_6_7]: WorkExecResultKind.codeOversize }, // >=0.6.7 -> 6
});
// In decoder:
if (kind > MAX_KIND) throw new Error(`Invalid WorkExecResultKind: ${kind}`);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Lite

📥 Commits

Reviewing files that changed from the base of the PR and between 748f689 and fcffb1a.

📒 Files selected for processing (3)
  • bin/test-runner/state-transition/state-transition.ts (2 hunks)
  • packages/jam/block/work-result.ts (2 hunks)
  • packages/jam/state-merkleization/state-entries.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.ts

⚙️ CodeRabbit configuration file

**/*.ts: as conversions must not be used. Suggest using tryAs conversion methods.

**/*.ts: Classes with static Codec field must have private constructor and static create method.

**/*.ts: Casting a bigint (or U64) using Number(x) must have an explanation comment why
it is safe.

**/*.ts: When making changes to code with comments containing links (in classes, constants, methods, etc.)
to graypaper.fluffylabs.dev, ensure those links point to the current version for this update.

Files:

  • bin/test-runner/state-transition/state-transition.ts
  • packages/jam/state-merkleization/state-entries.ts
  • packages/jam/block/work-result.ts
🧠 Learnings (2)
📚 Learning: 2025-06-10T12:06:32.535Z
Learnt from: tomusdrw
PR: FluffyLabs/typeberry#419
File: packages/jam/database-lmdb/states.test.ts:158-160
Timestamp: 2025-06-10T12:06:32.535Z
Learning: In test code, tomusdrw prefers pragmatic solutions over strict type safety when listing all entries would be cumbersome. Using `Object.assign({}, state)` for state updates in tests is acceptable even if it compromises type safety, prioritizing test maintainability and readability.

Applied to files:

  • packages/jam/state-merkleization/state-entries.ts
📚 Learning: 2025-06-10T12:20:17.513Z
Learnt from: tomusdrw
PR: FluffyLabs/typeberry#419
File: packages/jam/state/state-inmemory.ts:141-149
Timestamp: 2025-06-10T12:20:17.513Z
Learning: In the `InMemoryService.copyFrom` function in `packages/jam/state/state-inmemory.ts`, duplicate checking for `(hash, length)` pairs in the lookup history is not necessary because the function operates under the assumption that the input `ServiceEntries` comes from an existing well-formed state, which already maintains the invariant of unique lookup history entries per hash and length combination.

Applied to files:

  • packages/jam/state-merkleization/state-entries.ts
🧬 Code graph analysis (2)
bin/test-runner/state-transition/state-transition.ts (5)
packages/core/json-parser/parse.ts (1)
  • parseFromJson (6-140)
packages/jam/block/block.ts (1)
  • Block (70-88)
packages/jam/node/common.ts (1)
  • emptyBlock (111-126)
packages/jam/transition/block-verifier.ts (1)
  • BlockVerifier (19-90)
packages/core/utils/test.ts (1)
  • deepEqual (41-187)
packages/jam/block/work-result.ts (1)
packages/core/utils/compatibility.ts (1)
  • Compatibility (55-111)
🔇 Additional comments (2)
bin/test-runner/state-transition/state-transition.ts (1)

125-125: LGTM: clear early-reject signal derived from unchanged state roots.

Simple and robust heuristic; fits the conformance intent.

packages/jam/block/work-result.ts (1)

17-29: Drop import-order concern: Compatibility.override is only invoked in tests, so in production the enum discriminants use DEFAULT_VERSION (from process.env) at module load—import order won’t affect them.

Likely an incorrect or invalid review comment.

Comment thread bin/test-runner/state-transition/state-transition.ts
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 5, 2025

View all
File Benchmark Ops
collections/map-set.ts[0] 2 gets + conditional set 70325.25 ±0.23% fastest ✅
collections/map-set.ts[1] 1 get 1 set 41509.2 ±0.28% 40.98% slower
codec/decoding.ts[0] manual decode 22517878.81 ±0.8% 88.01% slower
codec/decoding.ts[1] int32array decode 187747344.82 ±4.88% fastest ✅
codec/decoding.ts[2] dataview decode 180709184.84 ±4.47% 3.75% slower
codec/encoding.ts[0] manual encode 2846722.28 ±1.7% 21.24% slower
codec/encoding.ts[1] int32array encode 3302342.27 ±1.37% 8.64% slower
codec/encoding.ts[2] dataview encode 3614625.7 ±1.47% fastest ✅
bytes/hex-from.ts[0] parse hex using Number with NaN checking 125748.75 ±1.05% 83.72% slower
bytes/hex-from.ts[1] parse hex from char codes 772625.12 ±1.16% fastest ✅
bytes/hex-from.ts[2] parse hex from string nibbles 461494.93 ±1.16% 40.27% slower
bytes/hex-to.ts[0] number toString + padding 260525.23 ±1.02% fastest ✅
bytes/hex-to.ts[1] manual 12877.99 ±1.74% 95.06% slower
codec/bigint.compare.ts[0] compare custom 199582550.66 ±7.49% 3.15% slower
codec/bigint.compare.ts[1] compare bigint 206067489.92 ±6.97% fastest ✅
codec/bigint.decode.ts[0] decode custom 169560222.47 ±4.62% fastest ✅
codec/bigint.decode.ts[1] decode bigint 66556332 ±8.95% 60.75% slower
hash/index.ts[0] hash with numeric representation 158.7 ±1.04% 20.8% slower
hash/index.ts[1] hash with string representation 101.13 ±1.09% 49.53% slower
hash/index.ts[2] hash with symbol representation 145.63 ±0.86% 27.32% slower
hash/index.ts[3] hash with uint8 representation 130.82 ±0.96% 34.71% slower
hash/index.ts[4] hash with packed representation 200.38 ±1.02% fastest ✅
hash/index.ts[5] hash with bigint representation 135.52 ±0.86% 32.37% slower
hash/index.ts[6] hash with uint32 representation 168.16 ±0.31% 16.08% slower
logger/index.ts[0] console.log with string concat 6283974.45 ±55.23% fastest ✅
logger/index.ts[1] console.log with args 1419061 ±102.12% 77.42% slower
math/add_one_overflow.ts[0] add and take modulus 221907494.74 ±5.85% 13.41% slower
math/add_one_overflow.ts[1] condition before calculation 256266294.6 ±6.14% fastest ✅
math/count-bits-u32.ts[0] standard method 74335548.64 ±2.37% 67.68% slower
math/count-bits-u32.ts[1] magic 230016472.14 ±5.86% fastest ✅
math/count-bits-u64.ts[0] standard method 944588.88 ±2.92% 85.59% slower
math/count-bits-u64.ts[1] magic 6556786.75 ±6.16% fastest ✅
math/mul_overflow.ts[0] multiply and bring back to u32 258815563.13 ±5.04% fastest ✅
math/mul_overflow.ts[1] multiply and take modulus 244884640.76 ±6.59% 5.38% slower
math/switch.ts[0] switch 235915372.03 ±8.25% fastest ✅
math/switch.ts[1] if 221369686.09 ±8.37% 6.17% slower
codec/view_vs_collection.ts[0] Get first element from Decoded 23658.09 ±4.04% 63.32% slower
codec/view_vs_collection.ts[1] Get first element from View 64491.84 ±1.67% fastest ✅
codec/view_vs_collection.ts[2] Get 50th element from Decoded 21537.37 ±3.12% 66.6% slower
codec/view_vs_collection.ts[3] Get 50th element from View 29275.66 ±2.11% 54.61% slower
codec/view_vs_collection.ts[4] Get last element from Decoded 20091.39 ±2.2% 68.85% slower
codec/view_vs_collection.ts[5] Get last element from View 17058.84 ±1.82% 73.55% slower
codec/view_vs_object.ts[0] Get the first field from Decoded 304276.14 ±2.8% 25.43% slower
codec/view_vs_object.ts[1] Get the first field from View 82388.92 ±2.11% 79.81% slower
codec/view_vs_object.ts[2] Get the first field as view from View 95705.3 ±1.29% 76.55% slower
codec/view_vs_object.ts[3] Get two fields from Decoded 408059.98 ±1.04% fastest ✅
codec/view_vs_object.ts[4] Get two fields from View 60228.33 ±2.64% 85.24% slower
codec/view_vs_object.ts[5] Get two fields from materialized from View 107850.64 ±4.47% 73.57% slower
codec/view_vs_object.ts[6] Get two fields as views from View 54250.76 ±1.92% 86.71% slower
codec/view_vs_object.ts[7] Get only third field from Decoded 286085.7 ±1.71% 29.89% slower
codec/view_vs_object.ts[8] Get only third field from View 67961.8 ±1.3% 83.35% slower
codec/view_vs_object.ts[9] Get only third field as view from View 74677.53 ±0.86% 81.7% slower
bytes/compare.ts[0] Comparing Uint32 bytes 16000.51 ±4.21% fastest ✅
bytes/compare.ts[1] Comparing raw bytes 12677.7 ±4.44% 20.77% slower
hash/blake2b.ts[0] hasher with simple allocator 0.0409 ±5.94% 0.49% slower
hash/blake2b.ts[1] hasher with page allocator 0.0411 ±6.25% fastest ✅
collections/map_vs_sorted.ts[0] Map 205333.78 ±1.82% fastest ✅
collections/map_vs_sorted.ts[1] Map-array 100239.2 ±0.33% 51.18% slower
collections/map_vs_sorted.ts[2] Array 60052.29 ±2.25% 70.75% slower
collections/map_vs_sorted.ts[3] SortedArray 190401.02 ±0.61% 7.27% slower
crypto/ed25519.ts[0] native crypto 5.42 ±16.77% 79.59% slower
crypto/ed25519.ts[1] wasm lib 9.01 ±3.29% 66.08% slower
crypto/ed25519.ts[2] wasm lib batch 26.56 ±2.77% fastest ✅

Benchmarks summary: 63/63 OK ✅

Copy link
Copy Markdown
Contributor

@skoszuta skoszuta left a comment

Choose a reason for hiding this comment

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

:shipit:

@tomusdrw tomusdrw merged commit 2341f48 into main Sep 5, 2025
12 checks passed
@tomusdrw tomusdrw deleted the td-work-exec branch September 5, 2025 08:07
@coderabbitai coderabbitai Bot mentioned this pull request Jan 9, 2026
6 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Jan 29, 2026
3 tasks
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.

3 participants