diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml new file mode 100644 index 000000000..9aa705e02 --- /dev/null +++ b/.github/workflows/bench.yml @@ -0,0 +1,77 @@ +name: Benchmarks + +on: + pull_request: + paths: + - "Cargo.toml" + - "Cargo.lock" + - "rust-toolchain.toml" + - "program/**" + - "cu-bench/**" + - "client/**" + - "interface/**" + - "instruction-macros/**" + - "price/**" + - "services/**" + - "transaction-parser/**" + - ".github/workflows/bench.yml" + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + SOLANA_VERSION: v3.1.9 + +jobs: + bench: + name: CU Benchmarks + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10.30.3 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: pnpm + - uses: dtolnay/rust-toolchain@1.86.0 + - uses: Swatinem/rust-cache@v2 + - run: pnpm install --frozen-lockfile + + - name: Cache Solana toolchain + id: solana-cache + uses: actions/cache@v4 + with: + path: | + ~/.local/share/solana/install + ~/.cache/solana + key: solana-${{ env.SOLANA_VERSION }}-${{ runner.os }} + + - name: Install Solana CLI + if: steps.solana-cache.outputs.cache-hit != 'true' + run: sh -c "$(curl -sSfL https://release.anza.xyz/${SOLANA_VERSION}/install)" + + - name: Add Solana to PATH + run: echo "$HOME/.local/share/solana/install/active_release/bin" >> "$GITHUB_PATH" + + - run: solana --version + + - name: Bench dropset + run: pnpm bench:dropset + - name: Bench manifest + run: pnpm bench:manifest + - name: Bench phoenix + run: pnpm bench:phoenix + - name: Bench pack-orders + run: pnpm bench:pack-orders + - name: Bench to-order-info + run: pnpm bench:to-order-info diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 000000000..0a5d40e3e --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,55 @@ +name: Lint + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + RUSTFLAGS: -D warnings + +jobs: + ts: + name: TS + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10.30.3 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm lint:ts + + rust: + name: Rust + runs-on: ubuntu-latest + timeout-minutes: 25 + steps: + - uses: actions/checkout@v4 + # rustfmt.toml uses unstable_features (imports_granularity, group_imports, + # wrap_comments, ...), so fmt and clippy must run on a pinned nightly. + - uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly-2026-04-15 + components: clippy, rustfmt + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + shared-key: rust-nightly-${{ runner.os }} + - name: cargo fmt --check + run: cargo +nightly-2026-04-15 fmt --all -- --check + - name: cargo clippy -D warnings + run: cargo +nightly-2026-04-15 clippy --workspace --all-targets --locked -- -D warnings diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..64ded8df7 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,65 @@ +name: Test + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + RUSTFLAGS: -D warnings + +jobs: + ts: + name: TS + runs-on: ubuntu-latest + timeout-minutes: 15 + # turbo's `test` task dependsOn `build`, which builds the frontend. + # next build evaluates env validation, so NEXT_PUBLIC_CLUSTER must be set. + env: + NEXT_PUBLIC_CLUSTER: localnet + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10.30.3 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm test:ts + + rust: + name: Rust + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@1.86.0 + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + shared-key: rust-stable-${{ runner.os }} + # instruction-macros-test-fixtures uses macrotest, which shells out to + # `cargo expand` to verify macro output. + - uses: taiki-e/install-action@v2 + with: + tool: cargo-expand + # These crates load pre-built .so files via mollusk; they run in the + # bench workflow with the Solana toolchain installed. + - run: > + cargo test --workspace --locked + --exclude client + --exclude dropset-taker-bot + --exclude cu-bench-dropset + --exclude cu-bench-tests + --exclude cu-bench-pack-orders + --exclude cu-bench-to-order-info diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml new file mode 100644 index 000000000..884501c21 --- /dev/null +++ b/.github/workflows/typecheck.yml @@ -0,0 +1,48 @@ +name: Typecheck + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +permissions: + contents: read + +env: + CARGO_TERM_COLOR: always + RUSTFLAGS: -D warnings + +jobs: + ts: + name: TS + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10.30.3 + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm check:ts + - run: pnpm check:ts:test + + rust: + name: Rust + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@1.86.0 + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + shared-key: rust-stable-${{ runner.os }} + - run: cargo check --workspace --all-targets --locked diff --git a/cu-bench/programs/pack-orders/src/lib.rs b/cu-bench/programs/pack-orders/src/lib.rs index 7bf001f01..0c7103a69 100644 --- a/cu-bench/programs/pack-orders/src/lib.rs +++ b/cu-bench/programs/pack-orders/src/lib.rs @@ -19,6 +19,8 @@ program_entrypoint!(process_instruction); no_allocator!(); nostd_panic_handler!(); +#[cfg(feature = "bench-program-B")] +use borsh::BorshDeserialize; use dropset_interface::state::user_order_sectors::MAX_ORDERS_USIZE; use price::OrderInfoArgs; diff --git a/interface/src/events/tests.rs b/interface/src/events/tests.rs index 8b8aee04b..4d460881a 100644 --- a/interface/src/events/tests.rs +++ b/interface/src/events/tests.rs @@ -52,7 +52,10 @@ fn test_fill_event_tagged_len_matches_written_bytes() { let tagged = event.pack_tagged(); assert_eq!(FillEventInstructionData::LEN, 22); - assert_eq!(FillEventInstructionData::LEN_WITH_TAG, FillEventInstructionData::LEN + 1); + assert_eq!( + FillEventInstructionData::LEN_WITH_TAG, + FillEventInstructionData::LEN + 1 + ); assert_eq!(untagged.len(), FillEventInstructionData::LEN); assert_eq!(tagged.len(), FillEventInstructionData::LEN_WITH_TAG); assert_eq!(tagged[0], FillEventInstructionData::TAG_BYTE); diff --git a/interface/src/state/linked_list.rs b/interface/src/state/linked_list.rs index f2151c883..9048d8c0d 100644 --- a/interface/src/state/linked_list.rs +++ b/interface/src/state/linked_list.rs @@ -167,7 +167,6 @@ impl<'a, T: LinkedListHeaderOperations> LinkedList<'a, T> { /// /// Caller guarantees `index` is in-bounds. pub unsafe fn remove_at(&mut self, index: SectorIndex) { - let num_sectors = self.sectors.len() / Sector::LEN; assert!((index as usize) < num_sectors); let (prev_index, next_index) = {