diff --git a/modules/homa/src/lib.rs b/modules/homa/src/lib.rs index 067ec1499..42d7a73b6 100644 --- a/modules/homa/src/lib.rs +++ b/modules/homa/src/lib.rs @@ -167,6 +167,8 @@ pub mod module { OutdatedEraIndex, /// Redeem request is not allowed to be fast matched. FastMatchIsNotAllowed, + /// The fast match cannot be matched completely. + CannotCompletelyFastMatch, } #[pallet::event] @@ -455,7 +457,7 @@ pub mod module { let _ = ensure_signed(origin)?; for redeemer in redeemer_list { - Self::do_fast_match_redeem(&redeemer)?; + Self::do_fast_match_redeem(&redeemer, true)?; } Ok(()) @@ -630,6 +632,22 @@ pub mod module { T::GovernanceOrigin::ensure_origin(origin)?; Self::bump_current_era(bump_amount) } + + /// Execute fast match for specific redeem requests, require completely matched. + /// + /// Parameters: + /// - `redeemer_list`: The list of redeem requests to execute fast redeem. + #[pallet::weight(< T as Config >::WeightInfo::fast_match_redeems(redeemer_list.len() as u32))] + #[transactional] + pub fn fast_match_redeems_completely(origin: OriginFor, redeemer_list: Vec) -> DispatchResult { + let _ = ensure_signed(origin)?; + + for redeemer in redeemer_list { + Self::do_fast_match_redeem(&redeemer, false)?; + } + + Ok(()) + } } impl Pallet { @@ -713,7 +731,7 @@ pub mod module { } #[transactional] - pub fn do_fast_match_redeem(redeemer: &T::AccountId) -> DispatchResult { + pub fn do_fast_match_redeem(redeemer: &T::AccountId, allow_partially: bool) -> DispatchResult { RedeemRequests::::try_mutate_exists(redeemer, |maybe_request| -> DispatchResult { if let Some((request_amount, allow_fast_match)) = maybe_request.take() { ensure!(allow_fast_match, Error::::FastMatchIsNotAllowed); @@ -768,6 +786,7 @@ pub mod module { // update request amount let remainder_request_amount = request_amount.saturating_sub(actual_liquid_to_redeem); if !remainder_request_amount.is_zero() { + ensure!(allow_partially, Error::::CannotCompletelyFastMatch); *maybe_request = Some((remainder_request_amount, allow_fast_match)); } } diff --git a/modules/homa/src/tests.rs b/modules/homa/src/tests.rs index d39b87cfa..2d965c74c 100644 --- a/modules/homa/src/tests.rs +++ b/modules/homa/src/tests.rs @@ -596,12 +596,12 @@ fn do_fast_match_redeem_works() { // Charlie's redeem request is not allowed to be fast matched. assert_noop!( - Homa::do_fast_match_redeem(&CHARLIE), + Homa::do_fast_match_redeem(&CHARLIE, true), Error::::FastMatchIsNotAllowed ); // Alice's redeem request is able to be fast matched fully. - assert_ok!(Homa::do_fast_match_redeem(&ALICE)); + assert_ok!(Homa::do_fast_match_redeem(&ALICE, false)); System::assert_last_event(Event::Homa(crate::Event::RedeemedByFastMatch( ALICE, 5_000_000, 500_000, 450_000, ))); @@ -625,7 +625,12 @@ fn do_fast_match_redeem_works() { // Bob's redeem request is able to be fast matched partially, // because must remain `RedeemThreshold` even if `ToBondPool` is enough. - assert_ok!(Homa::do_fast_match_redeem(&BOB)); + assert_noop!( + Homa::do_fast_match_redeem(&BOB, false), + Error::::CannotCompletelyFastMatch, + ); + + assert_ok!(Homa::do_fast_match_redeem(&BOB, true)); System::assert_last_event(Event::Homa(crate::Event::RedeemedByFastMatch( BOB, 5_500_000, 550_000, 500_499, )));