Skip to content

Authorization checking#940

Open
tomusdrw wants to merge 6 commits intomainfrom
td-authorize-package
Open

Authorization checking#940
tomusdrw wants to merge 6 commits intomainfrom
td-authorize-package

Conversation

@tomusdrw
Copy link
Copy Markdown
Member

@tomusdrw tomusdrw commented Apr 7, 2026

Related: #694

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 7, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added a dedicated authorization check step and a standalone per-item refinement executor to handle authorization and refinement flows.
  • Refactoring
    • Internal authorization fields and work-package handling renamed for clarity; authorization/refinement responsibilities moved into separate components.
  • Tests
    • Added comprehensive authorization tests and placeholder/refine tests.
  • Behavior
    • Fetch APIs now return empty payloads instead of nullable values, reducing null-handling in host-call flows.

Walkthrough

This PR splits authorization and refinement into distinct components: adds IsAuthorized and Refine modules that run PVM invocations for package authorization and per-item refinement. WorkPackage fields authorization and parametrization were renamed to authToken and authConfiguration and remapped across codecs, constructors, tests, and externalities. PvmExecutor gained factories and host-call wiring for the is-authorized flow. Fetch host-call interfaces and transition externalities were renamed and changed to return non-null BytesBlob. InCore was refactored to delegate to the new collaborators and re-export refine-related types.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Initial refine #859: Implements splitting refine/is-authorized, adds IsAuthorized and Refine executors and externalities, and renames authorization fields.
  • Fetch Refactor #934: Continues fetch refactor and adds IIsAuthorizedFetch / IsAuthorizedFetchExternalities and PvmExecutor wiring for is-authorized.
  • Fetch host call #390: Modifies Fetch host-call surface and FetchKind renames which overlap with this PR's fetch interface changes.

Suggested reviewers

  • mateuszsikora
  • DrEverr
  • skoszuta

Poem

🐇 I hopped through bytes with a curious cheer,
Swapped tokens and configs so the paths are clear,
IsAuthorized sang, Refine tuned each part,
Executors marched and tests played their part,
A tiny rabbit hops — the pipeline’s near! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Authorization checking' directly relates to the main change: implementing authorization validation logic via a new IsAuthorized module and refactoring work package authorization fields.
Description check ✅ Passed The description 'Related: #694' references an issue, providing context that connects this PR to tracked work on authorization features.

✏️ 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 td-authorize-package

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

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: 5

🧹 Nitpick comments (3)
packages/jam/in-core/refine.test.ts (1)

1-7: Placeholder test file noted.

The TODO comment clearly documents the intent to add Refine.invoke() tests following the is-authorized.test.ts pattern. Consider tracking this with an issue to ensure follow-up.

Would you like me to open an issue to track adding the refine-specific PVM invocation tests?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/in-core/refine.test.ts` around lines 1 - 7, Create a tracked
issue to add refine-specific PVM invocation tests for Refine.invoke(),
referencing the existing is-authorized.test.ts pattern; the issue should state
that tests should call Refine.invoke() directly, specify expected behaviors and
edge cases to cover, and link to this placeholder test so someone can pick it up
later.
packages/jam/in-core/is-authorized.test.ts (1)

28-48: Consider extracting createService to a shared test utility.

This helper is nearly identical to the one in in-core.test.ts (lines 35-55). Extracting to a shared test utility would reduce duplication and ensure consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/in-core/is-authorized.test.ts` around lines 28 - 48, The
duplicate createService helper should be extracted to a shared test utility:
move the createService implementation (which constructs an InMemoryService using
ServiceAccountInfo.create, PreimageItem.create, HashDictionary.fromEntries,
etc.) into a new exported test helper module, export any dependent types or
helper functions (e.g., OpaqueHash/BytesBlob typings if needed), and replace the
local copies in both in-core.test.ts and is-authorized.test.ts with imports from
that shared module; ensure the new module exports the same function signature so
tests using createService (and references to InMemoryService, codeHash, code)
need only import it and all existing calls continue to work.
packages/jam/transition/externalities/is-authorized-fetch-externalities.ts (1)

