Skip to content

Commit

Permalink
fix: handle setBitOr in ListBasicTreeViewDU.sliceTo()
Browse files Browse the repository at this point in the history
  • Loading branch information
twoeths committed Sep 22, 2023
1 parent e84686b commit 6185bb8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 24 deletions.
11 changes: 7 additions & 4 deletions packages/ssz/src/viewDU/listBasic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ export class ListBasicTreeViewDU<ElementType extends BasicType<unknown>> extends
const chunkIndex = Math.floor(index / this.type.itemsPerChunk);
const nodePrev = (this.nodes[chunkIndex] ?? getNodeAtDepth(rootNode, this.type.depth, chunkIndex)) as LeafNode;

const nodeChanged = nodePrev.clone();
// set remaining items in the same chunk to 0
for (let i = index + 1; i < (chunkIndex + 1) * this.type.itemsPerChunk; i++) {
this.type.elementType.tree_setToPackedNode(nodeChanged, i, 0);
// we can't set remaining items in the same chunk to 0 with tree_setToPackedNode api due to setBitwiseOR in UintNumberType
// instead, we set the same value in nodePrev up until index
const nodeChanged = LeafNode.fromZero();
for (let i = chunkIndex * this.type.itemsPerChunk; i <= index; i++) {
const prevValue = this.type.elementType.tree_getFromPackedNode(nodePrev, i);
this.type.elementType.tree_setToPackedNode(nodeChanged, i, prevValue);
}

const chunksNode = this.type.tree_getChunksNode(this._rootNode);
let newChunksNode = setNodesAtDepth(chunksNode, this.type.chunkDepth, [chunkIndex], [nodeChanged]);
// also do the treeZeroAfterIndex operation on the chunks tree
Expand Down
42 changes: 22 additions & 20 deletions packages/ssz/test/unit/byType/listBasic/tree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,24 +212,26 @@ describe("ListBasicType drop caches", () => {
});

describe("ListBasicType.sliceTo", () => {
// same to BeaconState InactivityScores
it("Slice List at multiple length", () => {
const listType = new ListBasicType(new UintNumberType(8), 100);
const listView = listType.defaultViewDU();
const listRoots: string[] = [];
const listSerialized: string[] = [];

for (let i = 0; i < 16; i++) {
listView.push(i);
listSerialized[i] = toHexString(listView.serialize());
listRoots[i] = toHexString(listView.hashTreeRoot());
}

for (let i = 0; i < 16; i++) {
const listSlice = listView.sliceTo(i);
expect(listSlice.length).to.equal(i + 1, `Wrong length at .sliceTo(${i})`);
expect(toHexString(listSlice.serialize())).equals(listSerialized[i], `Wrong serialize at .sliceTo(${i})`);
expect(toHexString(listSlice.hashTreeRoot())).equals(listRoots[i], `Wrong root at .sliceTo(${i})`);
}
});
// same to BeaconState inactivityScores and previousEpochParticipation
for (const elementType of [new UintNumberType(8), new UintNumberType(1, {setBitwiseOR: true})]) {
it(`Slice list of ${elementType.typeName} at multiple length`, () => {
const listType = new ListBasicType(elementType, 100);
const listView = listType.defaultViewDU();
const listRoots: string[] = [];
const listSerialized: string[] = [];

for (let i = 0; i < 16; i++) {
listView.push(i);
listSerialized[i] = toHexString(listView.serialize());
listRoots[i] = toHexString(listView.hashTreeRoot());
}

for (let i = 0; i < 16; i++) {
const listSlice = listView.sliceTo(i);
expect(listSlice.length).to.equal(i + 1, `Wrong length at .sliceTo(${i})`);
expect(toHexString(listSlice.serialize())).equals(listSerialized[i], `Wrong serialize at .sliceTo(${i})`);
expect(toHexString(listSlice.hashTreeRoot())).equals(listRoots[i], `Wrong root at .sliceTo(${i})`);
}
});
}
});

0 comments on commit 6185bb8

Please sign in to comment.