@@ -24,15 +24,15 @@ import BotPlutusInterface.Effects (
2424 saveBudget ,
2525 slotToPOSIXTime ,
2626 threadDelay ,
27- uploadDir ,
27+ uploadDir
2828 )
2929import BotPlutusInterface.Files (DummyPrivKey (FromSKey , FromVKey ))
3030import BotPlutusInterface.Files qualified as Files
3131import BotPlutusInterface.Types (
3232 ContractEnvironment (.. ),
3333 LogLevel (Debug , Warn ),
3434 Tip (block , slot ),
35- TxFile (Signed ),
35+ TxFile (Signed ), spInterval , spBlocksTimeOut
3636 )
3737import Cardano.Api (AsType (.. ), EraInMode (.. ), Tx (Tx ))
3838import Control.Lens (preview , (^.) )
@@ -45,7 +45,6 @@ import Control.Monad.Trans.Class (lift)
4545import Control.Monad.Trans.Either (EitherT , eitherT , firstEitherT , newEitherT )
4646import Data.Aeson (ToJSON , Value (Array , Bool , Null , Number , Object , String ))
4747import Data.Aeson.Extras (encodeByteString )
48- import Data.Either (fromRight )
4948import Data.HashMap.Strict qualified as HM
5049import Data.Kind (Type )
5150import Data.Map qualified as Map
@@ -210,27 +209,59 @@ awaitTxStatusChange ::
210209 Ledger. TxId ->
211210 Eff effs TxStatus
212211awaitTxStatusChange contractEnv txId = do
213- -- The depth (in blocks) after which a transaction cannot be rolled back anymore (from Plutus.ChainIndex.TxIdState)
214- let chainConstant = 8
215-
216- mTx <- queryChainIndexForTxState
217- case mTx of
218- Nothing -> pure Unknown
219- Just txState -> do
220- printBpiLog @ w Debug $ " Found transaction in node, waiting" <+> pretty chainConstant <+> " blocks for it to settle."
221- awaitNBlocks @ w contractEnv (chainConstant + 1 )
222- -- Check if the tx is still present in chain-index, in case of a rollback
223- -- we might not find it anymore.
224- ciTxState' <- queryChainIndexForTxState
225- case ciTxState' of
226- Nothing -> pure Unknown
227- Just _ -> do
228- blk <- fromInteger <$> currentBlock contractEnv
229- -- This will set the validity correctly based on the txState.
230- -- The tx will always be committed, as we wait for chainConstant + 1 blocks
231- let status = transactionStatus blk txState txId
232- pure $ fromRight Unknown status
212+ let txStatusPolling = contractEnv. cePABConfig. pcTxStausPolling
213+ pollInterval = fromIntegral $ spInterval txStatusPolling
214+ pollTimeOut = fromIntegral $ spBlocksTimeOut txStatusPolling
215+ cutOffBlock <- (pollTimeOut + ) <$> currentBlock contractEnv
216+ printBpiLog @ w Debug $ pretty $ " Awaiting status change for " ++ show txId
217+ txStausCheckLoop txId contractEnv pollInterval cutOffBlock
218+
219+ txStausCheckLoop ::
220+ forall (w :: Type ) (effs :: [Type -> Type ]).
221+ Member (PABEffect w ) effs =>
222+ Ledger. TxId ->
223+ ContractEnvironment w ->
224+ Int ->
225+ Integer ->
226+ Eff effs TxStatus
227+ txStausCheckLoop txId contractEnv pollInterval cutOffBlock = do
228+ currBlock <- currentBlock contractEnv
229+ txStatus <- getStatus
230+ case (txStatus, currBlock > cutOffBlock) of
231+ (status, True ) -> do
232+ logDebug $ " Awaiting preiod for TxId " ++ show txId
233+ ++ " status change is over, current status: " ++ show status
234+ return status
235+ (Unknown , _) -> do
236+ threadDelay @ w pollInterval
237+ txStausCheckLoop txId contractEnv pollInterval cutOffBlock
238+ (status, _) -> return status
233239 where
240+ -- | get Tx status with extensive debug logging
241+ getStatus = do
242+ mTx <- queryChainIndexForTxState
243+ case mTx of
244+ Nothing -> do
245+ logDebug $ " TxId " ++ show txId ++ " not found in index"
246+ return Unknown
247+ Just txState -> do
248+ logDebug $ " TxId " ++ show txId ++ " found in index, checking status"
249+ blk <- fromInteger <$> currentBlock contractEnv
250+ case transactionStatus blk txState txId of
251+ Left e -> do
252+ logDebug $ " Staus check for TxId " ++ show txId ++ " failed with " ++ show e
253+ return Unknown
254+ Right st -> case st of
255+ Unknown -> do
256+ logDebug $ " Staus for TxId " ++ show txId ++ " is Unknown"
257+ return Unknown
258+ other -> do
259+ logDebug $
260+ " Staus for TxId " ++ show txId ++ " is " ++ show other
261+ pure other
262+
263+ logDebug = printBpiLog @ w Debug . pretty
264+
234265 queryChainIndexForTxState :: Eff effs (Maybe TxIdState )
235266 queryChainIndexForTxState = do
236267 mTx <- join . preview _TxIdResponse <$> (queryChainIndex @ w $ TxFromTxId txId)
@@ -355,25 +386,25 @@ awaitSlot contractEnv s@(Slot n) = do
355386 | n < tip'. slot -> pure $ Slot tip'. slot
356387 _ -> awaitSlot contractEnv s
357388
358- -- | Wait for n Blocks.
359- awaitNBlocks ::
360- forall (w :: Type ) (effs :: [Type -> Type ]).
361- Member (PABEffect w ) effs =>
362- ContractEnvironment w ->
363- Integer ->
364- Eff effs ()
365- awaitNBlocks contractEnv n = do
366- current <- currentBlock contractEnv
367- go current
368- where
369- go :: Integer -> Eff effs ()
370- go start = do
371- threadDelay @ w (fromIntegral contractEnv. cePABConfig. pcTipPollingInterval)
372- tip <- CardanoCLI. queryTip @ w contractEnv. cePABConfig
373- case tip of
374- Right tip'
375- | start + n <= tip'. block -> pure ()
376- _ -> go start
389+ -- -- | Wait for n Blocks.
390+ -- awaitNBlocks ::
391+ -- forall (w :: Type) (effs :: [Type -> Type]).
392+ -- Member (PABEffect w) effs =>
393+ -- ContractEnvironment w ->
394+ -- Integer ->
395+ -- Eff effs ()
396+ -- awaitNBlocks contractEnv n = do
397+ -- current <- currentBlock contractEnv
398+ -- go current
399+ -- where
400+ -- go :: Integer -> Eff effs ()
401+ -- go start = do
402+ -- threadDelay @w (fromIntegral contractEnv.cePABConfig.pcTipPollingInterval)
403+ -- tip <- CardanoCLI.queryTip @w contractEnv.cePABConfig
404+ -- case tip of
405+ -- Right tip'
406+ -- | start + n <= tip'.block -> pure ()
407+ -- _ -> go start
377408
378409{- | Wait at least until the given time. Uses the awaitSlot under the hood, so the same constraints
379410 are applying here as well.
0 commit comments