Browse Source

p-token: Add `spl-token` test fixtures (#39)

* Remove unusual test

* Add fixtures test script

* Install solana on fixtures workflow

* Fix review comments
Fernando Otero 6 months ago
parent
commit
da8d9bd364
4 changed files with 125 additions and 27 deletions
  1. 60 0
      .github/workflows/main.yml
  2. 4 1
      package.json
  3. 0 26
      program/tests/processor.rs
  4. 61 0
      scripts/rust/fixtures.mjs

+ 60 - 0
.github/workflows/main.yml

@@ -151,6 +151,35 @@ jobs:
           path: ./**/*.so
           key: ${{ runner.os }}-builds-${{ github.sha }}
 
+  build_ptoken:
+    name: Build p-token
+    runs-on: ubuntu-latest
+    steps:
+      - name: Git Checkout
+        uses: actions/checkout@v4
+
+      - name: Setup Environment
+        uses: ./.github/actions/setup
+        with:
+          cargo-cache-key: cargo-build-program
+          solana: true
+
+      - name: Build
+        run: pnpm p-token:build
+
+      - name: Upload p-token Builds
+        uses: actions/upload-artifact@v4
+        with:
+          name: p-token-builds
+          path: ./target/deploy/*.so
+          if-no-files-found: error
+
+      - name: Save p-token Build For Client Jobs
+        uses: actions/cache/save@v4
+        with:
+          path: ./**/*.so
+          key: ${{ runner.os }}-ptoken-build-${{ github.sha }}
+
   test_client_js:
     name: Test Client JS
     runs-on: ubuntu-latest
@@ -212,3 +241,34 @@ jobs:
 
       - name: Test
         run: pnpm programs:test
+
+  conformance_ptoken:
+    name: Conformance Test for p-token
+    runs-on: ubuntu-latest
+    needs: build_ptoken
+    steps:
+      - name: Git Checkout
+        uses: actions/checkout@v4
+
+      - name: Setup Environment
+        uses: ./.github/actions/setup
+        with:
+          cargo-cache-key: cargo-fixtures-ptoken
+          solana: true
+
+      - name: Restore Program Builds
+        uses: actions/cache/restore@v4
+        with:
+          path: ./**/*.so
+          key: ${{ runner.os }}-ptoken-build-${{ github.sha }}
+
+      - name: Install mollusk-svm-cli
+        uses: taiki-e/cache-cargo-install-action@v2
+        with:
+          tool: mollusk-svm-cli
+
+      - name: Generate SPL Token Fixtures
+        run: pnpm fixtures:generate
+
+      - name: Run Fixtures
+        run: pnpm fixtures:run pinocchio_token_program

+ 4 - 1
package.json

@@ -25,7 +25,10 @@
     "rust:publish": "zx ./scripts/rust/publish.mjs",
     "rust:semver": "cargo semver-checks",
     "p-token:build": "zx ./scripts/rust/build-sbf.mjs p-token",
-    "p-token:test": "zx ./scripts/rust/test.mjs p-token"
+    "p-token:test": "zx ./scripts/rust/test.mjs p-token",
+    "fixtures:clean": "zx ./scripts/rust/fixtures.mjs clean",
+    "fixtures:generate": "zx ./scripts/rust/fixtures.mjs generate",
+    "fixtures:run": "zx ./scripts/rust/fixtures.mjs run"
   },
   "devDependencies": {
     "@codama/renderers-js": "^1.2.7",

+ 0 - 26
program/tests/processor.rs

@@ -5366,32 +5366,6 @@ fn test_overflow() {
     .unwrap();
     let account = Account::unpack_unchecked(&account_account.data).unwrap();
     assert_eq!(account.amount, u64::MAX);
-
-    // manipulate account balance to attempt overflow transfer
-    let mut account = Account::unpack_unchecked(&account2_account.data).unwrap();
-    account.amount = 1;
-    Account::pack(account, &mut account2_account.data).unwrap();
-
-    assert_eq!(
-        Err(TokenError::Overflow.into()),
-        do_process_instruction(
-            transfer(
-                &program_id,
-                &account2_key,
-                &account_key,
-                &owner2_key,
-                &[],
-                1,
-            )
-            .unwrap(),
-            vec![
-                &mut account2_account,
-                &mut account_account,
-                &mut owner2_account,
-            ],
-            &[Check::err(TokenError::Overflow.into())],
-        )
-    );
 }
 
 #[test]

+ 61 - 0
scripts/rust/fixtures.mjs

@@ -0,0 +1,61 @@
+#!/usr/bin/env zx
+import 'zx/globals';
+import { existsSync } from 'fs';
+import { cliArguments, workingDirectory } from '../utils.mjs';
+
+// Directory where the fixtures are generated.
+const FIXTURES_DIR = path.join(workingDirectory, 'target', 'fixtures');
+// Directory of the SPL Token program.
+const SPL_TOKEN_DIR = path.join(workingDirectory, 'program');
+// Directory of the SBF program.
+const SBF_OUTPUT_DIR = path.join(workingDirectory, 'target', 'deploy');
+
+const [command, ...args] = cliArguments();
+
+switch (command) {
+  case 'clean':
+    await clean();
+    break;
+  case 'generate':
+    await generate();
+    break;
+  case 'run':
+    await run(args);
+    break;
+  default:
+    throw new Error(`Unknown command: ${command}`);
+}
+
+async function clean() {
+  await $`rm -rf ${FIXTURES_DIR}`;
+}
+
+async function generate() {
+  if (existsSync(FIXTURES_DIR)) {
+    echo(chalk.yellow('[ WARNING ]'), `Fixtures directory already exists.`);
+  } else {
+    await $`mkdir ${FIXTURES_DIR}`;
+
+    // Fixtures are generated from the SPL Token program.
+    cd(SPL_TOKEN_DIR);
+
+    await $`RUST_LOG=error EJECT_FUZZ_FIXTURES=${FIXTURES_DIR} cargo test-sbf --features mollusk-svm/fuzz`;
+  }
+}
+
+async function run(args) {
+  if (!existsSync(FIXTURES_DIR)) {
+    throw new Error(`Fixtures directory does not exist: ${FIXTURES_DIR}`);
+  }
+
+  const [programName] = args;
+  if (!programName) {
+    throw new Error('The name of the program file must be provided.');
+  }
+
+  await $`mollusk execute-fixture                     \
+    ${path.join(SBF_OUTPUT_DIR, programName + '.so')} \
+    ${FIXTURES_DIR}                                   \
+    TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA       \
+    --ignore-compute-units`;
+}