diff --git a/pallets/market/src/lib.rs b/pallets/market/src/lib.rs index 21c0dac4..cc94430c 100644 --- a/pallets/market/src/lib.rs +++ b/pallets/market/src/lib.rs @@ -1180,6 +1180,11 @@ pub mod pallet { lock_funds::(who, amount) } + fn unlock_pre_commit_funds(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { + // NOTE(@aidan,23/1/25): unsure if this should emit an event + unlock_funds::(who, amount) + } + fn slash_pre_commit_funds(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { // NOTE(@jmg-duarte,21/1/25): unsure if this should emit an event slash_and_burn::(who, amount) diff --git a/pallets/storage-provider/src/lib.rs b/pallets/storage-provider/src/lib.rs index 650e907b..c39ae11d 100644 --- a/pallets/storage-provider/src/lib.rs +++ b/pallets/storage-provider/src/lib.rs @@ -374,6 +374,8 @@ pub mod pallet { TooManyProofs, /// AuthorVRF lookup failed. MissingAuthorVRF, + /// After proving failed to return pre commit deposit. + FailedToReturnPreCommitDeposit, /// Inner pallet errors GeneralPalletError(crate::error::GeneralPalletError), } @@ -572,6 +574,7 @@ pub mod pallet { let mut new_sectors = BoundedVec::new(); let mut sector_numbers: BoundedVec> = BoundedVec::new(); + let mut pre_commit_deposit_to_unlock = BalanceOf::::zero(); for sector in sectors { // Get pre-committed sector. This is the sector we are currently @@ -604,6 +607,8 @@ pub mod pallet { new_sectors .try_push(new_sector) .expect("Programmer error: New sectors should fit in bound of MAX_SECTORS"); + + pre_commit_deposit_to_unlock += calculate_pre_commit_deposit::(); } // Activate the deals for the sectors that will be proven. This @@ -667,6 +672,18 @@ pub mod pallet { .try_into() .expect("Programmer error: ProveCommitResult's should fit in bound of MAX_SECTORS"); + // Reduce pre commit deposit amount in state + if let Some(pre_commit_deposits) = sp + .pre_commit_deposits + .checked_sub(&pre_commit_deposit_to_unlock) + { + sp.pre_commit_deposits = pre_commit_deposits + } else { + log::error!(target: LOG_TARGET, "catastrophe, failed to subtract from pre_commit_deposits {:?} - {:?} < 0", sp.pre_commit_deposits, pre_commit_deposit_to_unlock); + return Err(Error::::FailedToReturnPreCommitDeposit.into()); + }; + // Unlock pre commit deposit funds. + T::Market::unlock_pre_commit_funds(&owner, pre_commit_deposit_to_unlock)?; StorageProviders::::set(owner.clone(), Some(sp)); Self::deposit_event(Event::SectorsProven { owner, diff --git a/pallets/storage-provider/src/tests/pre_commit_sector_hook.rs b/pallets/storage-provider/src/tests/pre_commit_sector_hook.rs index 8976929e..5e9ed1e9 100644 --- a/pallets/storage-provider/src/tests/pre_commit_sector_hook.rs +++ b/pallets/storage-provider/src/tests/pre_commit_sector_hook.rs @@ -78,13 +78,14 @@ fn pre_commit_hook_slashed_deal() { assert!(sp.sectors.contains_key(&second_sector.sector_number)); // First sector removed from here because it was slashed, second one because it was proven. assert!(sp.pre_committed_sectors.is_empty()); - // Pre-commit from the second deal is still there, as pre-commit deposits are until sector expired. - assert_eq!(sp.pre_commit_deposits, DEAL_PRECOMMIT_DEPOSIT); + // No pre-commit deposit as the second deal has been proven and the first one is expired and thus slashed. + assert_eq!(sp.pre_commit_deposits, 0); // 1 deal got slashed so the respective locked funds *vanished* assert_eq!( Market::locked(&account(storage_provider)), // The cast is kind of an hack but we know it is safe - Some(((2 * DEAL_COLLATERAL + DEAL_PRECOMMIT_DEPOSIT) as u32).into()) + // Not add the DEAL_PRECOMMIT_DEPOSIT because this has been unlocked after proving. + Some(((2 * DEAL_COLLATERAL) as u32).into()) ); let mut expected_faulty_sectors = BoundedBTreeSet::new(); expected_faulty_sectors diff --git a/pallets/storage-provider/src/tests/prove_commit_sectors.rs b/pallets/storage-provider/src/tests/prove_commit_sectors.rs index c7498d82..40111cbe 100644 --- a/pallets/storage-provider/src/tests/prove_commit_sectors.rs +++ b/pallets/storage-provider/src/tests/prove_commit_sectors.rs @@ -82,11 +82,11 @@ fn successfully_prove_sector() { ] ); - // check that the funds are still locked + // check that the funds are unlocked assert_eq!( Market::free(&account(storage_provider)), // Provider reserved 70 tokens in the market pallet and 1 token is used for the pre-commit - Some(20 - 1) + Some(20) ); let sp_state = StorageProviders::::get(account(storage_provider)) .expect("Should be able to get providers info"); @@ -190,12 +190,8 @@ fn successfully_prove_multiple_sectors() { ] ); - // check that the funds are still locked - assert_eq!( - Market::free(&account(storage_provider)), - // 70 - 25 * 2 = 20 - Some(20 - SECTORS_TO_COMMIT as u64) - ); + // check that the funds are unlocked + assert_eq!(Market::free(&account(storage_provider)), Some(20)); let sp_state = StorageProviders::::get(account(storage_provider)) .expect("Should be able to get providers info"); diff --git a/primitives/src/pallets.rs b/primitives/src/pallets.rs index 99870777..683068f4 100644 --- a/primitives/src/pallets.rs +++ b/primitives/src/pallets.rs @@ -51,6 +51,9 @@ pub trait Market { /// Locks funds for pre-commit purposes. fn lock_pre_commit_funds(who: &AccountId, amount: Balance) -> DispatchResult; + /// Unlocks funds for pre-commit purposes. + fn unlock_pre_commit_funds(who: &AccountId, amount: Balance) -> DispatchResult; + /// Slashes funds locked for pre-commit purposes. fn slash_pre_commit_funds(who: &AccountId, amount: Balance) -> DispatchResult;