Skip to content

Commit

Permalink
fix: EIP-4881 spec test
Browse files Browse the repository at this point in the history
  • Loading branch information
twoeths committed Sep 10, 2024
1 parent 21e0c54 commit 863b7d9
Show file tree
Hide file tree
Showing 6 changed files with 11,145 additions and 3 deletions.
3 changes: 2 additions & 1 deletion packages/ssz/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@
"benchmark:local": "yarn benchmark --local",
"test:perf": "mocha \"test/perf/**/*.test.ts\"",
"test:unit": "nyc mocha \"test/unit/**/*.test.ts\"",
"test:spec": "yarn test:spec-generic && yarn test:spec-static",
"test:spec": "yarn test:spec-generic && yarn test:spec-static test:spec-eip-4881",
"test:spec-generic": "mocha \"test/spec/generic/**/*.test.ts\"",
"test:spec-static": "yarn test:spec-static-minimal && yarn test:spec-static-mainnet",
"test:spec-static-minimal": "LODESTAR_PRESET=minimal mocha test/spec/ssz_static.test.ts",
"test:spec-static-mainnet": "LODESTAR_PRESET=mainnet mocha test/spec/ssz_static.test.ts",
"test:spec-eip-4881": "mocha \"test/spec/eip-4881/**/*.test.ts\"",
"download-spec-tests": "node -r ts-node/register test/spec/downloadTests.ts"
},
"types": "lib/index.d.ts",
Expand Down
3 changes: 3 additions & 0 deletions packages/ssz/src/viewDU/partialListComposite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export class PartialListCompositeTreeViewDU<
this.snapshot = snapshot;
}

