Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/actions/setup-and-build/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ runs:
echo "pnpm=${PNPM_VERSION}" >> $GITHUB_OUTPUT
echo "solana=${SOLANA_VERSION}" >> $GITHUB_OUTPUT
echo "anchor=${ANCHOR_VERSION}" >> $GITHUB_OUTPUT
echo "just=${JUST_VERSION}" >> $GITHUB_OUTPUT
echo "photon=${PHOTON_VERSION}" >> $GITHUB_OUTPUT
echo "photon_commit=${PHOTON_COMMIT}" >> $GITHUB_OUTPUT
echo "redis=${REDIS_VERSION}" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -114,6 +115,8 @@ runs:

- name: Install just
uses: extractions/setup-just@v2
with:
just-version: ${{ steps.versions.outputs.just }}

- name: Set Light Protocol environment variables
shell: bash
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"pubkey":"ACXg8a7VaqecBWrSbdu73W4Pg9gsqXJ3EXAqkHyhvVXg","account":{"lamports":3048480,"data":["tATnGtyQN6gBAAH+SAQtJ+UbyIx39TonBXNob6aj8IhJZXQDWxu0dUrRKtBIBC0n5RvIjHf1OicFc2hvpqPwiElldANbG7R1StEq0AyNmy4X80UX3keywHfcTHRpoDkggeuLDEJp3K8hdmjDNfsX+1mDkDWCPnO7jhPNTQ0DDtupetonCWjl6mDSxmj//4AA+CoBAoAwCKbpmLBf6SuYoNn3ednb6LLz7vZ4Eyh766UmSYCRaL0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==","base64"],"owner":"Lighton6oQpVkeewmo2mcPTQQp7kYHr4fWpAgJyEmDX","executable":false,"rentEpoch":0,"space":310}}
{"pubkey":"ACXg8a7VaqecBWrSbdu73W4Pg9gsqXJ3EXAqkHyhvVXg","account":{"lamports":3048480,"data":["tATnGtyQN6gBAAH+gIWDMK+2dZmaFyA2y83op3FH/WmGd/YVM+VM8Nt0Y8uAhYMwr7Z1mZoXIDbLzeincUf9aYZ39hUz5Uzw23RjywyNmy4X80UX3keywHfcTHRpoDkggeuLDEJp3K8hdmjDNfsX+1mDkDWCPnO7jhPNTQ0DDtupetonCWjl6mDSxmj//4AA+CoBAoAwCKbpmLBf6SuYoNn3ednb6LLz7vZ4Eyh766UmSYCRaL0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==","base64"],"owner":"Lighton6oQpVkeewmo2mcPTQQp7kYHr4fWpAgJyEmDX","executable":false,"rentEpoch":0,"space":310}}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"pubkey":"CuEtcKkkbTn6qy2qxqDswq5U2ADsqoipYDAYfRvxPjcp","account":{"lamports":2234160,"data":["YLDvkgH+Y5ICY+L7WEJcIRnY07lwy9TuaZBIebD9aqhznpq8Pv+mUf8AAAAAAAAAAAEAAAAAAAAACgAAAAAAAABkAAAAAAAAAMgAAAAAAAAAZAAAAAAAAACIEwAAAAAAAAhQAAAAAAAAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==","base64"],"owner":"Lighton6oQpVkeewmo2mcPTQQp7kYHr4fWpAgJyEmDX","executable":false,"rentEpoch":0,"space":193}}
{"pubkey":"CuEtcKkkbTn6qy2qxqDswq5U2ADsqoipYDAYfRvxPjcp","account":{"lamports":2234160,"data":["YLDvkgH+Y5ICY+L7WEJcIRnY07lwy9TuaZBIebD9aqhznpq8Pv+mUf8AAAAAAAAAAAEAAAAAAAAACgAAAAAAAABkAAAAAAAAAMgAAAAAAAAAZAAAAAAAAACIEwAAAAAAAMQ2AAAAAAAAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==","base64"],"owner":"Lighton6oQpVkeewmo2mcPTQQp7kYHr4fWpAgJyEmDX","executable":false,"rentEpoch":0,"space":193}}
5 changes: 3 additions & 2 deletions cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lightprotocol/zk-compression-cli",
"version": "0.28.3",
"version": "0.28.4",
"description": "ZK Compression: Secure Scaling on Solana",
"maintainers": [
{
Expand Down Expand Up @@ -95,13 +95,14 @@
"sync-prover-version": "./scripts/syncProverVersion.sh",
"sync-photon-version": "./scripts/syncPhotonVersion.sh",
"build": "shx rm -rf dist && pnpm sync-prover-version && pnpm sync-photon-version && pnpm tsc -p tsconfig.json && pnpm tsc -p tsconfig.test.json",
"build-release": "shx rm -rf dist && pnpm sync-prover-version && pnpm sync-photon-version && pnpm tsc -p tsconfig.json && pnpm tsc -p tsconfig.test.json",
"build-release": "shx rm -rf dist && pnpm sync-prover-version && pnpm sync-photon-version && pnpm tsc -p tsconfig.json && pnpm tsc -p tsconfig.test.json && pnpm verify-bundled-accounts",
"format": "pnpm prettier --write \"src/**/*.{ts,js}\" \"test/**/*.{ts,js}\" -w",
"format:check": "pnpm prettier \"src/**/*{ts,js}\" \"test/**/*.{ts,js}\" --check",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"postpack": "shx rm -f oclif.manifest.json",
"prepack": "pnpm build-release && oclif manifest && oclif readme",
"verify-bundled-accounts": "node ./scripts/verifyBundledAccounts.js",
"test-utils": "mocha ./test/utils/index.test.ts -t 10000000 --exit",
"test-config": "mocha ./test/commands/config/index.test.ts -t 10000000 --exit",
"test-create-mint": "mocha ./test/commands/create-mint/index.test.ts -t 10000000 --exit",
Expand Down
133 changes: 133 additions & 0 deletions cli/scripts/verifyBundledAccounts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
const fs = require("fs");
const path = require("path");

const EXPECTATIONS = [
{
filename:
"batch_state_merkle_tree_bmt1LryLZUMmF7ZtqESaw7wifBXLfXHQYoE4GAmrahU.json",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_state_merkle_tree_bmt2UxoBxB9xWev4BkLvkGdapsz6sZGkzViPNph7VFi.json",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_state_merkle_tree_bmt3ccLd4bqSVZVeCJnH1F6C8jNygAhaDfxDwePyyGb.json",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_state_merkle_tree_bmt4d3p1a4YQgk9PeZv5s4DBUmbF5NxqYpk9HGjQsd8.json",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_state_merkle_tree_bmt5yU97jC88YXTuSukYHa8Z5Bi2ZDUtmzfkDTA2mG2.json",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq1na8gojfdUhsfCpyjNt6h4JaDWtHf1yQj4koBWfto.json",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq2UkeMsJLfXt2QHzim242SUi3nvjJs8Pn7Eac9H9vg.json",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq3AxjekBWgo64gpauB6QtuZNesuv19xrhaC1ZM1THQ.json",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq4ypwvVGzCUMoiKKHWh4S1SgZJ9vCvKpcz6RT6A8dq.json",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq5oh5ZR3yGomuQgFduNDzjtGvVWfDRGLuDVjv9a96P.json",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_address_merkle_tree_amt2kaJA14v3urZbZvnc5v2np8jqvc4Z8zDep5wbtzx.json",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 30000,
expectedZkpBatchSize: 250,
},
];

function readSerializedAccountBuffer(accountsDir, filename) {
const raw = fs.readFileSync(path.join(accountsDir, filename), "utf8");
const parsed = JSON.parse(raw);
return Buffer.from(parsed.account.data[0], "base64");
}

function readU64(buffer, offset) {
return Number(buffer.readBigUInt64LE(offset));
}

function assertBundledAccountSizes(accountsDir = path.resolve(__dirname, "../accounts")) {
for (const expectation of EXPECTATIONS) {
const buffer = readSerializedAccountBuffer(accountsDir, expectation.filename);
const batchSize = readU64(buffer, expectation.batchSizeOffset);
const zkpBatchSize = readU64(buffer, expectation.zkpBatchSizeOffset);

if (batchSize !== expectation.expectedBatchSize) {
throw new Error(
`${expectation.filename} has batch_size=${batchSize}, expected ${expectation.expectedBatchSize}`,
);
}

if (zkpBatchSize !== expectation.expectedZkpBatchSize) {
throw new Error(
`${expectation.filename} has zkp_batch_size=${zkpBatchSize}, expected ${expectation.expectedZkpBatchSize}`,
);
}
}
}

if (require.main === module) {
assertBundledAccountSizes();
console.log("Verified bundled CLI batched account sizes.");
}

module.exports = {
EXPECTATIONS,
assertBundledAccountSizes,
};
163 changes: 162 additions & 1 deletion cli/test/commands/test-validator/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect } from "chai";
import { defaultSolanaWalletKeypair, programsDirPath } from "../../../src";
import { Connection, Keypair } from "@solana/web3.js";
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
import * as path from "path";
import * as fs from "fs";
import { killProcess } from "../../../src/utils/process";
Expand All @@ -9,6 +9,140 @@ import { promisify } from "util";
import { ExecException } from "node:child_process";

const exec = promisify(execCb);
const accountsDir = path.resolve(__dirname, "../../../accounts");

type BundledAccountExpectation = {
filename: string;
pubkey: string;
batchSizeOffset: number;
zkpBatchSizeOffset: number;
expectedBatchSize: number;
expectedZkpBatchSize: number;
};

const bundledAccountExpectations: BundledAccountExpectation[] = [
{
filename:
"batch_state_merkle_tree_bmt1LryLZUMmF7ZtqESaw7wifBXLfXHQYoE4GAmrahU.json",
pubkey: "bmt1LryLZUMmF7ZtqESaw7wifBXLfXHQYoE4GAmrahU",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_state_merkle_tree_bmt2UxoBxB9xWev4BkLvkGdapsz6sZGkzViPNph7VFi.json",
pubkey: "bmt2UxoBxB9xWev4BkLvkGdapsz6sZGkzViPNph7VFi",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_state_merkle_tree_bmt3ccLd4bqSVZVeCJnH1F6C8jNygAhaDfxDwePyyGb.json",
pubkey: "bmt3ccLd4bqSVZVeCJnH1F6C8jNygAhaDfxDwePyyGb",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_state_merkle_tree_bmt4d3p1a4YQgk9PeZv5s4DBUmbF5NxqYpk9HGjQsd8.json",
pubkey: "bmt4d3p1a4YQgk9PeZv5s4DBUmbF5NxqYpk9HGjQsd8",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_state_merkle_tree_bmt5yU97jC88YXTuSukYHa8Z5Bi2ZDUtmzfkDTA2mG2.json",
pubkey: "bmt5yU97jC88YXTuSukYHa8Z5Bi2ZDUtmzfkDTA2mG2",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq1na8gojfdUhsfCpyjNt6h4JaDWtHf1yQj4koBWfto.json",
pubkey: "oq1na8gojfdUhsfCpyjNt6h4JaDWtHf1yQj4koBWfto",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq2UkeMsJLfXt2QHzim242SUi3nvjJs8Pn7Eac9H9vg.json",
pubkey: "oq2UkeMsJLfXt2QHzim242SUi3nvjJs8Pn7Eac9H9vg",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq3AxjekBWgo64gpauB6QtuZNesuv19xrhaC1ZM1THQ.json",
pubkey: "oq3AxjekBWgo64gpauB6QtuZNesuv19xrhaC1ZM1THQ",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq4ypwvVGzCUMoiKKHWh4S1SgZJ9vCvKpcz6RT6A8dq.json",
pubkey: "oq4ypwvVGzCUMoiKKHWh4S1SgZJ9vCvKpcz6RT6A8dq",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batched_output_queue_oq5oh5ZR3yGomuQgFduNDzjtGvVWfDRGLuDVjv9a96P.json",
pubkey: "oq5oh5ZR3yGomuQgFduNDzjtGvVWfDRGLuDVjv9a96P",
batchSizeOffset: 240,
zkpBatchSizeOffset: 248,
expectedBatchSize: 15000,
expectedZkpBatchSize: 500,
},
{
filename:
"batch_address_merkle_tree_amt2kaJA14v3urZbZvnc5v2np8jqvc4Z8zDep5wbtzx.json",
pubkey: "amt2kaJA14v3urZbZvnc5v2np8jqvc4Z8zDep5wbtzx",
batchSizeOffset: 272,
zkpBatchSizeOffset: 280,
expectedBatchSize: 30000,
expectedZkpBatchSize: 250,
},
];

function readSerializedAccount(filename: string): Buffer {
const raw = fs.readFileSync(path.join(accountsDir, filename), "utf8");
const parsed = JSON.parse(raw);
return Buffer.from(parsed.account.data[0], "base64");
}

function readU64(buffer: Buffer, offset: number): number {
return Number(buffer.readBigUInt64LE(offset));
}

function expectBatchedAccountSizes(
buffer: Buffer,
expectation: BundledAccountExpectation,
) {
expect(readU64(buffer, expectation.batchSizeOffset)).to.equal(
expectation.expectedBatchSize,
);
expect(readU64(buffer, expectation.zkpBatchSizeOffset)).to.equal(
expectation.expectedZkpBatchSize,
);
}

describe("test-validator command", function () {
this.timeout(120_000);
Expand Down Expand Up @@ -121,6 +255,15 @@ describe("test-validator command", function () {
await cleanupProcesses();
});

it("should bundle release-sized batched tree accounts", function () {
for (const expectation of bundledAccountExpectations) {
expectBatchedAccountSizes(
readSerializedAccount(expectation.filename),
expectation,
);
}
});

it("should start validator without indexer and prover", async function () {
const { stdout } = await exec(
"./test_bin/dev test-validator --skip-indexer --skip-prover",
Expand Down Expand Up @@ -186,6 +329,24 @@ describe("test-validator command", function () {
}
});

it("should load release-sized batched tree accounts over RPC", async function () {
const { stdout } = await exec(
"./test_bin/dev test-validator --skip-indexer --skip-prover",
);
expect(stdout).to.contain("Setup tasks completed successfully");

const connection = await waitForValidatorReady();

for (const expectation of bundledAccountExpectations) {
const accountInfo = await connection.getAccountInfo(
new PublicKey(expectation.pubkey),
);
expect(accountInfo, `${expectation.pubkey} should be loaded`).to.not.be
.null;
expectBatchedAccountSizes(accountInfo!.data, expectation);
}
});

it("should start validator with custom ports", async function () {
const command = [
"./test_bin/dev test-validator",
Expand Down
Loading
Loading