7-53: Implementation correctly provides auth fields; stub methods are safe placeholders.

The class properly implements the essential auth-related methods (authToken(), authConfiguration(), constants()). The stub methods returning BytesBlob.empty() or null are safe per the getValue() implementation in fetch.ts (Context snippet 1), which handles these return values without panic.

The TODOs clearly document future work needed for full fetch support during authorization.

Would you like me to open issues to track implementing the stubbed methods (workPackage, refineContext, allWorkItems, oneWorkItem, workItemPayload)?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/transition/externalities/is-authorized-fetch-externalities.ts`
around lines 7 - 53, Summary: IsAuthorizedFetchExternalities implements auth
fields but leaves several methods as safe stubs. Fix: keep current behavior but
create tracking issues (or TODOs in your tracker) to implement the stubbed
methods: workPackage(), refineContext(), allWorkItems(), oneWorkItem(U64), and
workItemPayload(U64) on the IsAuthorizedFetchExternalities class so they return
the correct encoded values (E(p) for workPackage, encoded refinement context,
encoded work items list, single work item summary, and work item payload
respectively); include acceptance criteria in each issue that references these
method names and requires returning non-empty BytesBlob or a valid
BytesBlob|null consistent with fetch.getValue() expectations and add unit tests
covering each implemented method.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/jam/in-core/is-authorized.ts`:
- Around line 44-51: The invoke function currently only accepts
authToken/authConfiguration and forwards those into
IsAuthorizedFetchExternalities, dropping the encoded work package, refine
context, and work-item summaries/payloads; update the IsAuthorized.invoke
signature to also accept workPackage, context, and items (the encoded work
package, refine context, and work-item list) and pass those through into
IsAuthorizedFetchExternalities so FETCH handlers see the real package contents
(also apply the same change where invoke is declared/used around lines 80-83).
Locate the invoke method and any callers, add parameters for the work package,
context, and items, and ensure IsAuthorizedFetchExternalities is
constructed/called with these values instead of only token/configuration.

In `@packages/jam/in-core/refine.ts`:
- Around line 15-16: The cycle is caused by refine.ts importing types
(ImportedSegment, PerWorkItem, RefineItemResult) from in-core.ts while
in-core.ts imports Refine from refine.ts; break it by extracting those three
type definitions into a new module (e.g., in-core-types.ts or refine-types.ts)
and have both refine.ts and in-core.ts import the types from that new file;
update imports in RefineExternalitiesImpl (refine.ts) and wherever in-core.ts
referenced those types to point to the new module and remove the direct import
of in-core.ts from refine.ts.
- Around line 53-63: The invoke() path currently drops per-item data when
constructing RefineFetchExternalities so item-dependent host calls
(payload/imports/extrinsics/work-item fetches) have no backing data; update
invoke() and createRefineExternalities() to accept and pass the current item’s
payload, imports (allImports[idx]), and extrinsics (allExtrinsics[idx]) into the
RefineFetchExternalities constructor, and modify RefineFetchExternalities to
store and use those per-item values when servicing import/extrinsic and
work-item fetch kinds (ensure the work-item payload/summary source is passed
through and used by the fetch handlers).
- Around line 121-135: The branch that handles the incorrect number of exports
returns the actual exports array, which later gets used to advance exportOffset;
change the return so it discards the exports when the counts mismatch (i.e.,
return an empty array instead of the value from
externalities.refine.getExportedSegments()) — update the block that checks
exports.length !== item.exportCount (where exports is from
externalities.refine.getExportedSegments()) to return exports: [] while keeping
the existing WorkResult.create(...) and WorkRefineLoad.create(...) payload
(exportedSegments should remain 0).

