1+ {-# LANGUAGE BangPatterns #-}
12{-# LANGUAGE ScopedTypeVariables #-}
23{-# LANGUAGE TypeApplications #-}
34
@@ -13,6 +14,7 @@ import qualified Concordium.ID.AnonymityRevoker as AR
1314import qualified Concordium.ID.IdentityProvider as IP
1415import qualified Concordium.ID.Types as ID
1516import qualified Concordium.Types as Types
17+ import Concordium.Types.Execution (Payload (.. ), decodePayload )
1618import Concordium.Types.HashableTo (getHash )
1719import Concordium.Types.Option
1820import qualified Concordium.Types.Parameters as Params
@@ -315,6 +317,25 @@ verifyChainUpdate ui@Updates.UpdateInstruction{..} =
315317 return $ Ok $ ChainUpdateSuccess (getHash keys) nonce
316318 )
317319
320+ -- | Check if a transaction payload includes a schedule with a total amount that exceeds the
321+ -- maximum representable amount.
322+ canScheduleOverflow ::
323+ forall pv msg .
324+ (Tx. TransactionData msg ) =>
325+ Types. SProtocolVersion pv -> msg -> Bool
326+ canScheduleOverflow spv meta =
327+ case decodePayload spv (Tx. transactionPayload meta) of
328+ Left _ -> False
329+ Right TransferWithSchedule {.. } -> checkSchedule twsSchedule
330+ Right TransferWithScheduleAndMemo {.. } -> checkSchedule twswmSchedule
331+ Right _ -> False
332+ where
333+ checkSchedule = doCheckSchedule 0
334+ doCheckSchedule _ [] = False
335+ doCheckSchedule ! acc ((_, amt) : rest)
336+ | acc > maxBound - amt = True
337+ | otherwise = doCheckSchedule (acc + amt) rest
338+
318339-- | Verifies a 'NormalTransaction' transaction.
319340-- This function verifies the following:
320341-- * Checks that enough energy is supplied for the transaction.
@@ -366,6 +387,8 @@ verifyNormalTransaction meta =
366387 keys <- lift (getAccountVerificationKeys acc)
367388 let sigCheck = Tx. verifyTransaction keys meta
368389 unless sigCheck $ throwError $ MaybeOk NormalTransactionInvalidSignatures
390+ let scheduleOverflow = canScheduleOverflow (Types. protocolVersion @ (Types. MPV m )) meta
391+ when scheduleOverflow $ throwError $ MaybeOk NormalTransactionInsufficientFunds
369392 return $ Ok $ NormalTransactionSuccess (getHash keys) nonce
370393 )
371394
@@ -439,7 +462,7 @@ verifyExtendedTransaction meta =
439462 unless (depositedAmount <= amnt) $ throwError $ MaybeOk NormalTransactionInsufficientFunds
440463 -- Check the sender and sponsor signatures
441464 senderKeys <- lift (getAccountVerificationKeys senderAcc)
442- case mbSponsorAcc of
465+ sigResult <- case mbSponsorAcc of
443466 Nothing -> do
444467 let sigCheck = Tx. verifyTransaction senderKeys meta
445468 unless sigCheck $ throwError $ MaybeOk NormalTransactionInvalidSignatures
@@ -449,6 +472,9 @@ verifyExtendedTransaction meta =
449472 let sigCheck = Tx. verifySponsoredTransaction senderKeys sponsorKeys meta
450473 unless sigCheck $ throwError $ MaybeOk NormalTransactionInvalidSignatures
451474 return $ Ok $ ExtendedTransactionSuccess (getHash senderKeys) (Present $ getHash sponsorKeys) nonce
475+ let scheduleOverflow = canScheduleOverflow (Types. protocolVersion @ (Types. MPV m )) meta
476+ when scheduleOverflow $ throwError $ MaybeOk NormalTransactionInsufficientFunds
477+ return sigResult
452478 )
453479
454480-- | Wrapper types for pairing a transaction with its verification result (if it has one).
0 commit comments