Skip to content

Commit

Permalink
feat: use allocUnsafe() for hashTreeRoot()
Browse files Browse the repository at this point in the history
  • Loading branch information
twoeths committed Oct 11, 2024
1 parent 1da53b3 commit 024538d
Show file tree
Hide file tree
Showing 12 changed files with 28 additions and 17 deletions.
1 change: 1 addition & 0 deletions packages/as-sha256/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {newInstance} from "./wasm";
import {HashObject, byteArrayIntoHashObject, byteArrayToHashObject, hashObjectToByteArray} from "./hashObject";
import SHA256 from "./sha256";
export {HashObject, byteArrayToHashObject, hashObjectToByteArray, byteArrayIntoHashObject, SHA256};
export {allocUnsafe};

const ctx = newInstance();
const wasmInputValue = ctx.input.value;
Expand Down
1 change: 1 addition & 0 deletions packages/ssz/src/type/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export abstract class BasicType<V> extends Type<V> {
}

hashTreeRoot(value: V): Uint8Array {
// cannot use allocUnsafe() here because hashTreeRootInto() may not fill the whole 32 bytes
const root = new Uint8Array(32);
this.hashTreeRootInto(value, root, 0);
return root;
Expand Down
3 changes: 2 additions & 1 deletion packages/ssz/src/type/bitList.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {allocUnsafe} from "@chainsafe/as-sha256";
import {
getNodesAtDepth,
merkleizeInto,
Expand Down Expand Up @@ -113,7 +114,7 @@ export class BitListType extends BitArrayType {
// Merkleization: inherited from BitArrayType

hashTreeRoot(value: BitArray): Uint8Array {
const root = new Uint8Array(32);
const root = allocUnsafe(32);
this.hashTreeRootInto(value, root, 0);
return root;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/ssz/src/type/byteList.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {allocUnsafe} from "@chainsafe/as-sha256";
import {
getNodesAtDepth,
Node,
Expand All @@ -11,7 +12,6 @@ import {namedClass} from "../util/named";
import {addLengthNode, getChunksNodeFromRootNode, getLengthFromRootNode} from "./arrayBasic";
import {ByteViews} from "./composite";
import {ByteArrayType, ByteArray} from "./byteArray";

/* eslint-disable @typescript-eslint/member-ordering */

export interface ByteListOptions {
Expand Down Expand Up @@ -101,7 +101,7 @@ export class ByteListType extends ByteArrayType {
// Merkleization: inherited from ByteArrayType

hashTreeRoot(value: ByteArray): Uint8Array {
const root = new Uint8Array(32);
const root = allocUnsafe(32);
this.hashTreeRootInto(value, root, 0);
return root;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/ssz/src/type/composite.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {allocUnsafe} from "@chainsafe/as-sha256";
import {
concatGindices,
createProof,
Expand Down Expand Up @@ -218,7 +219,7 @@ export abstract class CompositeType<V, TV, TVDU> extends Type<V> {
}
}

const root = new Uint8Array(32);
const root = allocUnsafe(32);
this.hashTreeRootInto(value, root, 0);

// hashTreeRootInto will cache the root if cachePermanentRootStruct is true
Expand Down
3 changes: 0 additions & 3 deletions packages/ssz/src/type/containerNodeStruct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ import {ValueOfFields} from "../view/container";
* This tradeoff is good for data that is read often, written rarely, and consumes a lot of memory (i.e. Validator)
*/
export class ContainerNodeStructType<Fields extends Record<string, Type<unknown>>> extends ContainerType<Fields> {
// Temporary root to avoid allocating new Uint8Array every time
private temporaryRoot = new Uint8Array(32);

constructor(readonly fields: Fields, opts?: ContainerOptions<Fields>) {
super(fields, {
// Overwrite default "Container" typeName
Expand Down
3 changes: 2 additions & 1 deletion packages/ssz/src/type/listBasic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {ArrayBasicType} from "../view/arrayBasic";
import {ListBasicTreeView} from "../view/listBasic";
import {ListBasicTreeViewDU} from "../viewDU/listBasic";
import {ArrayType} from "./array";
import {allocUnsafe} from "@chainsafe/as-sha256";

/* eslint-disable @typescript-eslint/member-ordering */

Expand Down Expand Up @@ -174,7 +175,7 @@ export class ListBasicType<ElementType extends BasicType<unknown>>
}
}

const root = new Uint8Array(32);
const root = allocUnsafe(32);
this.hashTreeRootInto(value, root, 0);

// hashTreeRootInto will cache the root if cachePermanentRootStruct is true
Expand Down
3 changes: 2 additions & 1 deletion packages/ssz/src/type/listComposite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {ArrayCompositeType} from "../view/arrayComposite";
import {ListCompositeTreeView} from "../view/listComposite";
import {ListCompositeTreeViewDU} from "../viewDU/listComposite";
import {ArrayType} from "./array";
import {allocUnsafe} from "@chainsafe/as-sha256";

/* eslint-disable @typescript-eslint/member-ordering */

Expand Down Expand Up @@ -181,7 +182,7 @@ export class ListCompositeType<
}
}

const root = new Uint8Array(32);
const root = allocUnsafe(32);
this.hashTreeRootInto(value, root, 0);

// hashTreeRootInto will cache the root if cachePermanentRootStruct is true
Expand Down
3 changes: 2 additions & 1 deletion packages/ssz/src/type/optional.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {namedClass} from "../util/named";
import {Type, ByteViews, JsonPath, JsonPathProp} from "./abstract";
import {CompositeType, isCompositeType} from "./composite";
import {addLengthNode, getLengthFromRootNode} from "./arrayBasic";
import {allocUnsafe} from "@chainsafe/as-sha256";
/* eslint-disable @typescript-eslint/member-ordering */

export type NonOptionalType<T extends Type<unknown>> = T extends OptionalType<infer U> ? U : T;
Expand Down Expand Up @@ -178,7 +179,7 @@ export class OptionalType<ElementType extends Type<unknown>> extends CompositeTy
// Merkleization

hashTreeRoot(value: ValueOfType<ElementType>): Uint8Array {
const root = new Uint8Array(32);
const root = allocUnsafe(32);
this.hashTreeRootInto(value, root, 0);
return root;
}
Expand Down
3 changes: 2 additions & 1 deletion packages/ssz/src/type/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {Case} from "../util/strings";
import {BitArray} from "../value/bitArray";
import {mixInActiveFields, setActiveFields} from "./stableContainer";
import {NonOptionalFields, isOptionalType, toNonOptionalType} from "./optional";
import {allocUnsafe} from "@chainsafe/as-sha256";
/* eslint-disable @typescript-eslint/member-ordering */

type BytesRange = {start: number; end: number};
Expand Down Expand Up @@ -377,7 +378,7 @@ export class ProfileType<Fields extends Record<string, Type<unknown>>> extends C
}

const merkleBytes = this.getChunkBytes(value);
const root = new Uint8Array(32);
const root = allocUnsafe(32);
merkleizeInto(merkleBytes, this.maxChunkCount, root, 0);
mixInActiveFields(root, this.activeFields, root, 0);
output.set(root, offset);
Expand Down
15 changes: 10 additions & 5 deletions packages/ssz/src/type/stableContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
import {Case} from "../util/strings";
import {isOptionalType, toNonOptionalType, NonOptionalFields} from "./optional";
import {BitArray} from "../value/bitArray";
import {allocUnsafe} from "@chainsafe/as-sha256";
/* eslint-disable @typescript-eslint/member-ordering */

type BytesRange = {start: number; end: number};
Expand Down Expand Up @@ -350,7 +351,7 @@ export class StableContainerType<Fields extends Record<string, Type<unknown>>> e
}

const merkleBytes = this.getChunkBytes(value);
const root = new Uint8Array(32);
const root = allocUnsafe(32);
merkleizeInto(merkleBytes, this.maxChunkCount, root, 0);
// compute active field bitvector
const activeFields = BitArray.fromBoolArray([
Expand Down Expand Up @@ -750,12 +751,15 @@ export function getActiveFields(rootNode: Node, bitLen: number): BitArray {
return new BitArray(activeFieldsBuf, bitLen);
}

// This is a global buffer to avoid creating a new one for each call to getActiveFields
const singleChunkActiveFieldsBuf = new Uint8Array(32);

export function setActiveFields(rootNode: Node, activeFields: BitArray): Node {
// fast path for depth 1, the bitvector fits in one chunk
if (activeFields.bitLen <= 256) {
const activeFieldsBuf = new Uint8Array(32);
activeFieldsBuf.set(activeFields.uint8Array);
return new BranchNode(rootNode.left, LeafNode.fromRoot(activeFieldsBuf));
singleChunkActiveFieldsBuf.fill(0);
singleChunkActiveFieldsBuf.set(activeFields.uint8Array);
return new BranchNode(rootNode.left, LeafNode.fromRoot(singleChunkActiveFieldsBuf));
}

const activeFieldsChunkCount = Math.ceil(activeFields.bitLen / 256);
Expand Down Expand Up @@ -825,7 +829,8 @@ export function mixInActiveFields(root: Uint8Array, activeFields: BitArray, outp
activeFieldsSingleChunk.fill(0);
activeFieldsSingleChunk.set(activeFields.uint8Array);
// 1 chunk for root, 1 chunk for activeFields
merkleizeInto(mixInActiveFieldsChunkBytes, 2, output, offset);
const chunkCount = 2;
merkleizeInto(mixInActiveFieldsChunkBytes, chunkCount, output, offset);
return;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/ssz/src/type/union.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {Type, ByteViews} from "./abstract";
import {CompositeType, isCompositeType} from "./composite";
import {addLengthNode, getLengthFromRootNode} from "./arrayBasic";
import {NoneType} from "./none";
import {allocUnsafe} from "@chainsafe/as-sha256";

/* eslint-disable @typescript-eslint/member-ordering */

Expand Down Expand Up @@ -177,7 +178,7 @@ export class UnionType<Types extends Type<unknown>[]> extends CompositeType<
// Merkleization

hashTreeRoot(value: ValueOfTypes<Types>): Uint8Array {
const root = new Uint8Array(32);
const root = allocUnsafe(32);
this.hashTreeRootInto(value, root, 0);
return root;
}
Expand Down

0 comments on commit 024538d

Please sign in to comment.