From f616a328ac627b7354d9cfbda8b1d0d2adfbe0d3 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:01:03 -0400 Subject: [PATCH 01/20] Adding basics. --- .github/workflows/benchmark.yml | 52 ++++++++++++++++++++++++++ clients/js/bench/_setup.ts | 7 ++++ clients/js/bench/create.ts | 38 +++++++++++++++++++ clients/js/output.json | 7 ++++ clients/js/package.json | 6 ++- clients/js/tsconfig.json | 2 +- configs/scripts/client/benchmark-js.sh | 14 +++++++ 7 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/benchmark.yml create mode 100644 clients/js/bench/_setup.ts create mode 100644 clients/js/bench/create.ts create mode 100644 clients/js/output.json create mode 100755 configs/scripts/client/benchmark-js.sh diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 00000000..52a5796f --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,52 @@ +name: Benchmark +on: + workflow_call: + push: + branches: + - main + +jobs: + benchmark: + name: Performance regression check + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v3 + + - name: Load environment variables + run: cat .github/.env >> $GITHUB_ENV + + - name: Start validator + uses: metaplex-foundation/actions/start-validator@v1 + with: + node: ${{ matrix.node }} + solana: ${{ env.SOLANA_VERSION }} + cache: ${{ env.CACHE }} + + - name: Install dependencies + uses: metaplex-foundation/actions/install-node-dependencies@v1 + with: + folder: ./clients/js + cache: ${{ env.CACHE }} + key: clients-js + + # Download previous benchmark result from cache (if exists) + - name: Download previous benchmark data + uses: actions/cache@v4 + with: + path: ./cache + key: ${{ runner.os }}-benchmark + + # Run `github-action-benchmark` action + - name: Store benchmark result + uses: benchmark-action/github-action-benchmark@v1 + with: + # What benchmark tool the output.txt came from + tool: "customSmallerIsBetter" + # Where the output from the benchmark tool is stored + output-file-path: ./clients/js/output.txt + # Where the previous data file is stored + external-data-json-path: ./cache/benchmark-data.json + # Workflow will fail when an alert happens + fail-on-alert: true + # Upload the updated cache file for the next job by actions/cache diff --git a/clients/js/bench/_setup.ts b/clients/js/bench/_setup.ts new file mode 100644 index 00000000..06c58827 --- /dev/null +++ b/clients/js/bench/_setup.ts @@ -0,0 +1,7 @@ +/* eslint-disable import/no-extraneous-dependencies */ +import { createUmi as basecreateUmi } from '@metaplex-foundation/umi-bundle-tests'; +import { + mplCore, +} from '../src'; + +export const createUmi = async () => (await basecreateUmi()).use(mplCore()); diff --git a/clients/js/bench/create.ts b/clients/js/bench/create.ts new file mode 100644 index 00000000..3660a898 --- /dev/null +++ b/clients/js/bench/create.ts @@ -0,0 +1,38 @@ +import { generateSigner } from "@metaplex-foundation/umi"; +import test from "ava"; +import { existsSync, readFileSync, writeFileSync } from "fs"; +import { createV1 } from "../src"; +import { createUmi } from "./_setup"; + +test('create a new, empty asset', async (t) => { + // Given an Umi instance and a new signer. + const umi = await createUmi(); + const assetAddress = generateSigner(umi); + + const tx = await createV1(umi, { + asset: assetAddress, + name: "Test", + uri: "www.test.com", + }).sendAndConfirm(umi); + + const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + + const result = { + name: t.title, + unit: "Compute Units", + value: compute, + } + + // Read the results array from output.json + let output = []; + if (existsSync("./output.json")) { + output = JSON.parse(readFileSync("./output.json", 'utf-8')); + } + + // Push the result to the array + output.push(result); + // Write the array to output.json + writeFileSync("./output.json", JSON.stringify(output, null, 2)); + + t.pass(); +}); \ No newline at end of file diff --git a/clients/js/output.json b/clients/js/output.json new file mode 100644 index 00000000..ace663df --- /dev/null +++ b/clients/js/output.json @@ -0,0 +1,7 @@ +[ + { + "name": "create a new, empty asset", + "unit": "Compute Units", + "value": 7404 + } +] \ No newline at end of file diff --git a/clients/js/package.json b/clients/js/package.json index 34a5e3e3..3425eb7e 100644 --- a/clients/js/package.json +++ b/clients/js/package.json @@ -8,6 +8,7 @@ "build": "rimraf dist && tsc -p tsconfig.json", "build:docs": "typedoc", "test": "ava --timeout 600s", + "bench": "ava ./dist/bench/*.js", "lint": "eslint --ext js,ts,tsx src", "lint:fix": "eslint --fix --ext js,ts,tsx src", "format": "prettier --check src test", @@ -57,9 +58,10 @@ "compile": false, "rewritePaths": { "src/": "dist/src/", - "test/": "dist/test/" + "test/": "dist/test/", + "bench/": "dist/bench/" } } }, "packageManager": "pnpm@8.2.0" -} +} \ No newline at end of file diff --git a/clients/js/tsconfig.json b/clients/js/tsconfig.json index 5044f1c7..23b7996c 100644 --- a/clients/js/tsconfig.json +++ b/clients/js/tsconfig.json @@ -25,6 +25,6 @@ "skipLibCheck": true, "useUnknownInCatchVariables": false }, - "include": ["src", "test"], + "include": ["src", "test", "bench"], "exclude": ["node_modules", "dist", "build", "lib"] } diff --git a/configs/scripts/client/benchmark-js.sh b/configs/scripts/client/benchmark-js.sh new file mode 100755 index 00000000..9849fa18 --- /dev/null +++ b/configs/scripts/client/benchmark-js.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) +# go to parent folder +cd $(dirname $(dirname $(dirname $SCRIPT_DIR))) +WORKING_DIR=$(pwd) + +# command-line input +ARGS=$* + +# js client tests folder +cd ${WORKING_DIR}/clients/js + +pnpm install && pnpm build && pnpm bench ${ARGS} \ No newline at end of file From 74549d54f535215fa17af72d825010b3864fafc4 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:10:44 -0400 Subject: [PATCH 02/20] Updating workflow. --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 52a5796f..39de7640 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -19,7 +19,7 @@ jobs: - name: Start validator uses: metaplex-foundation/actions/start-validator@v1 with: - node: ${{ matrix.node }} + node: 18.x solana: ${{ env.SOLANA_VERSION }} cache: ${{ env.CACHE }} From de2d79cc8bfa39f7fc1f26ad5a105c5715101628 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:16:19 -0400 Subject: [PATCH 03/20] Adding cache var. --- .github/workflows/benchmark.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 39de7640..bce434ea 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -5,6 +5,9 @@ on: branches: - main +env: + CACHE: true + jobs: benchmark: name: Performance regression check From a98726880e969b1429bce9b1e324e21de482589f Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:25:23 -0400 Subject: [PATCH 04/20] Updating main. --- .github/workflows/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8a693ec9..a415a09b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -110,6 +110,12 @@ jobs: uses: ./.github/workflows/test-js-client.yml secrets: inherit + benchmark: + name: Benchmark + needs: generate_clients + uses: ./.github/workflows/benchmark.yml + secrets: inherit + build_rust_client: if: needs.changes.outputs.rust_client == 'true' name: Rust Client From 3939b7e59e2692c0ab0f9fd689a7fc0248dca74c Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:34:33 -0400 Subject: [PATCH 05/20] Updating workflow. --- .github/workflows/benchmark.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index bce434ea..0d7e8572 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -33,6 +33,14 @@ jobs: cache: ${{ env.CACHE }} key: clients-js + - name: Build + working-directory: ./clients/js + run: pnpm build + + - name: Test + working-directory: ./clients/js + run: pnpm bench + # Download previous benchmark result from cache (if exists) - name: Download previous benchmark data uses: actions/cache@v4 @@ -44,10 +52,10 @@ jobs: - name: Store benchmark result uses: benchmark-action/github-action-benchmark@v1 with: - # What benchmark tool the output.txt came from + # What benchmark tool the output.json came from tool: "customSmallerIsBetter" # Where the output from the benchmark tool is stored - output-file-path: ./clients/js/output.txt + output-file-path: ./clients/js/output.json # Where the previous data file is stored external-data-json-path: ./cache/benchmark-data.json # Workflow will fail when an alert happens From 07c75877d6a333daaabd9cbb52614bac7a42686b Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:39:19 -0400 Subject: [PATCH 06/20] Trigger. --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a415a09b..0a0e20b5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,6 @@ name: Main + on: push: branches: [main] From c0e75b23544774a6b6e87a5e126487e099d88391 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:53:30 -0400 Subject: [PATCH 07/20] Adding gh-pages. --- .github/workflows/benchmark.yml | 11 ++++++++++- .github/workflows/main.yml | 1 - 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 0d7e8572..6fad8604 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -5,6 +5,12 @@ on: branches: - main +permissions: + # deployments permission to deploy GitHub pages website + deployments: write + # contents permission to update benchmark contents in gh-pages branch + contents: write + env: CACHE: true @@ -60,4 +66,7 @@ jobs: external-data-json-path: ./cache/benchmark-data.json # Workflow will fail when an alert happens fail-on-alert: true - # Upload the updated cache file for the next job by actions/cache + # Access token to deploy GitHub Pages branch + github-token: ${{ secrets.GITHUB_TOKEN }} + # Push and deploy GitHub pages branch automatically + auto-push: true diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0a0e20b5..a415a09b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,5 @@ name: Main - on: push: branches: [main] From a06882f0a9acaf957fe9b38a06a06d63321ec6ef Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:58:59 -0400 Subject: [PATCH 08/20] Changing. --- .github/workflows/benchmark.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 6fad8604..be26dd3f 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -63,7 +63,7 @@ jobs: # Where the output from the benchmark tool is stored output-file-path: ./clients/js/output.json # Where the previous data file is stored - external-data-json-path: ./cache/benchmark-data.json + # external-data-json-path: ./cache/benchmark-data.json # Workflow will fail when an alert happens fail-on-alert: true # Access token to deploy GitHub Pages branch From f7f32f2b1f6596d08b58132fd6d1711cdc83feb5 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 22:59:55 -0400 Subject: [PATCH 09/20] Trigger. --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a415a09b..ddd10ee2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -122,7 +122,6 @@ jobs: needs: generate_clients uses: ./.github/workflows/build-rust-client.yml secrets: inherit - test_rust_client: if: needs.changes.outputs.rust_client == 'true' name: Rust Client From 31303e01335e969965e930147178e53fc7dc59f4 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 8 Apr 2024 23:06:38 -0400 Subject: [PATCH 10/20] Updating ignore. --- .gitignore | 1 + clients/js/output.json | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 clients/js/output.json diff --git a/.gitignore b/.gitignore index 690bcaca..f7b0e6be 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ dist corebAsZhvD7wa9UiwMiqdbmminpxCp1AxvTrFJbizL.json CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d.json clients/js/yarn.lock +clients/js/output.json \ No newline at end of file diff --git a/clients/js/output.json b/clients/js/output.json deleted file mode 100644 index ace663df..00000000 --- a/clients/js/output.json +++ /dev/null @@ -1,7 +0,0 @@ -[ - { - "name": "create a new, empty asset", - "unit": "Compute Units", - "value": 7404 - } -] \ No newline at end of file From cbe9367675dd988b2b6c2dc549be4d19ec4982c0 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Tue, 9 Apr 2024 17:31:08 -0400 Subject: [PATCH 11/20] Adding a test. --- clients/js/bench/create.ts | 47 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/clients/js/bench/create.ts b/clients/js/bench/create.ts index 3660a898..75110fec 100644 --- a/clients/js/bench/create.ts +++ b/clients/js/bench/create.ts @@ -1,7 +1,7 @@ -import { generateSigner } from "@metaplex-foundation/umi"; +import { generateSigner, TransactionBuilder, transactionBuilder } from "@metaplex-foundation/umi"; import test from "ava"; import { existsSync, readFileSync, writeFileSync } from "fs"; -import { createV1 } from "../src"; +import { createCollectionV1, createV1 } from "../src"; import { createUmi } from "./_setup"; test('create a new, empty asset', async (t) => { @@ -34,5 +34,48 @@ test('create a new, empty asset', async (t) => { // Write the array to output.json writeFileSync("./output.json", JSON.stringify(output, null, 2)); + t.pass(); +}); + +test('create a new, empty asset with empty collection', async (t) => { + // Given an Umi instance and a new signer. + const umi = await createUmi(); + const collectionAddress = generateSigner(umi); + const assetAddress = generateSigner(umi); + + const builder = new TransactionBuilder(); + builder.add(createCollectionV1(umi, { + collection: collectionAddress, + name: "Test", + uri: "www.test.com", + })); + builder.add(createV1(umi, { + asset: assetAddress, + collection: collectionAddress.publicKey, + name: "Test", + uri: "www.test.com", + })); + + const tx = await builder.sendAndConfirm(umi); + + const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + + const result = { + name: t.title, + unit: "Compute Units", + value: compute, + } + + // Read the results array from output.json + let output = []; + if (existsSync("./output.json")) { + output = JSON.parse(readFileSync("./output.json", 'utf-8')); + } + + // Push the result to the array + output.push(result); + // Write the array to output.json + writeFileSync("./output.json", JSON.stringify(output, null, 2)); + t.pass(); }); \ No newline at end of file From cf0c026de6c6b3694c5f54538be2cc569fcb4acf Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Tue, 9 Apr 2024 17:35:44 -0400 Subject: [PATCH 12/20] Removing inclusion. --- clients/js/bench/create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/js/bench/create.ts b/clients/js/bench/create.ts index 75110fec..df6e2323 100644 --- a/clients/js/bench/create.ts +++ b/clients/js/bench/create.ts @@ -1,4 +1,4 @@ -import { generateSigner, TransactionBuilder, transactionBuilder } from "@metaplex-foundation/umi"; +import { generateSigner, TransactionBuilder } from "@metaplex-foundation/umi"; import test from "ava"; import { existsSync, readFileSync, writeFileSync } from "fs"; import { createCollectionV1, createV1 } from "../src"; From 5493534708418c5511e2d5d75e2351d91d23d476 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Apr 2024 11:56:53 -0400 Subject: [PATCH 13/20] Adding space graph. --- clients/js/bench/create.ts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/clients/js/bench/create.ts b/clients/js/bench/create.ts index df6e2323..4f348f88 100644 --- a/clients/js/bench/create.ts +++ b/clients/js/bench/create.ts @@ -16,13 +16,21 @@ test('create a new, empty asset', async (t) => { }).sendAndConfirm(umi); const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + const account = await umi.rpc.getAccount(assetAddress.publicKey); + const space = account.exists ? account.data.length : 0; - const result = { + const cuResult = { name: t.title, unit: "Compute Units", value: compute, } + const spaceResult = { + name: t.title, + unit: "Bytes", + value: space, + } + // Read the results array from output.json let output = []; if (existsSync("./output.json")) { @@ -30,7 +38,8 @@ test('create a new, empty asset', async (t) => { } // Push the result to the array - output.push(result); + output.push(cuResult); + output.push(spaceResult); // Write the array to output.json writeFileSync("./output.json", JSON.stringify(output, null, 2)); @@ -59,13 +68,21 @@ test('create a new, empty asset with empty collection', async (t) => { const tx = await builder.sendAndConfirm(umi); const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + const account = await umi.rpc.getAccount(assetAddress.publicKey); + const space = account.exists ? account.data.length : 0; - const result = { + const cuResult = { name: t.title, unit: "Compute Units", value: compute, } + const spaceResult = { + name: t.title, + unit: "Bytes", + value: space, + } + // Read the results array from output.json let output = []; if (existsSync("./output.json")) { @@ -73,7 +90,8 @@ test('create a new, empty asset with empty collection', async (t) => { } // Push the result to the array - output.push(result); + output.push(cuResult); + output.push(spaceResult); // Write the array to output.json writeFileSync("./output.json", JSON.stringify(output, null, 2)); From 6f570ae889dfc7614ad18411920bb2db78a70eee Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Apr 2024 12:04:19 -0400 Subject: [PATCH 14/20] Fixing titles. --- clients/js/bench/create.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clients/js/bench/create.ts b/clients/js/bench/create.ts index 4f348f88..95685877 100644 --- a/clients/js/bench/create.ts +++ b/clients/js/bench/create.ts @@ -20,13 +20,13 @@ test('create a new, empty asset', async (t) => { const space = account.exists ? account.data.length : 0; const cuResult = { - name: t.title, + name: `CU: ${t.title}`, unit: "Compute Units", value: compute, } const spaceResult = { - name: t.title, + name: `Space: ${t.title}`, unit: "Bytes", value: space, } @@ -72,13 +72,13 @@ test('create a new, empty asset with empty collection', async (t) => { const space = account.exists ? account.data.length : 0; const cuResult = { - name: t.title, + name: `CU: ${t.title}`, unit: "Compute Units", value: compute, } const spaceResult = { - name: t.title, + name: `Space: ${t.title}`, unit: "Bytes", value: space, } From 11306b8ed79ff85ad5b8ffab2b94fd5ae6ba008b Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Apr 2024 12:43:17 -0400 Subject: [PATCH 15/20] Fixing benchmark. --- clients/js/bench/create.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/js/bench/create.ts b/clients/js/bench/create.ts index 95685877..c707adb4 100644 --- a/clients/js/bench/create.ts +++ b/clients/js/bench/create.ts @@ -52,13 +52,13 @@ test('create a new, empty asset with empty collection', async (t) => { const collectionAddress = generateSigner(umi); const assetAddress = generateSigner(umi); - const builder = new TransactionBuilder(); - builder.add(createCollectionV1(umi, { + let builder = new TransactionBuilder(); + builder = builder.add(createCollectionV1(umi, { collection: collectionAddress, name: "Test", uri: "www.test.com", })); - builder.add(createV1(umi, { + builder = builder.add(createV1(umi, { asset: assetAddress, collection: collectionAddress.publicKey, name: "Test", From 4702b02c09889768bf2d6ea5193a0fc1bf4b73b9 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Apr 2024 13:39:34 -0400 Subject: [PATCH 16/20] Adding more benchmarks. --- clients/js/bench/create.ts | 121 ++++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/clients/js/bench/create.ts b/clients/js/bench/create.ts index c707adb4..74ef401c 100644 --- a/clients/js/bench/create.ts +++ b/clients/js/bench/create.ts @@ -1,7 +1,7 @@ import { generateSigner, TransactionBuilder } from "@metaplex-foundation/umi"; import test from "ava"; import { existsSync, readFileSync, writeFileSync } from "fs"; -import { createCollectionV1, createV1 } from "../src"; +import { createCollectionV1, createV1, pluginAuthorityPair, ruleSet } from "../src"; import { createUmi } from "./_setup"; test('create a new, empty asset', async (t) => { @@ -95,5 +95,124 @@ test('create a new, empty asset with empty collection', async (t) => { // Write the array to output.json writeFileSync("./output.json", JSON.stringify(output, null, 2)); + t.pass(); +}); + +test('create a new asset with plugins', async (t) => { + // Given an Umi instance and a new signer. + const umi = await createUmi(); + const assetAddress = generateSigner(umi); + + const tx = await createV1(umi, { + asset: assetAddress, + name: "Test", + uri: "www.test.com", + plugins: [ + pluginAuthorityPair({ + type: 'Royalties', + data: { + basisPoints: 5, + creators: [{ address: umi.identity.publicKey, percentage: 100 }], + ruleSet: ruleSet('None'), + }, + }), + pluginAuthorityPair({ type: 'FreezeDelegate', data: { frozen: true } }), + pluginAuthorityPair({ type: 'TransferDelegate' }), + pluginAuthorityPair({ type: 'BurnDelegate' }), + ], + }).sendAndConfirm(umi); + + const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + const account = await umi.rpc.getAccount(assetAddress.publicKey); + const space = account.exists ? account.data.length : 0; + + const cuResult = { + name: `CU: ${t.title}`, + unit: "Compute Units", + value: compute, + } + + const spaceResult = { + name: `Space: ${t.title}`, + unit: "Bytes", + value: space, + } + + // Read the results array from output.json + let output = []; + if (existsSync("./output.json")) { + output = JSON.parse(readFileSync("./output.json", 'utf-8')); + } + + // Push the result to the array + output.push(cuResult); + output.push(spaceResult); + // Write the array to output.json + writeFileSync("./output.json", JSON.stringify(output, null, 2)); + + t.pass(); +}); + +test('create a new asset with plugins and empty collection', async (t) => { + // Given an Umi instance and a new signer. + const umi = await createUmi(); + const collectionAddress = generateSigner(umi); + const assetAddress = generateSigner(umi); + + let builder = new TransactionBuilder(); + builder = builder.add(createCollectionV1(umi, { + collection: collectionAddress, + name: "Test", + uri: "www.test.com", + })); + builder = builder.add(createV1(umi, { + asset: assetAddress, + name: "Test", + uri: "www.test.com", + plugins: [ + pluginAuthorityPair({ + type: 'Royalties', + data: { + basisPoints: 5, + creators: [{ address: umi.identity.publicKey, percentage: 100 }], + ruleSet: ruleSet('None'), + }, + }), + pluginAuthorityPair({ type: 'FreezeDelegate', data: { frozen: true } }), + pluginAuthorityPair({ type: 'TransferDelegate' }), + pluginAuthorityPair({ type: 'BurnDelegate' }), + ], + })); + + const tx = await builder.sendAndConfirm(umi); + + const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + const account = await umi.rpc.getAccount(assetAddress.publicKey); + const space = account.exists ? account.data.length : 0; + + const cuResult = { + name: `CU: ${t.title}`, + unit: "Compute Units", + value: compute, + } + + const spaceResult = { + name: `Space: ${t.title}`, + unit: "Bytes", + value: space, + } + + // Read the results array from output.json + let output = []; + if (existsSync("./output.json")) { + output = JSON.parse(readFileSync("./output.json", 'utf-8')); + } + + // Push the result to the array + output.push(cuResult); + output.push(spaceResult); + // Write the array to output.json + writeFileSync("./output.json", JSON.stringify(output, null, 2)); + t.pass(); }); \ No newline at end of file From de2110536e72686123b9f56efd08bef5fbab17dd Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Apr 2024 13:51:40 -0400 Subject: [PATCH 17/20] Adding transfer benchmarks. --- clients/js/bench/transfer.ts | 207 +++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 clients/js/bench/transfer.ts diff --git a/clients/js/bench/transfer.ts b/clients/js/bench/transfer.ts new file mode 100644 index 00000000..7950f524 --- /dev/null +++ b/clients/js/bench/transfer.ts @@ -0,0 +1,207 @@ +import { generateSigner, TransactionBuilder } from "@metaplex-foundation/umi"; +import test from "ava"; +import { existsSync, readFileSync, writeFileSync } from "fs"; +import { createCollectionV1, createV1, pluginAuthorityPair, ruleSet, transferV1 } from "../src"; +import { createUmi } from "./_setup"; + +test('transfer an empty asset', async (t) => { + // Given an Umi instance and a new signer. + const umi = await createUmi(); + const assetAddress = generateSigner(umi); + const newOwner = generateSigner(umi); + + await createV1(umi, { + asset: assetAddress, + name: "Test", + uri: "www.test.com", + }).sendAndConfirm(umi); + + const tx = await transferV1(umi, { + asset: assetAddress.publicKey, + newOwner: newOwner.publicKey, + }).sendAndConfirm(umi); + + const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + + const cuResult = { + name: `CU: ${t.title}`, + unit: "Compute Units", + value: compute, + } + + // Read the results array from output.json + let output = []; + if (existsSync("./output.json")) { + output = JSON.parse(readFileSync("./output.json", 'utf-8')); + } + + // Push the result to the array + output.push(cuResult); + // Write the array to output.json + writeFileSync("./output.json", JSON.stringify(output, null, 2)); + + t.pass(); +}); + +test('transfer an empty asset with empty collection', async (t) => { + // Given an Umi instance and a new signer. + const umi = await createUmi(); + const collectionAddress = generateSigner(umi); + const assetAddress = generateSigner(umi); + const newOwner = generateSigner(umi); + + let builder = new TransactionBuilder(); + builder = builder.add(createCollectionV1(umi, { + collection: collectionAddress, + name: "Test", + uri: "www.test.com", + })); + builder = builder.add(createV1(umi, { + asset: assetAddress, + collection: collectionAddress.publicKey, + name: "Test", + uri: "www.test.com", + })); + + await builder.sendAndConfirm(umi); + + const tx = await transferV1(umi, { + asset: assetAddress.publicKey, + newOwner: newOwner.publicKey, + collection: collectionAddress.publicKey, + }).sendAndConfirm(umi); + + const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + + const cuResult = { + name: `CU: ${t.title}`, + unit: "Compute Units", + value: compute, + } + + // Read the results array from output.json + let output = []; + if (existsSync("./output.json")) { + output = JSON.parse(readFileSync("./output.json", 'utf-8')); + } + + // Push the result to the array + output.push(cuResult); + // Write the array to output.json + writeFileSync("./output.json", JSON.stringify(output, null, 2)); + + t.pass(); +}); + +test('transfer an asset with plugins', async (t) => { + // Given an Umi instance and a new signer. + const umi = await createUmi(); + const assetAddress = generateSigner(umi); + const newOwner = generateSigner(umi); + + await createV1(umi, { + asset: assetAddress, + name: "Test", + uri: "www.test.com", + plugins: [ + pluginAuthorityPair({ + type: 'Royalties', + data: { + basisPoints: 5, + creators: [{ address: umi.identity.publicKey, percentage: 100 }], + ruleSet: ruleSet('None'), + }, + }), + pluginAuthorityPair({ type: 'FreezeDelegate', data: { frozen: false } }), + pluginAuthorityPair({ type: 'TransferDelegate' }), + pluginAuthorityPair({ type: 'BurnDelegate' }), + ], + }).sendAndConfirm(umi); + + const tx = await transferV1(umi, { + asset: assetAddress.publicKey, + newOwner: newOwner.publicKey, + }).sendAndConfirm(umi); + + const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + + const cuResult = { + name: `CU: ${t.title}`, + unit: "Compute Units", + value: compute, + } + + // Read the results array from output.json + let output = []; + if (existsSync("./output.json")) { + output = JSON.parse(readFileSync("./output.json", 'utf-8')); + } + + // Push the result to the array + output.push(cuResult); + // Write the array to output.json + writeFileSync("./output.json", JSON.stringify(output, null, 2)); + + t.pass(); +}); + +test('transfer an asset with plugins and empty collection', async (t) => { + // Given an Umi instance and a new signer. + const umi = await createUmi(); + const collectionAddress = generateSigner(umi); + const assetAddress = generateSigner(umi); + const newOwner = generateSigner(umi); + + let builder = new TransactionBuilder(); + builder = builder.add(createCollectionV1(umi, { + collection: collectionAddress, + name: "Test", + uri: "www.test.com", + })); + builder = builder.add(createV1(umi, { + asset: assetAddress, + name: "Test", + uri: "www.test.com", + plugins: [ + pluginAuthorityPair({ + type: 'Royalties', + data: { + basisPoints: 5, + creators: [{ address: umi.identity.publicKey, percentage: 100 }], + ruleSet: ruleSet('None'), + }, + }), + pluginAuthorityPair({ type: 'FreezeDelegate', data: { frozen: false } }), + pluginAuthorityPair({ type: 'TransferDelegate' }), + pluginAuthorityPair({ type: 'BurnDelegate' }), + ], + })); + + await builder.sendAndConfirm(umi); + + const tx = await transferV1(umi, { + asset: assetAddress.publicKey, + newOwner: newOwner.publicKey, + collection: collectionAddress.publicKey, + }).sendAndConfirm(umi); + + const compute = Number((await umi.rpc.getTransaction(tx.signature))?.meta.computeUnitsConsumed); + const cuResult = { + name: `CU: ${t.title}`, + unit: "Compute Units", + value: compute, + } + + // Read the results array from output.json + let output = []; + if (existsSync("./output.json")) { + output = JSON.parse(readFileSync("./output.json", 'utf-8')); + } + + // Push the result to the array + output.push(cuResult); + // Write the array to output.json + writeFileSync("./output.json", JSON.stringify(output, null, 2)); + + t.pass(); +}); \ No newline at end of file From 60dc07c7d83b636ab0481b534550cfa2a7cfd225 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Apr 2024 13:56:03 -0400 Subject: [PATCH 18/20] Updating workflow. --- .github/workflows/benchmark.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index be26dd3f..aaa9a3d6 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -1,9 +1,6 @@ name: Benchmark on: workflow_call: - push: - branches: - - main permissions: # deployments permission to deploy GitHub pages website From 83bd0c17d2a1c7caf31abf22c7176bc50269ffcd Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Apr 2024 20:10:16 -0400 Subject: [PATCH 19/20] Skipping benchmarks for PRs. --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ddd10ee2..d2c91933 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -111,6 +111,7 @@ jobs: secrets: inherit benchmark: + if: ${{github.event_name}} == 'push' name: Benchmark needs: generate_clients uses: ./.github/workflows/benchmark.yml From 39ff6a490711d72c689718b7d46e3a06effee3ab Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Apr 2024 20:18:52 -0400 Subject: [PATCH 20/20] Trying again. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d2c91933..60ef30a2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -111,7 +111,7 @@ jobs: secrets: inherit benchmark: - if: ${{github.event_name}} == 'push' + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} name: Benchmark needs: generate_clients uses: ./.github/workflows/benchmark.yml