In `@packages/jam/transition/externalities/refine-fetch-externalities.ts`:
- Around line 23-26: The unimplemented refine-fetch methods (e.g.,
authorizerTrace) currently return BytesBlob.empty(), which makes the runtime
treat them as successful zero-length fetches; change each unimplemented method
(authorizerTrace, packageTrace, packageKey, packageProof, authorizerKey,
authorizerProof, contextTrace — the methods in refine-fetch-externalities.ts
around the shown snippet) to return null/HostCallResult.NONE instead of
BytesBlob.empty(), and update their return types to allow null (e.g., BytesBlob
| null) so Fetch.execute() sees a genuine "no result" rather than a synthetic
empty blob.

---

Nitpick comments:
In `@packages/jam/in-core/is-authorized.test.ts`:
- Around line 28-48: The duplicate createService helper should be extracted to a
shared test utility: move the createService implementation (which constructs an
InMemoryService using ServiceAccountInfo.create, PreimageItem.create,
HashDictionary.fromEntries, etc.) into a new exported test helper module, export
any dependent types or helper functions (e.g., OpaqueHash/BytesBlob typings if
needed), and replace the local copies in both in-core.test.ts and
is-authorized.test.ts with imports from that shared module; ensure the new
module exports the same function signature so tests using createService (and
references to InMemoryService, codeHash, code) need only import it and all
existing calls continue to work.

In `@packages/jam/in-core/refine.test.ts`:
- Around line 1-7: Create a tracked issue to add refine-specific PVM invocation
tests for Refine.invoke(), referencing the existing is-authorized.test.ts
pattern; the issue should state that tests should call Refine.invoke() directly,
specify expected behaviors and edge cases to cover, and link to this placeholder
test so someone can pick it up later.

In `@packages/jam/transition/externalities/is-authorized-fetch-externalities.ts`:
- Around line 7-53: Summary: IsAuthorizedFetchExternalities implements auth
fields but leaves several methods as safe stubs. Fix: keep current behavior but
create tracking issues (or TODOs in your tracker) to implement the stubbed
methods: workPackage(), refineContext(), allWorkItems(), oneWorkItem(U64), and
workItemPayload(U64) on the IsAuthorizedFetchExternalities class so they return
the correct encoded values (E(p) for workPackage, encoded refinement context,
encoded work items list, single work item summary, and work item payload
respectively); include acceptance criteria in each issue that references these
method names and requires returning non-empty BytesBlob or a valid
BytesBlob|null consistent with fetch.getValue() expectations and add unit tests
covering each implemented method.
🪄 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: c255ebad-cbee-4b1c-be77-b0883dc103af

📥 Commits

Reviewing files that changed from the base of the PR and between 9567cee and 842f693.

📒 Files selected for processing (15)
  • bin/test-runner/w3f/codec/work-package.ts
  • packages/jam/block/work-package.ts
  • packages/jam/executor/pvm-executor.ts
  • packages/jam/in-core/fixtures/authorizer.pvm
  • packages/jam/in-core/in-core.test.ts
  • packages/jam/in-core/in-core.ts
  • packages/jam/in-core/is-authorized.test.ts
  • packages/jam/in-core/is-authorized.ts
  • packages/jam/in-core/refine.test.ts
  • packages/jam/in-core/refine.ts
  • packages/jam/jam-host-calls/general/fetch.test.ts
  • packages/jam/jam-host-calls/general/fetch.ts
  • packages/jam/transition/externalities/index.ts
  • packages/jam/transition/externalities/is-authorized-fetch-externalities.ts
  • packages/jam/transition/externalities/refine-fetch-externalities.ts

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.

♻️ Duplicate comments (2)
packages/jam/in-core/refine.ts (2)

120-127: ⚠️ Potential issue | 🔴 Critical

Per-item fetch data is still not wired into refine externalities.

