From 3df3c65037b00ba3b3280849d95a2ebc08bfe3c3 Mon Sep 17 00:00:00 2001 From: "resq-sync[bot]" Date: Fri, 1 May 2026 03:38:07 +0000 Subject: [PATCH] chore: sync from resq-software/resQ@0fd44c3 --- .gitignore | 6 - Cargo.lock | 74 +-- osv-scanner.toml | 58 --- resq-airspace/src/error.rs | 2 +- .../src/instructions/grant_permit.rs | 7 +- .../src/instructions/initialize_property.rs | 10 +- .../src/instructions/record_crossing.rs | 15 +- .../src/instructions/update_policy.rs | 8 +- .../src/instructions/update_treasury.rs | 5 +- resq-airspace/src/lib.rs | 11 +- resq-airspace/src/state/airspace_account.rs | 11 +- resq-airspace/src/state/mod.rs | 2 +- resq-airspace/src/state/permit.rs | 2 +- resq-airspace/tests/host_init_regression.rs | 21 +- resq-airspace/tests/integration.rs | 490 +++++------------- resq-delivery/src/error.rs | 2 +- resq-delivery/src/instructions/mod.rs | 2 +- .../src/instructions/record_delivery.rs | 4 +- resq-delivery/src/lib.rs | 6 +- resq-delivery/src/state/delivery_record.rs | 2 +- resq-delivery/src/state/mod.rs | 2 +- resq-delivery/tests/integration.rs | 61 +-- vendor/solana-program-test/osv-scanner.toml | 93 ---- 23 files changed, 242 insertions(+), 652 deletions(-) delete mode 100644 .gitignore delete mode 100644 osv-scanner.toml delete mode 100644 vendor/solana-program-test/osv-scanner.toml diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8b14544..0000000 --- a/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -target/ -.anchor/ -node_modules/ -test-ledger/ -*.so -.DS_Store diff --git a/Cargo.lock b/Cargo.lock index a08bd99..9dc1f90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,7 +152,7 @@ dependencies = [ "crossbeam-channel", "log", "lz4", - "rand 0.8.6", + "rand 0.8.5", "regex", "semver", "solana-accounts-db", @@ -589,7 +589,7 @@ dependencies = [ "fastbloom", "getrandom 0.3.4", "lru-slab", - "rand 0.9.3", + "rand 0.9.2", "ring", "rustc-hash", "rustls", @@ -853,7 +853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.6", + "rand 0.8.5", ] [[package]] @@ -863,7 +863,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", - "rand 0.8.6", + "rand 0.8.5", ] [[package]] @@ -2051,7 +2051,7 @@ checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" dependencies = [ "getrandom 0.3.4", "libm", - "rand 0.9.3", + "rand 0.9.2", "siphasher 1.0.2", ] @@ -2379,7 +2379,7 @@ dependencies = [ "parking_lot", "portable-atomic", "quanta", - "rand 0.8.6", + "rand 0.8.5", "smallvec", "spinning_top", ] @@ -2391,7 +2391,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand 0.8.6", + "rand 0.8.5", "rand_core 0.6.4", "rand_xorshift", "subtle", @@ -3570,7 +3570,7 @@ dependencies = [ "lazy_static", "percent-encoding", "pin-project", - "rand 0.8.6", + "rand 0.8.5", "thiserror 1.0.69", ] @@ -3905,7 +3905,7 @@ dependencies = [ "bytes", "getrandom 0.3.4", "lru-slab", - "rand 0.9.3", + "rand 0.9.2", "ring", "rustc-hash", "rustls", @@ -3973,9 +3973,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.6" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -3984,9 +3984,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -4378,9 +4378,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.12" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "ring", "rustls-pki-types", @@ -4861,7 +4861,7 @@ dependencies = [ "modular-bitfield", "num_cpus", "num_enum", - "rand 0.8.6", + "rand 0.8.5", "rayon", "seqlock", "serde", @@ -4918,7 +4918,7 @@ dependencies = [ "curve25519-dalek 4.1.3", "five8", "five8_const", - "rand 0.9.3", + "rand 0.9.2", "serde", "serde_derive", "sha2-const-stable", @@ -5082,7 +5082,7 @@ dependencies = [ "ff", "group", "pairing", - "rand 0.8.6", + "rand 0.8.5", "serde", "serde_json", "serde_with", @@ -5157,7 +5157,7 @@ dependencies = [ "memmap2 0.9.10", "modular-bitfield", "num_enum", - "rand 0.8.6", + "rand 0.8.5", "solana-clock", "solana-measure", "solana-pubkey 3.0.0", @@ -5385,7 +5385,7 @@ dependencies = [ "futures-util", "indexmap", "log", - "rand 0.8.6", + "rand 0.8.5", "rayon", "solana-keypair", "solana-measure", @@ -5770,7 +5770,7 @@ dependencies = [ "ed25519-dalek-bip32", "five8", "five8_core", - "rand 0.9.3", + "rand 0.9.2", "solana-address 2.3.0", "solana-derivation-path", "solana-seed-derivable", @@ -5949,7 +5949,7 @@ dependencies = [ "itertools 0.12.1", "log", "nix", - "rand 0.8.6", + "rand 0.8.5", "serde", "socket2", "solana-serde", @@ -6037,7 +6037,7 @@ dependencies = [ "libc", "log", "nix", - "rand 0.8.6", + "rand 0.8.5", "rayon", "serde", "solana-hash 3.1.0", @@ -6218,7 +6218,7 @@ dependencies = [ "itertools 0.12.1", "log", "percentage", - "rand 0.8.6", + "rand 0.8.5", "serde", "solana-account 3.4.0", "solana-account-info", @@ -6322,7 +6322,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8909d399deb0851aa524420beeb5646b115fd253ef446e35fe4504c904da3941" dependencies = [ - "rand 0.8.6", + "rand 0.8.5", "solana-address 1.1.0", ] @@ -6332,7 +6332,7 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b06bd918d60111ee1f97de817113e2040ca0cedb740099ee8d646233f6b906c" dependencies = [ - "rand 0.9.3", + "rand 0.9.2", "solana-address 2.3.0", ] @@ -6593,7 +6593,7 @@ dependencies = [ "num_enum", "percentage", "qualifier_attr", - "rand 0.8.6", + "rand 0.8.5", "rayon", "regex", "semver", @@ -6728,7 +6728,7 @@ dependencies = [ "hash32", "libc", "log", - "rand 0.8.6", + "rand 0.8.5", "rustc-demangle", "thiserror 2.0.18", "winapi", @@ -6946,7 +6946,7 @@ checksum = "132a93134f1262aa832f1849b83bec6c9945669b866da18661a427943b9e801e" dependencies = [ "ed25519-dalek 2.2.0", "five8", - "rand 0.9.3", + "rand 0.9.2", "serde", "serde-big-array", "serde_derive", @@ -7044,7 +7044,7 @@ dependencies = [ "num_cpus", "pem", "percentage", - "rand 0.8.6", + "rand 0.8.5", "rustls", "smallvec", "socket2", @@ -7175,7 +7175,7 @@ version = "3.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b2ea7c2f849cd6d190e2607c2af779d3dad2792784cc13c0e9342e429c87a1" dependencies = [ - "rand 0.8.6", + "rand 0.8.5", ] [[package]] @@ -7487,7 +7487,7 @@ dependencies = [ "base64 0.22.1", "bincode", "log", - "rand 0.8.6", + "rand 0.8.5", "solana-packet", "solana-perf", "solana-short-vec", @@ -7555,7 +7555,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17a9c5d23a31d8f34aac59812099c9d8d76203a447d04b65824f5c913ced9072" dependencies = [ "agave-feature-set", - "rand 0.8.6", + "rand 0.8.5", "semver", "serde", "solana-sanitize", @@ -7682,7 +7682,7 @@ dependencies = [ "merlin", "num-derive", "num-traits", - "rand 0.8.6", + "rand 0.8.5", "serde", "serde_derive", "serde_json", @@ -7734,7 +7734,7 @@ dependencies = [ "merlin", "num-derive", "num-traits", - "rand 0.8.6", + "rand 0.8.5", "serde", "serde_json", "sha3", @@ -8105,7 +8105,7 @@ dependencies = [ "humantime", "opentelemetry", "pin-project", - "rand 0.8.6", + "rand 0.8.5", "serde", "static_assertions", "tarpc-plugins", @@ -8566,7 +8566,7 @@ dependencies = [ "http 1.4.0", "httparse", "log", - "rand 0.9.3", + "rand 0.9.2", "rustls", "rustls-pki-types", "sha1", diff --git a/osv-scanner.toml b/osv-scanner.toml deleted file mode 100644 index 0a293e0..0000000 --- a/osv-scanner.toml +++ /dev/null @@ -1,58 +0,0 @@ -# OSV-Scanner configuration for resq-software/programs. -# -# Each [[IgnoredVulns]] block carries a rationale for why the advisory cannot -# be fixed in this workspace today. Revisit on any Solana / Anchor major bump. -# -# Format: https://google.github.io/osv-scanner/configuration/ -# Note: OSV-Scanner v2 expects PascalCase keys (IgnoredVulns); snake_case is rejected. - -# ── Unmaintained-crate advisories (informational, no known exploit) ────────── - -[[IgnoredVulns]] -id = "RUSTSEC-2025-0141" -# bincode 1.3.3 is unmaintained; bincode 2.x is available but breaks the -# Anchor 1.0.0-rc.2 serialization API. Blocked on Anchor upstream migration. -reason = "bincode 1.x transitive via anchor-lang; await upstream Anchor bump to bincode 2.x" - -[[IgnoredVulns]] -id = "RUSTSEC-2024-0388" -# derivative is unmaintained. Transitive via anchor-lang's macro machinery. -reason = "derivative 2.2.0 transitive via anchor-lang; await upstream migration to derive-more or similar" - -[[IgnoredVulns]] -id = "RUSTSEC-2024-0436" -# paste is unmaintained. Transitive via anchor-lang macros. -reason = "paste 1.0.15 transitive via anchor-lang macros; await upstream migration" - -[[IgnoredVulns]] -id = "RUSTSEC-2025-0161" -# libsecp256k1 0.6.0 is effectively frozen; Solana pins this version. -reason = "libsecp256k1 0.6.0 transitive via solana-* crates; fix requires upstream Solana bump" - -# ── Old dalek / rand pins (transitive via Solana; on-chain BPF unaffected) ─── - -[[IgnoredVulns]] -id = "RUSTSEC-2024-0344" -# curve25519-dalek 3.2.0 has a timing side channel in Scalar::from_canonical_bytes. -# Pinned by solana-zk-token-sdk and older solana-program versions which we pull -# transitively. On-chain BPF code does not execute this crate (programs verify -# via syscalls, not userspace dalek). Risk is confined to host-side tests. -reason = "curve25519-dalek 3.2.0 transitive via solana-zk-token-sdk; on-chain BPF unaffected; await upstream Solana bump to dalek 4.x across the stack" - -[[IgnoredVulns]] -id = "RUSTSEC-2022-0093" -# ed25519-dalek 1.0.1 has a signature-oracle vulnerability in specific API misuse -# patterns. Programs in this workspace never call ed25519-dalek directly; it comes -# in via vendored solana-program-test (a dev-dependency only). -reason = "ed25519-dalek 1.0.1 transitive via vendored solana-program-test (dev-dep only); on-chain programs do not call dalek directly" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0097" -# rand 0.7.3 is unsound when rand::rng() is called with a custom logger installed. -# We pin rand 0.7.3 only transitively via old solana-* deps. No workspace code uses -# custom loggers with rand; the 0.8.x and 0.9.x pins are already on fixed versions. -reason = "rand 0.7.3 transitive via solana-* deps; fixed versions (0.8.6, 0.9.3) already pinned for first-order users; no custom-logger code paths" - -# Vendor-only advisories live in vendor/solana-program-test/osv-scanner.toml. -# OSV-scanner treats each discovered lockfile directory as its own scan-config -# scope, so vendor entries here would be reported as "unused ignores". diff --git a/resq-airspace/src/error.rs b/resq-airspace/src/error.rs index c49f6e9..020213c 100644 --- a/resq-airspace/src/error.rs +++ b/resq-airspace/src/error.rs @@ -69,4 +69,4 @@ pub enum AirspaceError { /// drone_pda is the zero address; no key can sign as the default pubkey. #[msg("Drone PDA must not be the zero address")] InvalidDronePda, -} +} \ No newline at end of file diff --git a/resq-airspace/src/instructions/grant_permit.rs b/resq-airspace/src/instructions/grant_permit.rs index 1525f9c..cc534f9 100644 --- a/resq-airspace/src/instructions/grant_permit.rs +++ b/resq-airspace/src/instructions/grant_permit.rs @@ -53,10 +53,7 @@ pub struct GrantPermit<'info> { /// * `drone_pda` – the drone's Program-Derived Address /// * `expires_at` – Unix timestamp when the permit expires (0 = never) pub fn handler(ctx: Context, drone_pda: Pubkey, expires_at: i64) -> Result<()> { - require!( - drone_pda != Pubkey::default(), - AirspaceError::InvalidDronePda - ); + require!(drone_pda != Pubkey::default(), AirspaceError::InvalidDronePda); let clock = Clock::get()?; require!( expires_at == 0 || expires_at > clock.unix_timestamp, @@ -90,4 +87,4 @@ pub struct PermitGranted { pub airspace_pda: Pubkey, pub drone_pda: Pubkey, pub expires_at: i64, -} +} \ No newline at end of file diff --git a/resq-airspace/src/instructions/initialize_property.rs b/resq-airspace/src/instructions/initialize_property.rs index 5e6487c..05a1d99 100644 --- a/resq-airspace/src/instructions/initialize_property.rs +++ b/resq-airspace/src/instructions/initialize_property.rs @@ -52,7 +52,6 @@ pub struct InitializeProperty<'info> { /// * `policy` – `AccessPolicy` enum value /// * `fee_lamports` – per-crossing fee (0 = free) /// * `treasury` – SOL account that receives crossing fees -#[allow(clippy::too_many_arguments)] pub fn handler( ctx: Context, property_id: [u8; 32], @@ -67,13 +66,10 @@ pub fn handler( require!(property_id != [0u8; 32], AirspaceError::EmptyPropertyId); require!(min_alt_m < max_alt_m, AirspaceError::InvalidAltitudeBounds); require!( - (1..=8).contains(&vertex_count), + vertex_count >= 1 && vertex_count <= 8, AirspaceError::InvalidVertexCount ); - require!( - treasury != Pubkey::default(), - AirspaceError::InvalidTreasury - ); + require!(treasury != Pubkey::default(), AirspaceError::InvalidTreasury); let airspace_pda = ctx.accounts.airspace.key(); let owner_key = ctx.accounts.owner.key(); @@ -105,4 +101,4 @@ pub struct PropertyInitialized { pub airspace_pda: Pubkey, pub owner: Pubkey, pub property_id: [u8; 32], -} +} \ No newline at end of file diff --git a/resq-airspace/src/instructions/record_crossing.rs b/resq-airspace/src/instructions/record_crossing.rs index 29f9c42..25cef34 100644 --- a/resq-airspace/src/instructions/record_crossing.rs +++ b/resq-airspace/src/instructions/record_crossing.rs @@ -62,11 +62,11 @@ pub struct RecordCrossing<'info> { /// - `Deny` – always rejected. /// /// # Arguments -/// * `lat` – latitude × 1e7 (range -900_000_000 to +900_000_000) -/// * `lon` – longitude × 1e7 (range -1_800_000_000 to +1_800_000_000) +/// * `lat` – latitude × 1e7 (range −900_000_000 to +900_000_000) +/// * `lon` – longitude × 1e7 (range −1_800_000_000 to +1_800_000_000) /// * `alt_m` – altitude in metres (enforced against airspace altitude bounds) /// * `crossed_at` – Unix timestamp (seconds) of the crossing; must be within the -/// 5-minute look-back window and no more than 60 seconds ahead +/// 5-minute look-back window and no more than 60 seconds ahead pub fn handler( ctx: Context, lat: i64, @@ -95,11 +95,11 @@ pub fn handler( // Coordinate range validation (mirrors record_delivery). require!( - (-900_000_000..=900_000_000).contains(&lat), + lat >= -900_000_000 && lat <= 900_000_000, AirspaceError::LatitudeOutOfRange ); require!( - (-1_800_000_000..=1_800_000_000).contains(&lon), + lon >= -1_800_000_000 && lon <= 1_800_000_000, AirspaceError::LongitudeOutOfRange ); @@ -123,10 +123,7 @@ pub fn handler( .permit .as_ref() .ok_or(AirspaceError::NoValidPermit)?; - require!( - permit.is_active(clock.unix_timestamp), - AirspaceError::PermitExpired - ); + require!(permit.is_active(clock.unix_timestamp), AirspaceError::PermitExpired); // Collect per-crossing fee when configured. if airspace.fee_lamports > 0 { diff --git a/resq-airspace/src/instructions/update_policy.rs b/resq-airspace/src/instructions/update_policy.rs index ad3c2d0..99eadf1 100644 --- a/resq-airspace/src/instructions/update_policy.rs +++ b/resq-airspace/src/instructions/update_policy.rs @@ -37,7 +37,11 @@ pub struct UpdatePolicy<'info> { /// Update the access policy and/or per-crossing fee for an airspace. /// /// Only the registered owner may call this instruction. -pub fn handler(ctx: Context, policy: AccessPolicy, fee_lamports: u64) -> Result<()> { +pub fn handler( + ctx: Context, + policy: AccessPolicy, + fee_lamports: u64, +) -> Result<()> { let airspace = &mut ctx.accounts.airspace; airspace.policy = policy; airspace.fee_lamports = fee_lamports; @@ -57,4 +61,4 @@ pub struct PolicyUpdated { pub airspace_pda: Pubkey, pub policy: AccessPolicy, pub fee_lamports: u64, -} +} \ No newline at end of file diff --git a/resq-airspace/src/instructions/update_treasury.rs b/resq-airspace/src/instructions/update_treasury.rs index 9cf99f5..264838f 100644 --- a/resq-airspace/src/instructions/update_treasury.rs +++ b/resq-airspace/src/instructions/update_treasury.rs @@ -38,10 +38,7 @@ pub struct UpdateTreasury<'info> { /// # Arguments /// * `treasury` – new SOL account that will receive crossing fees pub fn handler(ctx: Context, treasury: Pubkey) -> Result<()> { - require!( - treasury != Pubkey::default(), - AirspaceError::InvalidTreasury - ); + require!(treasury != Pubkey::default(), AirspaceError::InvalidTreasury); ctx.accounts.airspace.treasury = treasury; emit!(TreasuryUpdated { diff --git a/resq-airspace/src/lib.rs b/resq-airspace/src/lib.rs index 28b4055..17adb8e 100644 --- a/resq-airspace/src/lib.rs +++ b/resq-airspace/src/lib.rs @@ -1,8 +1,4 @@ -#![allow( - unexpected_cfgs, - clippy::too_many_arguments, - clippy::diverging_sub_expression -)] +#![allow(unexpected_cfgs)] /* * Copyright 2026 ResQ @@ -106,7 +102,10 @@ pub mod resq_airspace { /// /// This is the only recovery path when the owner key is compromised or /// needs to be rotated. After this call the old owner has no authority. - pub fn transfer_ownership(ctx: Context, new_owner: Pubkey) -> Result<()> { + pub fn transfer_ownership( + ctx: Context, + new_owner: Pubkey, + ) -> Result<()> { instructions::transfer_ownership::handler(ctx, new_owner) } } diff --git a/resq-airspace/src/state/airspace_account.rs b/resq-airspace/src/state/airspace_account.rs index f93d28d..724fbe4 100644 --- a/resq-airspace/src/state/airspace_account.rs +++ b/resq-airspace/src/state/airspace_account.rs @@ -17,10 +17,9 @@ use anchor_lang::prelude::*; /// Access policy for an airspace envelope. -#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Eq, Debug, Default)] +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, PartialEq, Eq, Debug)] pub enum AccessPolicy { /// Any drone may transit without a permit or fee. - #[default] Open = 0, /// A drone must hold a valid `Permit` account to transit. Permit = 1, @@ -30,6 +29,12 @@ pub enum AccessPolicy { Auction = 3, } +impl Default for AccessPolicy { + fn default() -> Self { + AccessPolicy::Open + } +} + /// Per-property 3D airspace envelope registered on-chain. /// /// PDA seeds: `["airspace", property_id_bytes]` @@ -77,4 +82,4 @@ pub struct AirspaceAccount { impl AirspaceAccount { /// Account size in bytes (discriminator + fields). pub const LEN: usize = 8 + 32 + 32 + 4 + 4 + 128 + 1 + 1 + 8 + 32 + 1; -} +} \ No newline at end of file diff --git a/resq-airspace/src/state/mod.rs b/resq-airspace/src/state/mod.rs index d552198..ec89797 100644 --- a/resq-airspace/src/state/mod.rs +++ b/resq-airspace/src/state/mod.rs @@ -15,4 +15,4 @@ */ pub mod airspace_account; -pub mod permit; +pub mod permit; \ No newline at end of file diff --git a/resq-airspace/src/state/permit.rs b/resq-airspace/src/state/permit.rs index ce227a7..3beab66 100644 --- a/resq-airspace/src/state/permit.rs +++ b/resq-airspace/src/state/permit.rs @@ -53,4 +53,4 @@ impl Permit { pub fn is_active(&self, now: i64) -> bool { self.expires_at == 0 || self.expires_at > now } -} +} \ No newline at end of file diff --git a/resq-airspace/tests/host_init_regression.rs b/resq-airspace/tests/host_init_regression.rs index 326a714..56fe3f4 100644 --- a/resq-airspace/tests/host_init_regression.rs +++ b/resq-airspace/tests/host_init_regression.rs @@ -1,9 +1,3 @@ -#![allow( - clippy::needless_pass_by_value, - unused_imports, - unused_mut, - clippy::missing_transmute_annotations -)] /* * Copyright 2026 ResQ * @@ -22,19 +16,22 @@ use anchor_lang::{ prelude::{AccountMeta as AnchorAccountMeta, Pubkey as AnchorPubkey}, - system_program as anchor_system_program, AccountDeserialize, InstructionData, ToAccountMetas, + system_program as anchor_system_program, + AccountDeserialize, + InstructionData, + ToAccountMetas, }; use resq_airspace::state::airspace_account::{AccessPolicy, AirspaceAccount}; use solana_account_info::AccountInfo; use solana_instruction::{AccountMeta, Instruction}; use solana_keypair::Keypair; -use solana_program_entrypoint::ProgramResult; use solana_program_test::{processor, ProgramTest}; use solana_pubkey::Pubkey; use solana_sdk::program_error::ProgramError; use solana_signer::Signer; use solana_system_interface::instruction as system_instruction; use solana_transaction::Transaction; +use solana_program_entrypoint::ProgramResult; #[allow(unsafe_code)] fn process_instruction( @@ -64,8 +61,7 @@ fn anchor_pubkey(value: Pubkey) -> AnchorPubkey { } fn sdk_account_metas(value: Vec) -> Vec { - value - .into_iter() + value.into_iter() .map(|meta| { let pubkey = sdk_pubkey(meta.pubkey); if meta.is_writable { @@ -78,10 +74,7 @@ fn sdk_account_metas(value: Vec) -> Vec { } fn airspace_pda(property_id: &[u8; 32]) -> (Pubkey, u8) { - Pubkey::find_program_address( - &[b"airspace", property_id], - &sdk_pubkey(resq_airspace::id()), - ) + Pubkey::find_program_address(&[b"airspace", property_id], &sdk_pubkey(resq_airspace::id())) } #[tokio::test] diff --git a/resq-airspace/tests/integration.rs b/resq-airspace/tests/integration.rs index 97d5471..fe2e1d1 100644 --- a/resq-airspace/tests/integration.rs +++ b/resq-airspace/tests/integration.rs @@ -1,11 +1,3 @@ -#![allow( - clippy::needless_pass_by_value, - clippy::needless_borrow, - clippy::too_many_arguments, - clippy::missing_transmute_annotations, - unused_imports, - unused_mut -)] /* * Copyright 2026 ResQ * @@ -22,22 +14,26 @@ * limitations under the License. */ -use anchor_lang::{AccountDeserialize, InstructionData, ToAccountMetas}; +use anchor_lang::{InstructionData, ToAccountMetas, AccountDeserialize}; +use solana_program_test::*; +use solana_sdk::{ + instruction::Instruction, + pubkey::Pubkey, + signature::Keypair, + signer::Signer, + sysvar::clock::Clock, + transaction::Transaction, +}; use solana_account_info::AccountInfo; use solana_instruction::{AccountMeta, Instruction as SolanaInstruction}; use solana_keypair::Keypair as SolanaKeypair; -use solana_program_entrypoint::ProgramResult; -use solana_program_test::*; use solana_program_test::{processor, ProgramTest}; use solana_pubkey::Pubkey as SolanaPubkey; use solana_sdk::program_error::ProgramError; -use solana_sdk::{ - instruction::Instruction, pubkey::Pubkey, signature::Keypair, signer::Signer, - sysvar::clock::Clock, transaction::Transaction, -}; use solana_signer::Signer as SolanaSigner; use solana_system_interface::instruction as system_instruction; use solana_transaction::Transaction as SolanaTransaction; +use solana_program_entrypoint::ProgramResult; use resq_airspace::state::airspace_account::{AccessPolicy, AirspaceAccount}; use resq_airspace::state::permit::Permit; @@ -64,8 +60,7 @@ fn anchor_pubkey(value: SolanaPubkey) -> anchor_lang::prelude::Pubkey { } fn sdk_account_metas(value: Vec) -> Vec { - value - .into_iter() + value.into_iter() .map(|meta| { let pubkey = sdk_pubkey(meta.pubkey); if meta.is_writable { @@ -163,8 +158,7 @@ async fn test_initialize_property_happy_path() { 1, // vertex count AccessPolicy::Open, 0, // fee - ) - .await; + ).await; // Airdrop some SOL to owner for rent let mut tx = SolanaTransaction::new_with_payer( @@ -178,8 +172,7 @@ async fn test_initialize_property_happy_path() { banks_client.process_transaction(tx).await.unwrap(); let account = banks_client.get_account(pda).await.unwrap().unwrap(); - let acc: AirspaceAccount = - AirspaceAccount::try_deserialize(&mut account.data.as_slice()).unwrap(); + let acc: AirspaceAccount = AirspaceAccount::try_deserialize(&mut account.data.as_slice()).unwrap(); assert_eq!(sdk_pubkey(acc.owner), owner.pubkey()); assert_eq!(acc.policy, AccessPolicy::Open); @@ -211,8 +204,7 @@ async fn test_initialize_rejects_empty_property_id() { 1, AccessPolicy::Open, 0, - ) - .await; + ).await; let mut tx = SolanaTransaction::new_with_payer( &[ @@ -224,10 +216,7 @@ async fn test_initialize_rejects_empty_property_id() { tx.sign(&[&payer, &owner], recent_blockhash); let err = banks_client.process_transaction(tx).await.unwrap_err(); - assert!( - err.unwrap().to_string().contains("EmptyPropertyId") - || format!("{:?}", err).contains("Custom(6001)") - ); + assert!(err.unwrap().to_string().contains("EmptyPropertyId") || format!("{:?}", err).contains("Custom(6001)")); } #[tokio::test] @@ -253,8 +242,7 @@ async fn test_grant_permit_happy_path() { 1, AccessPolicy::Permit, 0, - ) - .await; + ).await; let drone = Keypair::new(); let (p_pda, _) = permit_pda(&airspace_pubkey, &drone.pubkey()); @@ -262,16 +250,14 @@ async fn test_grant_permit_happy_path() { let grant_data = resq_airspace::instruction::GrantPermit { drone_pda: anchor_pubkey(drone.pubkey()), expires_at: 0, - } - .data(); + }.data(); let grant_accounts = resq_airspace::accounts::GrantPermit { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: anchor_pubkey(p_pda), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let grant_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), @@ -323,8 +309,7 @@ async fn test_record_crossing_open_policy() { 1, AccessPolicy::Open, 0, - ) - .await; + ).await; // Create airspace account let mut tx1 = SolanaTransaction::new_with_payer( @@ -344,21 +329,22 @@ async fn test_record_crossing_open_policy() { let grant_data = resq_airspace::instruction::GrantPermit { drone_pda: anchor_pubkey(drone.pubkey()), expires_at: 0, - } - .data(); + }.data(); let grant_accounts = resq_airspace::accounts::GrantPermit { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: anchor_pubkey(p_pda), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let grant_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(grant_accounts), data: grant_data, }; - let mut tx_grant = SolanaTransaction::new_with_payer(&[grant_ix], Some(&payer.pubkey())); + let mut tx_grant = SolanaTransaction::new_with_payer( + &[grant_ix], + Some(&payer.pubkey()), + ); let recent_blockhash2 = banks_client.get_latest_blockhash().await.unwrap(); tx_grant.sign(&[&payer, &owner], recent_blockhash2); banks_client.process_transaction(tx_grant).await.unwrap(); @@ -373,8 +359,7 @@ async fn test_record_crossing_open_policy() { lon: -740060000, alt_m: 50, crossed_at, - } - .data(); + }.data(); // Open policy does not require a permit; pass None. let cross_accounts = resq_airspace::accounts::RecordCrossing { @@ -383,8 +368,7 @@ async fn test_record_crossing_open_policy() { permit: None, treasury: anchor_pubkey(treasury.pubkey()), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let cross_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), @@ -429,8 +413,7 @@ async fn test_record_crossing_deny_policy() { 1, AccessPolicy::Deny, 0, - ) - .await; + ).await; let mut tx1 = SolanaTransaction::new_with_payer( &[ @@ -448,21 +431,21 @@ async fn test_record_crossing_deny_policy() { let grant_data = resq_airspace::instruction::GrantPermit { drone_pda: anchor_pubkey(drone.pubkey()), expires_at: 0, - } - .data(); + }.data(); let grant_accounts = resq_airspace::accounts::GrantPermit { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: anchor_pubkey(p_pda), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let mut tx_grant = SolanaTransaction::new_with_payer( - &[SolanaInstruction { - program_id: sdk_pubkey(resq_airspace::id()), - accounts: sdk_account_metas(grant_accounts), - data: grant_data, - }], + &[ + SolanaInstruction { + program_id: sdk_pubkey(resq_airspace::id()), + accounts: sdk_account_metas(grant_accounts), + data: grant_data, + } + ], Some(&payer.pubkey()), ); let recent_blockhash_grant = banks_client.get_latest_blockhash().await.unwrap(); @@ -479,8 +462,7 @@ async fn test_record_crossing_deny_policy() { lon: 0, alt_m: 50, // within min_alt_m=0, max_alt_m=100 crossed_at, - } - .data(); + }.data(); let cross_accounts = resq_airspace::accounts::RecordCrossing { drone: anchor_pubkey(drone.pubkey()), @@ -488,8 +470,7 @@ async fn test_record_crossing_deny_policy() { permit: Some(anchor_pubkey(p_pda)), treasury: anchor_pubkey(treasury.pubkey()), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let cross_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), @@ -509,10 +490,7 @@ async fn test_record_crossing_deny_policy() { tx2.sign(&[&payer, &drone], recent_blockhash2); let err = banks_client.process_transaction(tx2).await.unwrap_err(); - assert!( - err.unwrap().to_string().contains("NoValidPermit") - || format!("{:?}", err).contains("Custom(6004)") - ); + assert!(err.unwrap().to_string().contains("NoValidPermit") || format!("{:?}", err).contains("Custom(6004)")); } #[tokio::test] @@ -538,20 +516,17 @@ async fn test_update_policy() { 1, AccessPolicy::Open, 0, - ) - .await; + ).await; let update_data = resq_airspace::instruction::UpdatePolicy { policy: AccessPolicy::Deny, fee_lamports: 0, - } - .data(); + }.data(); let update_accounts = resq_airspace::accounts::UpdatePolicy { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), - } - .to_account_metas(None); + }.to_account_metas(None); let update_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), @@ -570,13 +545,8 @@ async fn test_update_policy() { tx.sign(&[&payer, &owner], recent_blockhash); banks_client.process_transaction(tx).await.unwrap(); - let account = banks_client - .get_account(airspace_pubkey) - .await - .unwrap() - .unwrap(); - let acc: AirspaceAccount = - AirspaceAccount::try_deserialize(&mut account.data.as_slice()).unwrap(); + let account = banks_client.get_account(airspace_pubkey).await.unwrap().unwrap(); + let acc: AirspaceAccount = AirspaceAccount::try_deserialize(&mut account.data.as_slice()).unwrap(); assert_eq!(acc.policy, AccessPolicy::Deny); } @@ -597,30 +567,19 @@ async fn test_close_permit_happy_path() { let (p_pda, _) = permit_pda(&airspace_pubkey, &drone.pubkey()); let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &owner.pubkey(), - pid, - 0, - 100, - 1, - AccessPolicy::Permit, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &owner.pubkey(), + pid, 0, 100, 1, AccessPolicy::Permit, 0, + ).await; let grant_data = resq_airspace::instruction::GrantPermit { - drone_pda: anchor_pubkey(drone.pubkey()), - expires_at: 0, - } - .data(); + drone_pda: anchor_pubkey(drone.pubkey()), expires_at: 0, + }.data(); let grant_accounts = resq_airspace::accounts::GrantPermit { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: anchor_pubkey(p_pda), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let grant_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(grant_accounts), @@ -628,11 +587,7 @@ async fn test_close_permit_happy_path() { }; let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), - init_ix, - grant_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), init_ix, grant_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &owner], recent_blockhash); @@ -647,8 +602,7 @@ async fn test_close_permit_happy_path() { airspace: anchor_pubkey(airspace_pubkey), permit: anchor_pubkey(p_pda), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let close_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(close_accounts), @@ -681,30 +635,19 @@ async fn test_close_permit_rejects_non_owner() { let (p_pda, _) = permit_pda(&airspace_pubkey, &drone.pubkey()); let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &owner.pubkey(), - pid, - 0, - 100, - 1, - AccessPolicy::Permit, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &owner.pubkey(), + pid, 0, 100, 1, AccessPolicy::Permit, 0, + ).await; let grant_data = resq_airspace::instruction::GrantPermit { - drone_pda: anchor_pubkey(drone.pubkey()), - expires_at: 0, - } - .data(); + drone_pda: anchor_pubkey(drone.pubkey()), expires_at: 0, + }.data(); let grant_accounts = resq_airspace::accounts::GrantPermit { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: anchor_pubkey(p_pda), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let grant_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(grant_accounts), @@ -715,8 +658,7 @@ async fn test_close_permit_rejects_non_owner() { &[ system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), system_instruction::transfer(&payer.pubkey(), &attacker.pubkey(), 1_000_000_000), - init_ix, - grant_ix, + init_ix, grant_ix, ], Some(&payer.pubkey()), ); @@ -730,8 +672,7 @@ async fn test_close_permit_rejects_non_owner() { airspace: anchor_pubkey(airspace_pubkey), permit: anchor_pubkey(p_pda), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let close_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(close_accounts), @@ -765,27 +706,17 @@ async fn test_update_treasury_happy_path() { let (airspace_pubkey, _) = airspace_pda(&pid); let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &owner.pubkey(), - pid, - 0, - 100, - 1, - AccessPolicy::Open, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &owner.pubkey(), + pid, 0, 100, 1, AccessPolicy::Open, 0, + ).await; let upd_data = resq_airspace::instruction::UpdateTreasury { treasury: anchor_pubkey(new_treasury.pubkey()), - } - .data(); + }.data(); let upd_accounts = resq_airspace::accounts::UpdateTreasury { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), - } - .to_account_metas(None); + }.to_account_metas(None); let upd_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(upd_accounts), @@ -793,23 +724,14 @@ async fn test_update_treasury_happy_path() { }; let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), - init_ix, - upd_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), init_ix, upd_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &owner], recent_blockhash); banks_client.process_transaction(tx).await.unwrap(); - let account = banks_client - .get_account(airspace_pubkey) - .await - .unwrap() - .unwrap(); - let acc: AirspaceAccount = - AirspaceAccount::try_deserialize(&mut account.data.as_slice()).unwrap(); + let account = banks_client.get_account(airspace_pubkey).await.unwrap().unwrap(); + let acc: AirspaceAccount = AirspaceAccount::try_deserialize(&mut account.data.as_slice()).unwrap(); assert_eq!(sdk_pubkey(acc.treasury), new_treasury.pubkey()); } @@ -827,27 +749,17 @@ async fn test_update_treasury_rejects_zero_address() { let (airspace_pubkey, _) = airspace_pda(&pid); let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &owner.pubkey(), - pid, - 0, - 100, - 1, - AccessPolicy::Open, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &owner.pubkey(), + pid, 0, 100, 1, AccessPolicy::Open, 0, + ).await; let upd_data = resq_airspace::instruction::UpdateTreasury { treasury: anchor_lang::prelude::Pubkey::default(), - } - .data(); + }.data(); let upd_accounts = resq_airspace::accounts::UpdateTreasury { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), - } - .to_account_metas(None); + }.to_account_metas(None); let upd_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(upd_accounts), @@ -855,11 +767,7 @@ async fn test_update_treasury_rejects_zero_address() { }; let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), - init_ix, - upd_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), init_ix, upd_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &owner], recent_blockhash); @@ -886,27 +794,17 @@ async fn test_transfer_ownership_happy_path() { let (airspace_pubkey, _) = airspace_pda(&pid); let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &owner.pubkey(), - pid, - 0, - 100, - 1, - AccessPolicy::Open, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &owner.pubkey(), + pid, 0, 100, 1, AccessPolicy::Open, 0, + ).await; let xfer_data = resq_airspace::instruction::TransferOwnership { new_owner: anchor_pubkey(new_owner.pubkey()), - } - .data(); + }.data(); let xfer_accounts = resq_airspace::accounts::TransferOwnership { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), - } - .to_account_metas(None); + }.to_account_metas(None); let xfer_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(xfer_accounts), @@ -914,36 +812,24 @@ async fn test_transfer_ownership_happy_path() { }; let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), - init_ix, - xfer_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), init_ix, xfer_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &owner], recent_blockhash); banks_client.process_transaction(tx).await.unwrap(); - let account = banks_client - .get_account(airspace_pubkey) - .await - .unwrap() - .unwrap(); - let acc: AirspaceAccount = - AirspaceAccount::try_deserialize(&mut account.data.as_slice()).unwrap(); + let account = banks_client.get_account(airspace_pubkey).await.unwrap().unwrap(); + let acc: AirspaceAccount = AirspaceAccount::try_deserialize(&mut account.data.as_slice()).unwrap(); assert_eq!(sdk_pubkey(acc.owner), new_owner.pubkey()); // New owner can use owner-only instructions; old owner cannot. let upd_data = resq_airspace::instruction::UpdatePolicy { - policy: AccessPolicy::Deny, - fee_lamports: 0, - } - .data(); + policy: AccessPolicy::Deny, fee_lamports: 0, + }.data(); let upd_accounts_new = resq_airspace::accounts::UpdatePolicy { owner: anchor_pubkey(new_owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), - } - .to_account_metas(None); + }.to_account_metas(None); let upd_ix_new = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(upd_accounts_new), @@ -952,10 +838,7 @@ async fn test_transfer_ownership_happy_path() { let recent_blockhash2 = banks_client.get_latest_blockhash().await.unwrap(); let mut tx2 = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &new_owner.pubkey(), 1_000_000_000), - upd_ix_new, - ], + &[system_instruction::transfer(&payer.pubkey(), &new_owner.pubkey(), 1_000_000_000), upd_ix_new], Some(&payer.pubkey()), ); tx2.sign(&[&payer, &new_owner], recent_blockhash2); @@ -965,8 +848,7 @@ async fn test_transfer_ownership_happy_path() { let upd_accounts_old = resq_airspace::accounts::UpdatePolicy { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), - } - .to_account_metas(None); + }.to_account_metas(None); let upd_ix_old = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(upd_accounts_old), @@ -999,27 +881,17 @@ async fn test_transfer_ownership_rejects_zero_address() { let (airspace_pubkey, _) = airspace_pda(&pid); let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &owner.pubkey(), - pid, - 0, - 100, - 1, - AccessPolicy::Open, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &owner.pubkey(), + pid, 0, 100, 1, AccessPolicy::Open, 0, + ).await; let xfer_data = resq_airspace::instruction::TransferOwnership { new_owner: anchor_lang::prelude::Pubkey::default(), - } - .data(); + }.data(); let xfer_accounts = resq_airspace::accounts::TransferOwnership { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), - } - .to_account_metas(None); + }.to_account_metas(None); let xfer_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(xfer_accounts), @@ -1027,11 +899,7 @@ async fn test_transfer_ownership_rejects_zero_address() { }; let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), - init_ix, - xfer_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), init_ix, xfer_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &owner], recent_blockhash); @@ -1060,30 +928,19 @@ async fn test_grant_permit_rejects_zero_drone_pda() { let (p_pda, _) = permit_pda(&airspace_pubkey, &sdk_pubkey(zero_key)); let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &owner.pubkey(), - pid, - 0, - 100, - 1, - AccessPolicy::Permit, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &owner.pubkey(), + pid, 0, 100, 1, AccessPolicy::Permit, 0, + ).await; let grant_data = resq_airspace::instruction::GrantPermit { - drone_pda: zero_key, - expires_at: 0, - } - .data(); + drone_pda: zero_key, expires_at: 0, + }.data(); let grant_accounts = resq_airspace::accounts::GrantPermit { owner: anchor_pubkey(owner.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: anchor_pubkey(p_pda), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let grant_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), accounts: sdk_account_metas(grant_accounts), @@ -1091,11 +948,7 @@ async fn test_grant_permit_rejects_zero_drone_pda() { }; let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), - init_ix, - grant_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), init_ix, grant_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &owner], recent_blockhash); @@ -1123,23 +976,12 @@ async fn setup_open_airspace( let treasury = owner.pubkey(); // owner doubles as treasury for Open/no-fee airspaces let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &treasury, - pid, - min_alt_m, - max_alt_m, - 1, - AccessPolicy::Open, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &treasury, + pid, min_alt_m, max_alt_m, 1, AccessPolicy::Open, 0, + ).await; let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), - init_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), init_ix], Some(&payer.pubkey()), ); tx.sign(&[payer, owner], recent_blockhash); @@ -1150,36 +992,30 @@ async fn setup_open_airspace( #[tokio::test] async fn test_record_crossing_rejects_old_timestamp() { let program = ProgramTest::new( - "resq_airspace", - sdk_pubkey(resq_airspace::id()), - processor!(process_instruction), + "resq_airspace", sdk_pubkey(resq_airspace::id()), processor!(process_instruction), ); let (banks_client, payer, recent_blockhash) = program.start().await; let owner = Keypair::new(); let drone = Keypair::new(); let pid = str_to_bytes32("cross-old-ts"); - let airspace_pubkey = - setup_open_airspace(&banks_client, &payer, &owner, pid, 0, 200, recent_blockhash).await; + let airspace_pubkey = setup_open_airspace( + &banks_client, &payer, &owner, pid, 0, 200, recent_blockhash, + ).await; let clock: Clock = banks_client.get_sysvar().await.unwrap(); // 6 minutes in the past — outside the 5-minute look-back window. let crossed_at = clock.unix_timestamp - 360; let cross_data = resq_airspace::instruction::RecordCrossing { - lat: 0, - lon: 0, - alt_m: 50, - crossed_at, - } - .data(); + lat: 0, lon: 0, alt_m: 50, crossed_at, + }.data(); let cross_accounts = resq_airspace::accounts::RecordCrossing { drone: anchor_pubkey(drone.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: None, treasury: anchor_pubkey(owner.pubkey()), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let cross_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), @@ -1188,10 +1024,7 @@ async fn test_record_crossing_rejects_old_timestamp() { }; let recent_blockhash2 = banks_client.get_latest_blockhash().await.unwrap(); let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &drone.pubkey(), 1_000_000_000), - cross_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &drone.pubkey(), 1_000_000_000), cross_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &drone], recent_blockhash2); @@ -1206,36 +1039,30 @@ async fn test_record_crossing_rejects_old_timestamp() { #[tokio::test] async fn test_record_crossing_rejects_future_timestamp() { let program = ProgramTest::new( - "resq_airspace", - sdk_pubkey(resq_airspace::id()), - processor!(process_instruction), + "resq_airspace", sdk_pubkey(resq_airspace::id()), processor!(process_instruction), ); let (banks_client, payer, recent_blockhash) = program.start().await; let owner = Keypair::new(); let drone = Keypair::new(); let pid = str_to_bytes32("cross-future-ts"); - let airspace_pubkey = - setup_open_airspace(&banks_client, &payer, &owner, pid, 0, 200, recent_blockhash).await; + let airspace_pubkey = setup_open_airspace( + &banks_client, &payer, &owner, pid, 0, 200, recent_blockhash, + ).await; let clock: Clock = banks_client.get_sysvar().await.unwrap(); // 2 minutes in the future — outside the 60-second ahead limit. let crossed_at = clock.unix_timestamp + 120; let cross_data = resq_airspace::instruction::RecordCrossing { - lat: 0, - lon: 0, - alt_m: 50, - crossed_at, - } - .data(); + lat: 0, lon: 0, alt_m: 50, crossed_at, + }.data(); let cross_accounts = resq_airspace::accounts::RecordCrossing { drone: anchor_pubkey(drone.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: None, treasury: anchor_pubkey(owner.pubkey()), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let cross_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), @@ -1244,10 +1071,7 @@ async fn test_record_crossing_rejects_future_timestamp() { }; let recent_blockhash2 = banks_client.get_latest_blockhash().await.unwrap(); let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &drone.pubkey(), 1_000_000_000), - cross_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &drone.pubkey(), 1_000_000_000), cross_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &drone], recent_blockhash2); @@ -1262,9 +1086,7 @@ async fn test_record_crossing_rejects_future_timestamp() { #[tokio::test] async fn test_record_crossing_rejects_altitude_out_of_bounds() { let program = ProgramTest::new( - "resq_airspace", - sdk_pubkey(resq_airspace::id()), - processor!(process_instruction), + "resq_airspace", sdk_pubkey(resq_airspace::id()), processor!(process_instruction), ); let (banks_client, payer, recent_blockhash) = program.start().await; let owner = Keypair::new(); @@ -1272,34 +1094,22 @@ async fn test_record_crossing_rejects_altitude_out_of_bounds() { let pid = str_to_bytes32("cross-alt-bounds"); // min=50, max=200 — drone at alt_m=30 is below minimum let airspace_pubkey = setup_open_airspace( - &banks_client, - &payer, - &owner, - pid, - 50, - 200, - recent_blockhash, - ) - .await; + &banks_client, &payer, &owner, pid, 50, 200, recent_blockhash, + ).await; let clock: Clock = banks_client.get_sysvar().await.unwrap(); let crossed_at = clock.unix_timestamp - 30; let cross_data = resq_airspace::instruction::RecordCrossing { - lat: 0, - lon: 0, - alt_m: 30, - crossed_at, // 30 < min_alt_m=50 - } - .data(); + lat: 0, lon: 0, alt_m: 30, crossed_at, // 30 < min_alt_m=50 + }.data(); let cross_accounts = resq_airspace::accounts::RecordCrossing { drone: anchor_pubkey(drone.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: None, treasury: anchor_pubkey(owner.pubkey()), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let cross_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), @@ -1308,10 +1118,7 @@ async fn test_record_crossing_rejects_altitude_out_of_bounds() { }; let recent_blockhash2 = banks_client.get_latest_blockhash().await.unwrap(); let mut tx = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &drone.pubkey(), 1_000_000_000), - cross_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &drone.pubkey(), 1_000_000_000), cross_ix], Some(&payer.pubkey()), ); tx.sign(&[&payer, &drone], recent_blockhash2); @@ -1326,9 +1133,7 @@ async fn test_record_crossing_rejects_altitude_out_of_bounds() { #[tokio::test] async fn test_record_crossing_permit_policy_requires_permit() { let program = ProgramTest::new( - "resq_airspace", - sdk_pubkey(resq_airspace::id()), - processor!(process_instruction), + "resq_airspace", sdk_pubkey(resq_airspace::id()), processor!(process_instruction), ); let (banks_client, payer, recent_blockhash) = program.start().await; let owner = Keypair::new(); @@ -1338,22 +1143,11 @@ async fn test_record_crossing_permit_policy_requires_permit() { // Permit-policy airspace — crossings require a permit. let init_ix = initialize_property_ix( - &owner.pubkey(), - &airspace_pubkey, - &owner.pubkey(), - pid, - 0, - 200, - 1, - AccessPolicy::Permit, - 0, - ) - .await; + &owner.pubkey(), &airspace_pubkey, &owner.pubkey(), + pid, 0, 200, 1, AccessPolicy::Permit, 0, + ).await; let mut tx1 = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), - init_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &owner.pubkey(), 1_000_000_000), init_ix], Some(&payer.pubkey()), ); tx1.sign(&[&payer, &owner], recent_blockhash); @@ -1364,20 +1158,15 @@ async fn test_record_crossing_permit_policy_requires_permit() { // Drone submits crossing with permit: None — should be rejected. let cross_data = resq_airspace::instruction::RecordCrossing { - lat: 0, - lon: 0, - alt_m: 50, - crossed_at, - } - .data(); + lat: 0, lon: 0, alt_m: 50, crossed_at, + }.data(); let cross_accounts = resq_airspace::accounts::RecordCrossing { drone: anchor_pubkey(drone.pubkey()), airspace: anchor_pubkey(airspace_pubkey), permit: None, treasury: anchor_pubkey(owner.pubkey()), system_program: anchor_lang::system_program::ID, - } - .to_account_metas(None); + }.to_account_metas(None); let cross_ix = SolanaInstruction { program_id: sdk_pubkey(resq_airspace::id()), @@ -1386,10 +1175,7 @@ async fn test_record_crossing_permit_policy_requires_permit() { }; let recent_blockhash2 = banks_client.get_latest_blockhash().await.unwrap(); let mut tx2 = SolanaTransaction::new_with_payer( - &[ - system_instruction::transfer(&payer.pubkey(), &drone.pubkey(), 1_000_000_000), - cross_ix, - ], + &[system_instruction::transfer(&payer.pubkey(), &drone.pubkey(), 1_000_000_000), cross_ix], Some(&payer.pubkey()), ); tx2.sign(&[&payer, &drone], recent_blockhash2); diff --git a/resq-delivery/src/error.rs b/resq-delivery/src/error.rs index a71def3..410f610 100644 --- a/resq-delivery/src/error.rs +++ b/resq-delivery/src/error.rs @@ -39,4 +39,4 @@ pub enum DeliveryError { /// delivered_at is more than 60 seconds ahead of the current block time. #[msg("delivered_at must not be more than 60 seconds in the future")] TimestampInFuture, -} +} \ No newline at end of file diff --git a/resq-delivery/src/instructions/mod.rs b/resq-delivery/src/instructions/mod.rs index 73fab0f..1ff3715 100644 --- a/resq-delivery/src/instructions/mod.rs +++ b/resq-delivery/src/instructions/mod.rs @@ -16,4 +16,4 @@ pub mod record_delivery; -pub use record_delivery::*; +pub use record_delivery::*; \ No newline at end of file diff --git a/resq-delivery/src/instructions/record_delivery.rs b/resq-delivery/src/instructions/record_delivery.rs index db908c6..543aeba 100644 --- a/resq-delivery/src/instructions/record_delivery.rs +++ b/resq-delivery/src/instructions/record_delivery.rs @@ -80,11 +80,11 @@ pub fn handler( DeliveryError::TimestampInFuture ); require!( - (-900_000_000..=900_000_000).contains(&lat), + lat >= -900_000_000 && lat <= 900_000_000, DeliveryError::LatitudeOutOfRange ); require!( - (-1_800_000_000..=1_800_000_000).contains(&lon), + lon >= -1_800_000_000 && lon <= 1_800_000_000, DeliveryError::LongitudeOutOfRange ); diff --git a/resq-delivery/src/lib.rs b/resq-delivery/src/lib.rs index feea9ec..bad728f 100644 --- a/resq-delivery/src/lib.rs +++ b/resq-delivery/src/lib.rs @@ -1,8 +1,4 @@ -#![allow( - unexpected_cfgs, - clippy::too_many_arguments, - clippy::diverging_sub_expression -)] +#![allow(unexpected_cfgs)] /* * Copyright 2026 ResQ diff --git a/resq-delivery/src/state/delivery_record.rs b/resq-delivery/src/state/delivery_record.rs index 1f2a934..72e713b 100644 --- a/resq-delivery/src/state/delivery_record.rs +++ b/resq-delivery/src/state/delivery_record.rs @@ -57,4 +57,4 @@ pub struct DeliveryRecord { impl DeliveryRecord { /// Account size in bytes (discriminator + fields). pub const LEN: usize = 8 + 32 + 32 + 64 + 8 + 8 + 4 + 8 + 1; -} +} \ No newline at end of file diff --git a/resq-delivery/src/state/mod.rs b/resq-delivery/src/state/mod.rs index c54eafd..6a69a5f 100644 --- a/resq-delivery/src/state/mod.rs +++ b/resq-delivery/src/state/mod.rs @@ -14,4 +14,4 @@ * limitations under the License. */ -pub mod delivery_record; +pub mod delivery_record; \ No newline at end of file diff --git a/resq-delivery/tests/integration.rs b/resq-delivery/tests/integration.rs index a4c720b..d33ea83 100644 --- a/resq-delivery/tests/integration.rs +++ b/resq-delivery/tests/integration.rs @@ -1,11 +1,3 @@ -#![allow( - clippy::needless_pass_by_value, - clippy::needless_borrow, - clippy::too_many_arguments, - clippy::missing_transmute_annotations, - unused_imports, - unused_mut -)] /* * Copyright 2026 ResQ * @@ -22,23 +14,27 @@ * limitations under the License. */ -use anchor_lang::{AccountDeserialize, InstructionData, ToAccountMetas}; +use anchor_lang::{InstructionData, ToAccountMetas, AccountDeserialize}; use solana_account::Account; +use solana_program_test::*; +use solana_sdk::{ + instruction::Instruction, + pubkey::Pubkey, + signature::Keypair, + signer::Signer, + sysvar::clock::Clock, + transaction::Transaction, +}; use solana_account_info::AccountInfo; use solana_instruction::{AccountMeta, Instruction as SolanaInstruction}; use solana_keypair::Keypair as SolanaKeypair; -use solana_program_entrypoint::ProgramResult; -use solana_program_test::*; use solana_program_test::{processor, ProgramTest}; use solana_pubkey::Pubkey as SolanaPubkey; use solana_sdk::program_error::ProgramError; -use solana_sdk::{ - instruction::Instruction, pubkey::Pubkey, signature::Keypair, signer::Signer, - sysvar::clock::Clock, transaction::Transaction, -}; use solana_signer::Signer as SolanaSigner; use solana_system_interface::instruction as system_instruction; use solana_transaction::Transaction as SolanaTransaction; +use solana_program_entrypoint::ProgramResult; use anchor_lang::Discriminator; use resq_airspace::state::airspace_account::AirspaceAccount; @@ -66,8 +62,7 @@ fn anchor_pubkey(value: SolanaPubkey) -> anchor_lang::prelude::Pubkey { } fn sdk_account_metas(value: Vec) -> Vec { - value - .into_iter() + value.into_iter() .map(|meta| { let pubkey = sdk_pubkey(meta.pubkey); if meta.is_writable { @@ -187,8 +182,7 @@ async fn test_record_delivery_happy_path() { // Verify account state let account = banks_client.get_account(record_pda).await.unwrap().unwrap(); - let record: DeliveryRecord = - DeliveryRecord::try_deserialize(&mut account.data.as_slice()).unwrap(); + let record: DeliveryRecord = DeliveryRecord::try_deserialize(&mut account.data.as_slice()).unwrap(); assert_eq!(sdk_pubkey(record.drone_pda), drone.pubkey()); assert_eq!(sdk_pubkey(record.airspace_pda), airspace_pubkey); @@ -197,9 +191,7 @@ async fn test_record_delivery_happy_path() { assert_eq!(record.alt_m, 50); assert_eq!(record.delivered_at, delivered_at); - let stored_cid_str = std::str::from_utf8(&record.ipfs_cid) - .unwrap() - .trim_matches(char::from(0)); + let stored_cid_str = std::str::from_utf8(&record.ipfs_cid).unwrap().trim_matches(char::from(0)); assert!(stored_cid_str.contains("QmResQTestCID")); } @@ -234,10 +226,7 @@ async fn test_rejects_all_zero_cid() { tx.sign(&[&payer, &drone], recent_blockhash); let err = banks_client.process_transaction(tx).await.unwrap_err(); - assert!( - err.unwrap().to_string().contains("EmptyCid") - || format!("{:?}", err).contains("Custom(6000)") - ); + assert!(err.unwrap().to_string().contains("EmptyCid") || format!("{:?}", err).contains("Custom(6000)")); } #[tokio::test] @@ -270,10 +259,7 @@ async fn test_rejects_zero_timestamp() { tx.sign(&[&payer, &drone], recent_blockhash); let err = banks_client.process_transaction(tx).await.unwrap_err(); - assert!( - err.unwrap().to_string().contains("InvalidTimestamp") - || format!("{:?}", err).contains("Custom(6001)") - ); + assert!(err.unwrap().to_string().contains("InvalidTimestamp") || format!("{:?}", err).contains("Custom(6001)")); } #[tokio::test] @@ -307,10 +293,7 @@ async fn test_rejects_latitude_out_of_range() { tx.sign(&[&payer, &drone], recent_blockhash); let err = banks_client.process_transaction(tx).await.unwrap_err(); - assert!( - err.unwrap().to_string().contains("LatitudeOutOfRange") - || format!("{:?}", err).contains("Custom(6002)") - ); + assert!(err.unwrap().to_string().contains("LatitudeOutOfRange") || format!("{:?}", err).contains("Custom(6002)")); } #[tokio::test] @@ -344,10 +327,7 @@ async fn test_rejects_longitude_out_of_range() { tx.sign(&[&payer, &drone], recent_blockhash); let err = banks_client.process_transaction(tx).await.unwrap_err(); - assert!( - err.unwrap().to_string().contains("LongitudeOutOfRange") - || format!("{:?}", err).contains("Custom(6003)") - ); + assert!(err.unwrap().to_string().contains("LongitudeOutOfRange") || format!("{:?}", err).contains("Custom(6003)")); } #[tokio::test] @@ -401,10 +381,7 @@ async fn test_duplicate_delivery_fails() { let err = banks_client.process_transaction(tx2).await.unwrap_err(); // Anchor initialization failure - assert!( - format!("{:?}", err).contains("already in use") - || format!("{:?}", err).contains("InstructionError") - ); + assert!(format!("{:?}", err).contains("already in use") || format!("{:?}", err).contains("InstructionError")); } #[tokio::test] diff --git a/vendor/solana-program-test/osv-scanner.toml b/vendor/solana-program-test/osv-scanner.toml deleted file mode 100644 index 9eda678..0000000 --- a/vendor/solana-program-test/osv-scanner.toml +++ /dev/null @@ -1,93 +0,0 @@ -# OSV-Scanner config for the vendored solana-program-test lockfile. -# -# This file is picked up when osv-scanner scans the directory as its own -# project (it discovers Cargo.lock and looks for `osv-scanner.toml` in the -# same dir). Root-level config at the repo root does NOT propagate here — -# each lockfile is its own scan project. -# -# `solana-program-test` is a vendored copy of upstream Solana's test -# harness, consumed only as a dev-dependency from the workspace root. -# On-chain program bytecode ships none of this. Every advisory below is -# ignored with a reason; re-vendor from a newer Solana release to clear. -# -# Format: https://google.github.io/osv-scanner/configuration/ -# Note: OSV-Scanner v2 expects PascalCase keys (IgnoredVulns); snake_case -# is rejected (checked against v2.3.5). - -# ── Same advisories as the root config, re-declared here for this scan ────── - -[[IgnoredVulns]] -id = "RUSTSEC-2025-0141" -reason = "bincode 1.x — dev-only in vendored solana-program-test; await upstream Anchor/Solana bump to bincode 2.x" - -[[IgnoredVulns]] -id = "RUSTSEC-2024-0388" -reason = "derivative 2.2.0 — dev-only in vendored solana-program-test; await upstream migration" - -[[IgnoredVulns]] -id = "RUSTSEC-2024-0436" -reason = "paste 1.0.9 — dev-only in vendored solana-program-test; unmaintained crate" - -[[IgnoredVulns]] -id = "RUSTSEC-2025-0161" -reason = "libsecp256k1 0.6.0 — dev-only in vendored solana-program-test; solana-* frozen pin" - -[[IgnoredVulns]] -id = "RUSTSEC-2024-0344" -reason = "curve25519-dalek 3.2.0 — dev-only in vendored solana-program-test; on-chain BPF unaffected" - -[[IgnoredVulns]] -id = "RUSTSEC-2022-0093" -reason = "ed25519-dalek 1.0.1 — dev-only in vendored solana-program-test; on-chain programs do not call dalek directly" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0097" -reason = "rand 0.7.3 / 0.8.5 / 0.9.0 — dev-only in vendored solana-program-test; no custom-logger code paths" - -# ── Advisories unique to this vendored lockfile ───────────────────────────── -# (fixed upstream in the main workspace but still pinned in this older vendor -# of solana-program-test; safe because the vendor is dev-only) - -[[IgnoredVulns]] -id = "RUSTSEC-2025-0056" -reason = "adler 1.0.2 unmaintained — dev-only; await Solana adler2 migration" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0007" -reason = "bytes 1.10.1 — dev-only; main workspace already on 1.11.1" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0012" -reason = "keccak 0.1.5 — dev-only; main workspace already on 0.1.6" - -[[IgnoredVulns]] -id = "RUSTSEC-2024-0370" -reason = "proc-macro-error 1.0.4 — dev-only; unmaintained; upstream replacement is proc-macro-error2" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0037" -reason = "quinn-proto 0.11.13 — dev-only; main workspace already on 0.11.14; on-chain programs never execute quinn" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0049" -reason = "rustls-webpki 0.103.6 — dev-only; main workspace already on 0.103.12" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0098" -reason = "rustls-webpki 0.103.6 — dev-only; main workspace already on 0.103.12" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0099" -reason = "rustls-webpki 0.103.6 — dev-only; main workspace already on 0.103.12" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0067" -reason = "tar 0.4.44 — dev-only test harness; no user-controlled archives" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0068" -reason = "tar 0.4.44 — dev-only test harness; no user-controlled archives" - -[[IgnoredVulns]] -id = "RUSTSEC-2026-0009" -reason = "time 0.3.9 — dev-only; await upstream Solana bump"