/**
* Create snapshot from the first `count` elements of the list.
*/
toSnapshot(count: number): Snapshot {
if (count < this.snapshot.count) {
throw new Error(
Expand Down
18 changes: 17 additions & 1 deletion packages/ssz/test/lodestarTypes/phase0/sszTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
VectorCompositeType,
} from "../../../src";
import {ListUintNum64Type} from "../../../src/type/listUintNum64";
import {PartialListCompositeType} from "../../../src/type/partialListComposite";
import {
preset,
MAX_REQUEST_BLOCKS,
Expand Down Expand Up @@ -140,7 +141,8 @@ export const DepositData = new ContainerType(
{typeName: "DepositData", jsonCase: "eth2"}
);

export const DepositDataRootList = new ListCompositeType(Root, 2 ** DEPOSIT_CONTRACT_TREE_DEPTH);
export const DepositDataRootFullList = new ListCompositeType(Root, 2 ** DEPOSIT_CONTRACT_TREE_DEPTH);
export const DepositDataRootPartialList = new PartialListCompositeType(Root, 2 ** DEPOSIT_CONTRACT_TREE_DEPTH);

export const DepositEvent = new ContainerType(
{
Expand Down Expand Up @@ -172,6 +174,20 @@ export const Eth1DataOrdered = new ContainerType(
{typeName: "Eth1DataOrdered", jsonCase: "eth2"}
);

/**
* Specific type for EIP-4881.
*/
export const DepositsDataSnapshot = new ContainerType(
{
finalized: DepositDataRootFullList,
depositRoot: Root,
depositCount: UintNum64,
executionBlockHash: Root,
executionBlockHeight: UintNum64,
},
{typeName: "DepositsDataSnapshot", jsonCase: "eth2"}
);

/** Spec'ed but only used in lodestar as a type */
export const Eth1Block = new ContainerType(
{
Expand Down
109 changes: 109 additions & 0 deletions packages/ssz/test/spec/eip-4881/eip4881.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import fs from "node:fs";
import path from "node:path";
import jsyaml from "js-yaml";
import {expect} from "chai";
import {ContainerType, ListCompositeType} from "../../../src";
import {ssz} from "../../lodestarTypes";
import {DepositDataRootFullList, DepositDataRootPartialList} from "../../lodestarTypes/phase0/sszTypes";
import {ListCompositeTreeViewDU} from "../../../src/viewDU/listComposite";

const EIP4881TestDataArrayItem = new ContainerType(
{
depositData: ssz.phase0.DepositData,
depositDataRoot: ssz.Root,
eth1Data: ssz.phase0.Eth1Data,
blockHeight: ssz.UintNum64,
snapshot: ssz.phase0.DepositsDataSnapshot,
},
{typeName: "EIP4881TestDataArrayItem", jsonCase: "eth2"}
);

// test data contains 512 items
const EIP4881TestDataArray = new ListCompositeType(EIP4881TestDataArrayItem, 1024);

describe("EIP-4881", function () {
this.timeout(60 * 1000);

const ymlStr = fs.readFileSync(path.join(__dirname, "test_data.yaml"), "utf8");
const json = jsyaml.load(ymlStr) as unknown[];
expect(json.length).to.be.equal(512);
const testData = EIP4881TestDataArray.fromJson(json);
expect(testData.length).to.be.equal(512);

const testCases: {name: string; viewDU: ListCompositeTreeViewDU<typeof ssz.Root>}[] = [
{
name: "DepositDataRootFullList",
viewDU: DepositDataRootFullList.defaultViewDU(),
},
{
name: "DepositDataRootPartialList",
viewDU: DepositDataRootPartialList.defaultPartialViewDU(),
},
];

for (const {name, viewDU: depositRootTree} of testCases) {
it(`${name}.toSnapshot()`, () => {
for (let i = 0; i < testData.length; i++) {
const {depositData, eth1Data, blockHeight, snapshot, depositDataRoot} = testData[i];

// validate depositDataRoot
expect(ssz.phase0.DepositData.hashTreeRoot(depositData)).to.be.deep.equal(depositDataRoot);
depositRootTree.push(depositDataRoot);

// validate eth1Data
expect(eth1Data.depositRoot).to.be.deep.equal(depositRootTree.hashTreeRoot());
expect(eth1Data.depositCount).to.be.equal(depositRootTree.length);

const blockHash = eth1Data.blockHash;
const {finalized, depositRoot, depositCount, executionBlockHash, executionBlockHeight} = snapshot;

// validate snapshot data
expect(executionBlockHash).to.be.deep.equal(blockHash);
expect(executionBlockHeight).to.be.equal(blockHeight);
expect(depositRoot).to.be.deep.equal(depositRootTree.hashTreeRoot());

// validate actual snapshot
const actualSnapshot = depositRootTree.toSnapshot(i + 1);
expect(actualSnapshot.finalized).to.be.deep.equal(finalized);
expect(actualSnapshot.root).to.be.deep.equal(depositRoot);
expect(actualSnapshot.count).to.be.equal(depositCount);
}
});
}

it("snapshot to PartialListCompositeTreeViewDU", () => {
const fullTree = DepositDataRootFullList.defaultViewDU();

for (let i = 0; i < testData.length; i++) {
const {snapshot, depositDataRoot} = testData[i];
const partialTree = DepositDataRootPartialList.toPartialViewDU({
finalized: snapshot.finalized,
root: snapshot.depositRoot,
count: snapshot.depositCount,
});

fullTree.push(depositDataRoot);
expect(partialTree.hashTreeRoot()).to.be.deep.equal(fullTree.hashTreeRoot());

// grow the tree since then
const newFullTree = fullTree.clone();
for (let j = i + 1; j < testData.length; j++) {
newFullTree.push(testData[j].depositDataRoot);
partialTree.push(testData[j].depositDataRoot);

// validate root
expect(partialTree.hashTreeRoot()).to.be.deep.equal(newFullTree.hashTreeRoot());

// validate snapshot
const actualSnapshot = partialTree.toSnapshot(j + 1);
expect(actualSnapshot).to.be.deep.equal(newFullTree.toSnapshot(j + 1));
const expectedSnapshot = testData[j].snapshot;
expect(actualSnapshot).to.be.deep.equal({
finalized: expectedSnapshot.finalized,
root: expectedSnapshot.depositRoot,
count: expectedSnapshot.depositCount,
});
}
}
});
});
Loading

0 comments on commit 863b7d9

Please sign in to comment.