payload, imports, and extrinsics are collected but not used to back fetch host calls; RefineFetchExternalities is still created with only chainSpec. Item-dependent fetches will not resolve correctly.

🐛 Minimal direction to fix
-    const externalities = this.createRefineExternalities({
-      payload: item.payload,
-      imports: allImports,
-      extrinsics: allExtrinsics,
+    const externalities = this.createRefineExternalities({
+      payload: item.payload,
+      imports,
+      extrinsics,
       currentServiceId: item.service,
       lookupState,
       exportOffset,
     });

   private createRefineExternalities(args: {
     payload: BytesBlob;
-    imports: PerWorkItem<ImportedSegment[]>;
-    extrinsics: PerWorkItem<WorkItemExtrinsic[]>;
+    imports: ImportedSegment[];
+    extrinsics: WorkItemExtrinsic[];
     currentServiceId: ServiceId;
     lookupState: State;
     exportOffset: number;
   }): RefineHostCallExternalities {
-    const fetchExternalities = new RefineFetchExternalities(this.chainSpec);
+    const fetchExternalities = new RefineFetchExternalities(
+      this.chainSpec,
+      args.payload,
+      args.imports,
+      args.extrinsics,
+    );

(plus corresponding constructor/handler support in packages/jam/transition/externalities/refine-fetch-externalities.ts)

Also applies to: 231-241

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/in-core/refine.ts` around lines 120 - 127, The
createRefineExternalities call is only passing chainSpec and thus per-item fetch
data (payload, imports, extrinsics, currentServiceId, exportOffset, lookupState)
never reaches RefineFetchExternalities; update createRefineExternalities
invocation (and the RefineFetchExternalities constructor/handler in
packages/jam/transition/externalities/refine-fetch-externalities.ts) to accept
and store the item-specific fields (payload, imports, extrinsics,
currentServiceId, exportOffset, lookupState) so that fetch host calls inside
RefineFetchExternalities use the item-scoped data when resolving fetches.

141-145: ⚠️ Potential issue | 🟠 Major

Discard exports when export count validation fails.

When exports.length !== item.exportCount, returning exports leaks invalid segments into downstream offset/count aggregation.

✅ Minimal fix
     if (exports.length !== item.exportCount) {
       return {
-        exports,
+        exports: [],
         result: WorkResult.create({
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/in-core/refine.ts` around lines 141 - 145, The current branch
returns the captured exports when exports.length !== item.exportCount which
leaks invalid segments; change the early-return path in refine (the block that
calls externalities.refine.getExportedSegments() and compares exports.length to
item.exportCount) to discard the exported segments—return an empty exports array
(or omit the exports field) alongside the WorkResult.create(...) instead of
returning the collected exports so downstream offset/count aggregation does not
receive invalid segments.
🧹 Nitpick comments (2)
packages/jam/in-core/in-core.ts (1)

42-50: Prefer a private constructor + static factory for collaborator wiring.

InCore is an updated module in this PR, and the constructor now contains composition logic. Please move creation to a static factory (create(...)) and keep constructor private.

♻️ Suggested refactor
 export class InCore {
   private readonly isAuthorized: IsAuthorized;
   private readonly refineItem: Refine;

-  constructor(
+  static create(
+    chainSpec: ChainSpec,
+    states: StatesDb,
+    pvmBackend: PvmBackend,
+    blake2b: Blake2b,
+  ) {
+    return new InCore(chainSpec, states, pvmBackend, blake2b);
+  }
+
+  private constructor(
     public readonly chainSpec: ChainSpec,
     private readonly states: StatesDb,
     pvmBackend: PvmBackend,
     blake2b: Blake2b,
   ) {

As per coding guidelines, “Prefer Rust-style static builder methods and keep constructors private; avoid constructor overloading.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/in-core/in-core.ts` around lines 42 - 50, The InCore constructor
currently performs collaborator wiring (instantiating IsAuthorized and Refine);
change this by making the class constructor private and moving the wiring into a
static async/sync factory method named create(chainSpec, states, pvmBackend,
blake2b) which returns a new InCore instance; ensure create constructs
IsAuthorized and Refine (using the same parameters) and assigns them to the
instance before returning, while the private constructor only accepts
already-initialized dependencies (chainSpec, states, isAuthorized, refineItem)
to preserve encapsulation and follow the Rust-style static builder guideline.
packages/jam/in-core/refine.ts (1)

67-71: Use static factory + private constructor for new module initialization.

For this newly added module, prefer static creation and keep constructor private.

As per coding guidelines, “Prefer Rust-style static builder methods and keep constructors private; avoid constructor overloading.”

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/in-core/refine.ts` around lines 67 - 71, Make the constructor
private and provide a static factory method to create instances: change the
current public constructor(...) to a private constructor(chainSpec, pvmBackend,
blake2b) and add a static method (e.g., create or newInstance) that accepts
chainSpec, pvmBackend, blake2b, constructs and returns the class instance;
update any call sites to use the new static factory instead of new constructor.
Ensure symbols referenced are constructor, chainSpec, pvmBackend, blake2b and
the new static factory name you choose.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/jam/in-core/refine.ts`:
- Around line 120-127: The createRefineExternalities call is only passing
chainSpec and thus per-item fetch data (payload, imports, extrinsics,
currentServiceId, exportOffset, lookupState) never reaches
RefineFetchExternalities; update createRefineExternalities invocation (and the
RefineFetchExternalities constructor/handler in
packages/jam/transition/externalities/refine-fetch-externalities.ts) to accept
and store the item-specific fields (payload, imports, extrinsics,
currentServiceId, exportOffset, lookupState) so that fetch host calls inside
RefineFetchExternalities use the item-scoped data when resolving fetches.
- Around line 141-145: The current branch returns the captured exports when
exports.length !== item.exportCount which leaks invalid segments; change the
early-return path in refine (the block that calls
externalities.refine.getExportedSegments() and compares exports.length to
item.exportCount) to discard the exported segments—return an empty exports array
(or omit the exports field) alongside the WorkResult.create(...) instead of
returning the collected exports so downstream offset/count aggregation does not
receive invalid segments.

---

Nitpick comments:
In `@packages/jam/in-core/in-core.ts`:
- Around line 42-50: The InCore constructor currently performs collaborator
wiring (instantiating IsAuthorized and Refine); change this by making the class
constructor private and moving the wiring into a static async/sync factory
method named create(chainSpec, states, pvmBackend, blake2b) which returns a new
InCore instance; ensure create constructs IsAuthorized and Refine (using the
same parameters) and assigns them to the instance before returning, while the
private constructor only accepts already-initialized dependencies (chainSpec,
states, isAuthorized, refineItem) to preserve encapsulation and follow the
Rust-style static builder guideline.

In `@packages/jam/in-core/refine.ts`:
- Around line 67-71: Make the constructor private and provide a static factory
method to create instances: change the current public constructor(...) to a
private constructor(chainSpec, pvmBackend, blake2b) and add a static method
(e.g., create or newInstance) that accepts chainSpec, pvmBackend, blake2b,
constructs and returns the class instance; update any call sites to use the new
static factory instead of new constructor. Ensure symbols referenced are
constructor, chainSpec, pvmBackend, blake2b and the new static factory name you
choose.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4fea1f7d-3cee-4ecd-8164-7c4a0873bb29

📥 Commits

Reviewing files that changed from the base of the PR and between 842f693 and a6247f3.

📒 Files selected for processing (2)
  • packages/jam/in-core/in-core.ts
  • packages/jam/in-core/refine.ts

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 (1)
packages/jam/in-core/refine.ts (1)

173-188: TODO: Output size validation is not implemented.

Line 176 notes that output size should be verified and potentially return digestTooBig. If there's a spec-defined maximum digest size, this check should be added before shipping to prevent oversized results.

Would you like me to help identify the max digest size from the Gray Paper and draft the validation logic, or open an issue to track this?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/jam/in-core/refine.ts` around lines 173 - 188, extractWorkResult
currently returns WorkExecResult.ok(BytesBlob.blobFrom(slice)) without
validating output size; add a size check against the protocol max digest size
before calling BytesBlob.blobFrom. Define or import a MAX_DIGEST_SIZE constant
(e.g., MAX_DIGEST_SIZE or SPEC_MAX_DIGEST_BYTES), compute slice.length (or
slice.byteLength) and if it exceeds the max return
WorkExecResult.error(WorkExecResultKind.digestTooBig) instead of ok; otherwise
continue to create the blob. Update the TODO comment and add a unit test
covering both under-limit and over-limit cases for extractWorkResult.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/jam/in-core/refine.ts`:
- Around line 239-246: RefineFetchExternalities is being constructed with only
chainSpec but its methods (workItemExtrinsic, workItemImport, workPackage,
allWorkItems) require work-item-specific data; update the
RefineFetchExternalities class to accept and store payload, imports, and
extrinsics (e.g., add constructor params and private fields for payload,
imports, extrinsics and use them in the incomplete methods) and then wire these
into the instantiation in refine.ts by passing the corresponding args (e.g.,
args.payload, args.imports, args.extrinsics) when creating fetchExternalities;
leave RefineExternalitiesImpl.create usage unchanged.

---

Nitpick comments:
In `@packages/jam/in-core/refine.ts`:
- Around line 173-188: extractWorkResult currently returns
WorkExecResult.ok(BytesBlob.blobFrom(slice)) without validating output size; add
a size check against the protocol max digest size before calling
BytesBlob.blobFrom. Define or import a MAX_DIGEST_SIZE constant (e.g.,
MAX_DIGEST_SIZE or SPEC_MAX_DIGEST_BYTES), compute slice.length (or
slice.byteLength) and if it exceeds the max return
WorkExecResult.error(WorkExecResultKind.digestTooBig) instead of ok; otherwise
continue to create the blob. Update the TODO comment and add a unit test
covering both under-limit and over-limit cases for extractWorkResult.
🪄 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: 606f1c0c-2dee-44d0-8f98-200714bd5aa6

📥 Commits

Reviewing files that changed from the base of the PR and between a6247f3 and 8b98af3.

📒 Files selected for processing (1)
  • packages/jam/in-core/refine.ts

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 7, 2026

View all
File Benchmark Ops
bytes/hex-from.ts[0] parse hex using Number with NaN checking 66718.76 ±0.52% 85.19% slower
bytes/hex-from.ts[1] parse hex from char codes 450634.36 ±0.93% fastest ✅
bytes/hex-from.ts[2] parse hex from string nibbles 262484.06 ±0.5% 41.75% slower
bytes/hex-to.ts[0] number toString + padding 86078.15 ±1.43% fastest ✅
bytes/hex-to.ts[1] manual 6949.61 ±2.9% 91.93% slower
codec/bigint.compare.ts[0] compare custom 81311679.08 ±4.69% 7.77% slower
codec/bigint.compare.ts[1] compare bigint 88163730.94 ±4.45% fastest ✅
codec/bigint.decode.ts[0] decode custom 66481867.57 ±3.39% 22.3% slower
codec/bigint.decode.ts[1] decode bigint 85561543.02 ±5.22% fastest ✅
codec/decoding.ts[0] manual decode 8578394.88 ±2.29% 85.68% slower
codec/decoding.ts[1] int32array decode 59899522.23 ±3.63% fastest ✅
codec/decoding.ts[2] dataview decode 58925427.41 ±4.53% 1.63% slower
codec/encoding.ts[0] manual encode 920460.23 ±1.99% 11.72% slower
codec/encoding.ts[1] int32array encode 1042685.19 ±2.85% fastest ✅
codec/encoding.ts[2] dataview encode 996469.24 ±3.23% 4.43% slower
collections/map-set.ts[0] 2 gets + conditional set 62888.39 ±1.7% fastest ✅
collections/map-set.ts[1] 1 get 1 set 42337.07 ±1.24% 32.68% slower
logger/index.ts[0] console.log with string concat 4312773.8 ±41.05% fastest ✅
logger/index.ts[1] console.log with args 1098943.52 ±70.63% 74.52% slower
math/add_one_overflow.ts[0] add and take modulus 81947278.58 ±5.61% fastest ✅
math/add_one_overflow.ts[1] condition before calculation 80639683.98 ±5.17% 1.6% slower
math/count-bits-u32.ts[0] standard method 34840555.52 ±3.36% 51.23% slower
math/count-bits-u32.ts[1] magic 71442999.89 ±5.61% fastest ✅
math/count-bits-u64.ts[0] standard method 3814637.51 ±2.02% 83.39% slower
math/count-bits-u64.ts[1] magic 22971459.01 ±2.32% fastest ✅
math/mul_overflow.ts[0] multiply and bring back to u32 76934164 ±6.1% 1.55% slower
math/mul_overflow.ts[1] multiply and take modulus 78143863.66 ±7.04% fastest ✅
math/switch.ts[0] switch 82367400.41 ±4.98% 5.89% slower
math/switch.ts[1] if 87521789.52 ±6.13% fastest ✅
hash/index.ts[0] hash with numeric representation 68.11 ±0.14% 29.51% slower
hash/index.ts[1] hash with string representation 41.25 ±3.01% 57.31% slower
hash/index.ts[2] hash with symbol representation 66.45 ±0.18% 31.23% slower
hash/index.ts[3] hash with uint8 representation 75.3 ±0.45% 22.07% slower
hash/index.ts[4] hash with packed representation 96.62 ±0.9% fastest ✅
hash/index.ts[5] hash with bigint representation 71.29 ±0.25% 26.22% slower
hash/index.ts[6] hash with uint32 representation 91.88 ±0.73% 4.91% slower
bytes/bytes-to-number.ts[0] Conversion with bitops 2491.6 ±4.55% fastest ✅
bytes/bytes-to-number.ts[1] Conversion without bitops 2270.99 ±2.22% 8.85% slower
bytes/compare.ts[0] Comparing Uint32 bytes 11057.63 ±0.99% fastest ✅
bytes/compare.ts[1] Comparing raw bytes 10602.85 ±3.38% 4.11% slower
codec/view_vs_collection.ts[0] Get first element from Decoded 13339.11 ±1.94% 55.74% slower
codec/view_vs_collection.ts[1] Get first element from View 30138.29 ±1.59% fastest ✅
codec/view_vs_collection.ts[2] Get 50th element from Decoded 13236.22 ±1.72% 56.08% slower
codec/view_vs_collection.ts[3] Get 50th element from View 15850.41 ±1.45% 47.41% slower
codec/view_vs_collection.ts[4] Get last element from Decoded 13670 ±0.91% 54.64% slower
codec/view_vs_collection.ts[5] Get last element from View 11081.41 ±1.17% 63.23% slower
codec/view_vs_object.ts[0] Get the first field from Decoded 189622.35 ±0.82% fastest ✅
codec/view_vs_object.ts[1] Get the first field from View 48000.75 ±0.81% 74.69% slower
codec/view_vs_object.ts[2] Get the first field as view from View 47206.14 ±0.92% 75.11% slower
codec/view_vs_object.ts[3] Get two fields from Decoded 184505.62 ±1.91% 2.7% slower
codec/view_vs_object.ts[4] Get two fields from View 37890.27 ±0.96% 80.02% slower
codec/view_vs_object.ts[5] Get two fields from materialized from View 74836.28 ±2.35% 60.53% slower
codec/view_vs_object.ts[6] Get two fields as views from View 37505.69 ±1.81% 80.22% slower
codec/view_vs_object.ts[7] Get only third field from Decoded 187659.41 ±1.19% 1.04% slower
codec/view_vs_object.ts[8] Get only third field from View 24774.83 ±91.28% 86.93% slower
codec/view_vs_object.ts[9] Get only third field as view from View 46376.4 ±1.66% 75.54% slower
collections/map_vs_sorted.ts[0] Map 117301.48 ±2.1% fastest ✅
collections/map_vs_sorted.ts[1] Map-array 39180.95 ±5.03% 66.6% slower
collections/map_vs_sorted.ts[2] Array 39619.79 ±3.89% 66.22% slower
collections/map_vs_sorted.ts[3] SortedArray 62063.29 ±6.78% 47.09% slower
collections/hash-dict-vs-blob-dict_delete.ts[0] StringHashDictionary 2446.63 ±0.75% fastest ✅
collections/hash-dict-vs-blob-dict_delete.ts[1] BlobDictionary(1) 2228.49 ±3.74% 8.92% slower
collections/hash-dict-vs-blob-dict_delete.ts[2] BlobDictionary(2) 2434.04 ±0.94% 0.51% slower
collections/hash-dict-vs-blob-dict_delete.ts[3] BlobDictionary(3) 2398.92 ±1.54% 1.95% slower
collections/hash-dict-vs-blob-dict_delete.ts[4] BlobDictionary(4) 2361.09 ±2.04% 3.5% slower
collections/hash-dict-vs-blob-dict_delete.ts[5] BlobDictionary(5) 2398.41 ±1.63% 1.97% slower
collections/hash-dict-vs-blob-dict_get.ts[0] StringHashDictionary 2434.06 ±3.68% 6.21% slower
collections/hash-dict-vs-blob-dict_get.ts[1] BlobDictionary(1) 2568.43 ±1.31% 1.03% slower
collections/hash-dict-vs-blob-dict_get.ts[2] BlobDictionary(2) 2546.3 ±1.51% 1.89% slower
collections/hash-dict-vs-blob-dict_get.ts[3] BlobDictionary(3) 2508.39 ±1.74% 3.35% slower
collections/hash-dict-vs-blob-dict_get.ts[4] BlobDictionary(4) 2497.68 ±1.77% 3.76% slower
collections/hash-dict-vs-blob-dict_get.ts[5] BlobDictionary(5) 2595.28 ±1.46% fastest ✅
collections/hash-dict-vs-blob-dict_set.ts[0] StringHashDictionary 1776.22 ±5.11% 13.29% slower
collections/hash-dict-vs-blob-dict_set.ts[1] BlobDictionary(1) 1749.17 ±5.45% 14.61% slower
collections/hash-dict-vs-blob-dict_set.ts[2] BlobDictionary(2) 1760.99 ±5.42% 14.03% slower
collections/hash-dict-vs-blob-dict_set.ts[3] BlobDictionary(3) 2048.48 ±3.01% fastest ✅
collections/hash-dict-vs-blob-dict_set.ts[4] BlobDictionary(4) 1922.35 ±5.09% 6.16% slower
collections/hash-dict-vs-blob-dict_set.ts[5] BlobDictionary(5) 2010.76 ±3.55% 1.84% slower
hash/blake2b.ts[0] our hasher 0.89 ±9.53% fastest ✅
hash/blake2b.ts[1] blake2b js 0.03 ±7.37% 96.63% slower
crypto/ed25519.ts[0] native crypto 5.57 ±2.65% fastest ✅
crypto/ed25519.ts[1] wasm lib 2.23 ±1% 59.96% slower
crypto/ed25519.ts[2] wasm lib batch 2.24 ±0.17% 59.78% slower

Benchmarks summary: 83/83 OK ✅

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