Skip to content

Commit

Permalink
fix: throw Error for methods that PartialListCompositeType does not s…
Browse files Browse the repository at this point in the history
…upport
  • Loading branch information
twoeths committed Sep 10, 2024
1 parent cac1ef7 commit df36a03
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 27 deletions.
37 changes: 24 additions & 13 deletions packages/ssz/src/type/partialListComposite.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {fromSnapshot, zeroNode} from "@chainsafe/persistent-merkle-tree";
import {CompositeType, CompositeView, CompositeViewDU} from "./composite";
import {ListCompositeTreeView} from "../view/listComposite";
import {ListCompositeOpts, ListCompositeType} from "./listComposite";
import {PartialListCompositeTreeViewDU} from "../viewDU/partialListComposite";
import {Snapshot} from "../util/types";
Expand All @@ -9,13 +8,37 @@ import {byteArrayEquals} from "../util/byteArray";
/**
* Similar to ListCompositeType, this is mainly used to create a PartialListCompositeTreeViewDU from a snapshot.
* The ViewDU created is a partial tree created from a snapshot, not a full tree.
* Note that this class only inherits minimal methods as defined in ArrayType of ../view/arrayBasic.ts
* It'll throw errors for all other methods, most of the usage is in the ViewDU class.
*/
export class PartialListCompositeType<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ElementType extends CompositeType<any, CompositeView<ElementType>, CompositeViewDU<ElementType>>
> extends ListCompositeType<ElementType> {
constructor(readonly elementType: ElementType, readonly limit: number, opts?: ListCompositeOpts) {
super(elementType, limit, opts);

// only inherit methods in ArrayType of ../view/arrayBasic.ts
const inheritedMethods = [
"tree_getLength",
"tree_setLength",
"tree_getChunksNode",
"tree_chunksNodeOffset",
"tree_setChunksNode",
];
const methodNames = Object.getOwnPropertyNames(ListCompositeType.prototype).filter(
(prop) =>
prop !== "constructor" &&
typeof (this as unknown as Record<string, unknown>)[prop] === "function" &&
!inheritedMethods.includes(prop)
);

// throw errors for all remaining methods
for (const methodName of methodNames) {
(this as unknown as Record<string, unknown>)[methodName] = () => {
throw new Error(`Method ${methodName} is not implemented for PartialListCompositeType`);
};
}
}

snapshotToViewDU(snapshot: Snapshot): PartialListCompositeTreeViewDU<ElementType> {
Expand All @@ -29,16 +52,4 @@ export class PartialListCompositeType<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return new PartialListCompositeTreeViewDU(this, rootNode, snapshot);
}

getView(): ListCompositeTreeView<ElementType> {
throw new Error("View is not implemented for PartialListCompositeType");
}

getViewDU(): PartialListCompositeTreeViewDU<ElementType> {
throw new Error("Does not support PartialListCompositeType.getViewDU(), use fromSnapshot() instead");
}

toViewDU(): PartialListCompositeTreeViewDU<ElementType> {
throw new Error("Does not support PartialListCompositeType.toViewDU(), use fromSnapshot() instead");
}
}
46 changes: 32 additions & 14 deletions packages/ssz/src/viewDU/partialListComposite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export class PartialListCompositeTreeViewDU<
return super.toSnapshot(count);
}

/** Methods in ArrayCompositeTreeViewDU */

get(index: number): CompositeViewDU<ElementType> {
if (index < this.snapshot.count) {
throw new Error(`Cannot get index ${index} less than existing snapshot count ${this.snapshot.count}`);
Expand Down Expand Up @@ -68,6 +70,12 @@ export class PartialListCompositeTreeViewDU<
throw new Error("getAllReadonlyValues() is not supported for PartialListCompositeTreeViewDU");
}

// commit() is inherited from ArrayCompositeTreeViewDU

/** Methods in ListCompositeTreeViewDU */

// push() is inherited from ListCompositeTreeViewDU

/**
* Similar to ListCompositeTreeViewDU.sliceTo() but:
* - throw error if index < snapshot.count - 1
Expand Down Expand Up @@ -122,22 +130,14 @@ export class PartialListCompositeTreeViewDU<
return new PartialListCompositeTreeViewDU(this.type, newRootNode, ZERO_SNAPSHOT) as this;
}

/**
* Similar to ListCompositeTreeViewDU.toValue() but we need to set undefined values for items 0 to snapshot.count - 1
*/
toValue(): ValueOf<ElementType>[] {
const values = new Array<ValueOf<ElementType>>(this.length);
serializeToBytes(): number {
throw new Error("serializeToBytes() is not supported for PartialListCompositeTreeViewDU");
}

const snapshotCount = this.snapshot.count;
const allNodes = getNodesAtDepth(this._rootNode, this.type.depth, snapshotCount, this.length - snapshotCount);
const type = this.type.elementType;
// value of 0 to snapshot.count - 1 is from snapshot, and they are undefined
for (let i = snapshotCount; i < this.length; i++) {
values[i] = type.toValueFromViewDU(type.getViewDU(allNodes[i - snapshotCount]));
}
/** Methods in TreeViewDU */

return values;
}
// hashTreeRoot() is inherited from TreeViewDU
// batchHashTreeRoot() is inherited from TreeViewDU

/**
* Does not support serialize and deserialize, it works through snapshot.
Expand All @@ -159,6 +159,24 @@ export class PartialListCompositeTreeViewDU<
}
}

/**
* Mainly used for testing, to ensure the snapshot is correct.
* Set undefined values for items 0 to snapshot.count - 1
*/
toValue(): ValueOf<ElementType>[] {
const values = new Array<ValueOf<ElementType>>(this.length);

const snapshotCount = this.snapshot.count;
const allNodes = getNodesAtDepth(this._rootNode, this.type.depth, snapshotCount, this.length - snapshotCount);
const type = this.type.elementType;
// value of 0 to snapshot.count - 1 is from snapshot, and they are undefined
for (let i = snapshotCount; i < this.length; i++) {
values[i] = type.toValueFromViewDU(type.getViewDU(allNodes[i - snapshotCount]));
}

return values;
}

/**
* Throw error because we only have partial tree in this case.
*/
Expand Down

0 comments on commit df36a03

Please sign in to comment.