Skip to content

Commit fd77f79

Browse files
committed
Fix tests and update awaitTxStatusChange so that it can also fail if the Tx does
not show up in chain-index after a set number of blocks (currently 5) Change-type: patch Signed-off-by: Giovanni Garufi <giovanni@mlabs.city>
1 parent 86f19b6 commit fd77f79

File tree

6 files changed

+100
-79
lines changed

6 files changed

+100
-79
lines changed

examples/plutus-game/app/Main.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import Data.Aeson.TH (defaultOptions, deriveJSON)
2424
import Data.ByteString.Lazy qualified as LazyByteString
2525
import Data.Default (def)
2626
import Data.Maybe (fromMaybe)
27-
import Ledger.Address (StakePubKeyHash (..))
2827
import Playground.Types (FunctionSchema)
2928
import Schema (FormSchema)
3029
import Servant.Client.Core (BaseUrl (BaseUrl), Scheme (Http))
@@ -61,12 +60,12 @@ main = do
6160
, pcProtocolParams = protocolParams
6261
, pcTipPollingInterval = 10_000_000
6362
, pcSlotConfig = def
64-
, pcOwnPubKeyHash = "54667d9a5b790a8640fe4662812060a782aa5a3a266cf75ff3869be3"
65-
, pcOwnStakePubKeyHash = Just $ StakePubKeyHash "7f8286c1eae3afc4241480cc534ab89f28383f4673bc5aa27e0582b0"
63+
, pcOwnPubKeyHash = "0f45aaf1b2959db6e5ff94dbb1f823bf257680c3c723ac2d49f97546"
64+
, pcOwnStakePubKeyHash = Nothing
6665
, pcScriptFileDir = "./scripts"
6766
, pcSigningKeyFileDir = "./signing-keys"
6867
, pcTxFileDir = "./txs"
69-
, pcDryRun = False
68+
, pcDryRun = True
7069
, pcLogLevel = Debug
7170
, pcProtocolParamsFile = "./protocol.json"
7271
, pcForceBudget = Just (1000, 1000)

examples/plutus-nft/app/Main.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ main = do
6161
, pcTipPollingInterval = 10_000_000
6262
, pcSlotConfig = def
6363
, pcOwnPubKeyHash = "0f45aaf1b2959db6e5ff94dbb1f823bf257680c3c723ac2d49f97546"
64+
, pcOwnStakePubKeyHash = Nothing
6465
, pcScriptFileDir = "./scripts"
6566
, pcSigningKeyFileDir = "./signing-keys"
6667
, pcTxFileDir = "./txs"

examples/plutus-transfer/app/Main.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ main = do
6060
, pcTipPollingInterval = 10_000_000
6161
, pcSlotConfig = def
6262
, pcOwnPubKeyHash = "0f45aaf1b2959db6e5ff94dbb1f823bf257680c3c723ac2d49f97546"
63+
, pcOwnStakePubKeyHash = Nothing
6364
, pcScriptFileDir = "./scripts"
6465
, pcSigningKeyFileDir = "./signing-keys"
6566
, pcTxFileDir = "./txs"

