From 7f43c055ce5238d61a7dce914cd1cd4efa2871fa Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Apr 2026 01:58:44 +0800 Subject: [PATCH] fix(drive): wire v1 dispatcher for deduct_from_prefunded_specialized_balance The top-level `Drive::deduct_from_prefunded_specialized_balance` dispatcher only matched version 0, but platform versions v3-v7 set the `deduct_from_prefunded_specialized_balance` feature version to 1, causing the helper to unconditionally return `UnknownVersionMismatch` on any v3+ platform. The helper currently has no production callers (the real state transition path goes through the `_operations` sibling, which already handles both v0 and v1), so this has not impacted consensus, but the helper is part of the public `Drive` API and is effectively dead on all recent platform versions. This adds a v1 impl mirroring v0 (v0's body is already version-agnostic, since version selection for the actual deduction logic happens inside the `_operations` dispatcher it delegates to) and wires the match arm. Also corrects the stale `known_versions: vec![0]` in the `_operations` dispatcher error arm to `vec![0, 1]`, since it has handled both versions since #2422. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../mod.rs | 9 +++- .../v1/mod.rs | 54 +++++++++++++++++++ .../mod.rs | 2 +- 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance/v1/mod.rs diff --git a/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance/mod.rs b/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance/mod.rs index 755c5a510cf..34ac1a7cc20 100644 --- a/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance/mod.rs +++ b/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance/mod.rs @@ -1,4 +1,5 @@ mod v0; +mod v1; use crate::drive::Drive; use crate::error::drive::DriveError; @@ -43,9 +44,15 @@ impl Drive { transaction, platform_version, ), + 1 => self.deduct_from_prefunded_specialized_balance_v1( + specialized_balance_id, + amount, + transaction, + platform_version, + ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "deduct_from_prefunded_specialized_balance".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), } diff --git a/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance/v1/mod.rs b/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance/v1/mod.rs new file mode 100644 index 00000000000..ddaee3a92da --- /dev/null +++ b/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance/v1/mod.rs @@ -0,0 +1,54 @@ +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; + +use dpp::identifier::Identifier; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Deducts from a prefunded specialized balance (v1). + /// + /// Functionally identical to `deduct_from_prefunded_specialized_balance_v0`: + /// version selection for the actual deduction logic happens inside the + /// `deduct_from_prefunded_specialized_balance_operations` dispatcher, which + /// routes to `_operations_v0` / `_operations_v1` based on the platform + /// version. This top-level wrapper just collects those operations and + /// applies the resulting grovedb batch. + /// + /// # Arguments + /// + /// * `amount` - The amount of credits to be removed from the prefunded balance. + /// * `transaction` - A `TransactionArg` object representing the transaction to be used. + /// * `platform_version` - A `PlatformVersion` object specifying the version of Platform. + /// + /// # Returns + /// + /// * `Result<(), Error>` - If successful, returns `Ok(())`. Otherwise, returns an `Error`. + #[inline(always)] + pub(super) fn deduct_from_prefunded_specialized_balance_v1( + &self, + specialized_balance_id: Identifier, + amount: u64, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut drive_operations = vec![]; + let batch_operations = self.deduct_from_prefunded_specialized_balance_operations( + specialized_balance_id, + amount, + &mut None, + transaction, + platform_version, + )?; + let grove_db_operations = + LowLevelDriveOperation::grovedb_operations_batch(&batch_operations); + self.grove_apply_batch_with_add_costs( + grove_db_operations, + false, + transaction, + &mut drive_operations, + &platform_version.drive, + ) + } +} diff --git a/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance_operations/mod.rs b/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance_operations/mod.rs index aef16a0cb53..a07ae98bb56 100644 --- a/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance_operations/mod.rs +++ b/packages/rs-drive/src/drive/prefunded_specialized_balances/deduct_from_prefunded_specialized_balance_operations/mod.rs @@ -60,7 +60,7 @@ impl Drive { ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "deduct_from_prefunded_specialized_balance_operations".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), }