src/BotPlutusInterface/Contract.hs

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import Control.Monad.Trans.Class (lift)
3131
import Control.Monad.Trans.Either (eitherT, firstEitherT, newEitherT)
3232
import Data.Aeson (ToJSON, Value)
3333
import Data.Aeson.Extras (encodeByteString)
34+
import Data.Either (fromRight)
3435
import Data.Kind (Type)
3536
import Data.Map qualified as Map
3637
import Data.Row (Row)
@@ -44,7 +45,8 @@ import Ledger.Slot (Slot (Slot))
4445
import Ledger.TimeSlot (posixTimeRangeToContainedSlotRange, posixTimeToEnclosingSlot, slotToEndPOSIXTime)
4546
import Ledger.Tx (CardanoTx)
4647
import Ledger.Tx qualified as Tx
47-
import Plutus.ChainIndex.Types (RollbackState (Committed), TxStatus, TxValidity (..))
48+
import Plutus.ChainIndex.TxIdState (fromTx, transactionStatus)
49+
import Plutus.ChainIndex.Types (RollbackState (..), TxIdState, TxStatus)
4850
import Plutus.Contract.Checkpoint (Checkpoint (..))
4951
import Plutus.Contract.Effects (
5052
BalanceTxResponse (..),
@@ -152,7 +154,7 @@ handlePABReq contractEnv req = do
152154
PosixTimeRangeToContainedSlotRangeResp $
153155
Right $
154156
posixTimeRangeToContainedSlotRange contractEnv.cePABConfig.pcSlotConfig posixTimeRange
155-
AwaitTxStatusChangeReq txId -> AwaitTxStatusChangeResp txId <$> getTxUpdate @w contractEnv txId
157+
AwaitTxStatusChangeReq txId -> AwaitTxStatusChangeResp txId <$> awaitTxStatusChange @w contractEnv txId
156158
------------------------
157159
-- Unhandled requests --
158160
------------------------
@@ -167,32 +169,51 @@ handlePABReq contractEnv req = do
167169
printLog @w Debug $ show resp
168170
pure resp
169171

170-
getTxUpdate ::
172+
awaitTxStatusChange ::
171173
forall (w :: Type) (effs :: [Type -> Type]).
172174
Member (PABEffect w) effs =>
173175
ContractEnvironment w ->
174176
Ledger.TxId ->
175177
Eff effs TxStatus
176-
getTxUpdate contractEnv txId = do
177-
let minBlockHeight = 3
178-
_ <- findTxByIdOrLoop
179-
printLog @w Debug $ "Found tx in chain index. Waiting for " ++ show minBlockHeight ++ " blocks"
180-
_ <- awaitNBlocks @w contractEnv minBlockHeight
181-
printLog @w Debug "Waited, checking once more for tx rollback"
182-
_ <- findTxByIdOrLoop
183-
printLog @w Debug "Tx is confirmed"
184-
pure $ Committed TxValid ()
178+
awaitTxStatusChange contractEnv txId = do
179+
-- The depth (in blocks) after which a transaction cannot be rolled back anymore (from Plutus.ChainIndex.TxIdState)
180+
let chainConstant = 8
181+
182+
ciTxState <- findChainIndexTxLoop
183+
case ciTxState of
184+
Nothing -> pure Unknown
185+
Just txState -> do
186+
awaitNBlocks @w contractEnv chainConstant
187+
-- Check if the tx is still present in chain-index, in case of a rollback
188+
-- we might not find it anymore.
189+
ciTxState' <- findChainIndexTxLoop
190+
case ciTxState' of
191+
Nothing -> pure Unknown
192+
Just _ -> do
193+
blk <- fromInteger <$> currentBlock contractEnv
194+
-- This will set the validity correctly based on the txState.
195+
-- The tx will always be committed, as we wait for chainConstant blocks
196+
let status = transactionStatus blk txState txId
197+
pure $ fromRight Unknown status
185198
where
186-
findTxByIdOrLoop :: Eff effs ()
187-
findTxByIdOrLoop = do
188-
mTx <- join . preview _TxIdResponse <$> (queryChainIndex @w $ TxFromTxId txId)
189-
case mTx of
190-
Just _ -> pure ()
191-
Nothing -> do
192-
printLog @w Debug "Tx not found... looping"
193-
-- Wait for 1 block and try again
194-
_ <- awaitNBlocks @w contractEnv 1
195-
void $ getTxUpdate @w contractEnv txId
199+
-- Attempts to find the tx in chain index. If the tx does not appear after
200+
-- 5 blocks we give up
201+
findChainIndexTxLoop :: Eff effs (Maybe TxIdState)
202+
findChainIndexTxLoop = go 0
203+
where
204+
go :: Int -> Eff effs (Maybe TxIdState)
205+
go n = do
206+
mTx <- join . preview _TxIdResponse <$> (queryChainIndex @w $ TxFromTxId txId)
207+
case mTx of
208+
Just tx -> do
209+
blk <- fromInteger <$> currentBlock contractEnv
210+
pure . Just $ fromTx blk tx
211+
Nothing -> do
212+
if n >= 5
213+
then pure Nothing
214+
else do
215+
_ <- awaitNBlocks @w contractEnv 1
216+
go (n + 1)
196217

197218
-- | This will FULLY balance a transaction
198219
balanceTx ::
@@ -294,7 +315,7 @@ awaitNBlocks contractEnv n = do
294315
tip <- CardanoCLI.queryTip @w contractEnv.cePABConfig
295316
case tip of
296317
Right tip'
297-
| start + n >= tip'.block -> pure ()
318+
| start + n <= tip'.block -> pure ()
298319
_ -> go start
299320

300321
{- | Wait at least until the given time. Uses the awaitSlot under the hood, so the same constraints

0 commit comments

Comments
 (0)