Skip to content

Commit 53cd2de

Browse files
committed
reproduce issue where we can't recover deposit from previous open head
1 parent 6452d6f commit 53cd2de

File tree

2 files changed

+110
-20
lines changed

2 files changed

+110
-20
lines changed

hydra-cluster/src/Hydra/Cluster/Scenarios.hs

Lines changed: 107 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,8 +1516,8 @@ canRecoverDeposit tracer workDir backend hydraScriptsTxId =
15161516
hydraTracer = contramap FromHydraNode tracer
15171517

15181518
-- | Open a single participant head, deposit, Close and then recover it.
1519-
canRecoverDepositWhenClosed :: ChainBackend backend => Tracer IO EndToEndLog -> FilePath -> backend -> [TxId] -> IO ()
1520-
canRecoverDepositWhenClosed tracer workDir backend hydraScriptsTxId =
1519+
canRecoverDepositInAnyState :: ChainBackend backend => Tracer IO EndToEndLog -> FilePath -> backend -> [TxId] -> IO ()
1520+
canRecoverDepositInAnyState tracer workDir backend hydraScriptsTxId =
15211521
(`finally` returnFundsToFaucet tracer backend Alice) $ do
15221522
refuelIfNeeded tracer backend Alice 30_000_000
15231523
-- NOTE: Directly expire deposits
@@ -1541,60 +1541,150 @@ canRecoverDepositWhenClosed tracer workDir backend hydraScriptsTxId =
15411541
-- Get some L1 funds
15421542
(walletVk, walletSk) <- generate genKeyPair
15431543
let commitAmount = 5_000_000
1544-
commitUTxO <- seedFromFaucet backend walletVk commitAmount (contramap FromFaucet tracer)
1544+
commitUTxO1 <- seedFromFaucet backend walletVk commitAmount (contramap FromFaucet tracer)
1545+
commitUTxO2 <- seedFromFaucet backend walletVk commitAmount (contramap FromFaucet tracer)
1546+
commitUTxO3 <- seedFromFaucet backend walletVk commitAmount (contramap FromFaucet tracer)
15451547

15461548
(balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
1547-
`shouldReturn` lovelaceToValue commitAmount
1549+
`shouldReturn` lovelaceToValue (commitAmount * 3)
15481550

1549-
depositTransaction <-
1551+
-- Increment commit #1
1552+
depositTransaction1 <-
15501553
parseUrlThrow ("POST " <> hydraNodeBaseUrl n1 <> "/commit")
1551-
<&> setRequestBodyJSON commitUTxO
1554+
<&> setRequestBodyJSON commitUTxO1
15521555
>>= httpJSON
15531556
<&> getResponseBody
15541557

1555-
let tx = signTx walletSk depositTransaction
1556-
Backend.submitTransaction backend tx
1558+
let tx1 = signTx walletSk depositTransaction1
1559+
Backend.submitTransaction backend tx1
1560+
1561+
deadline1 <- waitMatch 10 n1 $ \v -> do
1562+
guard $ v ^? key "tag" == Just "CommitRecorded"
1563+
v ^? key "deadline" >>= parseMaybe parseJSON
1564+
1565+
(selectLovelace . balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
1566+
`shouldReturn` (commitAmount * 2)
1567+
1568+
-- Increment commit #2
1569+
depositTransaction2 <-
1570+
parseUrlThrow ("POST " <> hydraNodeBaseUrl n1 <> "/commit")
1571+
<&> setRequestBodyJSON commitUTxO2
1572+
>>= httpJSON
1573+
<&> getResponseBody
1574+
1575+
let tx2 = signTx walletSk depositTransaction2
1576+
Backend.submitTransaction backend tx2
15571577

1558-
deadline <- waitMatch 10 n1 $ \v -> do
1578+
deadline2 <- waitMatch 10 n1 $ \v -> do
1579+
guard $ v ^? key "tag" == Just "CommitRecorded"
1580+
v ^? key "deadline" >>= parseMaybe parseJSON
1581+
1582+
(selectLovelace . balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
1583+
`shouldReturn` commitAmount
1584+
1585+
-- Increment commit #3
1586+
depositTransaction3 <-
1587+
parseUrlThrow ("POST " <> hydraNodeBaseUrl n1 <> "/commit")
1588+
<&> setRequestBodyJSON commitUTxO3
1589+
>>= httpJSON
1590+
<&> getResponseBody
1591+
1592+
let tx3 = signTx walletSk depositTransaction3
1593+
Backend.submitTransaction backend tx3
1594+
1595+
deadline3 <- waitMatch 10 n1 $ \v -> do
15591596
guard $ v ^? key "tag" == Just "CommitRecorded"
15601597
v ^? key "deadline" >>= parseMaybe parseJSON
15611598

15621599
(selectLovelace . balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
15631600
`shouldReturn` 0
15641601

1602+
-- Close the head
15651603
send n1 $ input "Close" []
15661604

1567-
deadline' <- waitMatch (10 * blockTime) n1 $ \v -> do
1605+
deadline1' <- waitMatch (10 * blockTime) n1 $ \v -> do
15681606
guard $ v ^? key "tag" == Just "HeadIsClosed"
15691607
v ^? key "contestationDeadline" . _JSON
15701608

1571-
let path = BSC.unpack $ urlEncode False $ encodeUtf8 $ T.pack $ show (getTxId $ getTxBody tx)
1609+
-- Recover deposit #1
1610+
let path1 = BSC.unpack $ urlEncode False $ encodeUtf8 $ T.pack $ show (getTxId $ getTxBody tx1)
15721611
-- NOTE: we need to wait for the deadline to pass before we can recover the deposit
1573-
diff <- realToFrac . diffUTCTime deadline <$> getCurrentTime
1574-
threadDelay $ diff + 1
1612+
diff1 <- realToFrac . diffUTCTime deadline1 <$> getCurrentTime
1613+
threadDelay $ diff1 + 1
15751614

15761615
(`shouldReturn` "OK") $
1577-
parseUrlThrow ("DELETE " <> hydraNodeBaseUrl n1 <> "/commits/" <> path)
1616+
parseUrlThrow ("DELETE " <> hydraNodeBaseUrl n1 <> "/commits/" <> path1)
15781617
>>= httpJSON
15791618
<&> getResponseBody @String
15801619

15811620
waitMatch 20 n1 $ \v -> do
15821621
guard $ v ^? key "tag" == Just "CommitRecovered"
1583-
guard $ v ^? key "recoveredUTxO" == Just (toJSON commitUTxO)
1622+
guard $ v ^? key "recoveredUTxO" == Just (toJSON commitUTxO1)
15841623

15851624
(balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
15861625
`shouldReturn` lovelaceToValue commitAmount
15871626

1588-
remainingTime <- diffUTCTime deadline' <$> getCurrentTime
1627+
-- Fanout the head
1628+
remainingTime <- diffUTCTime deadline1' <$> getCurrentTime
15891629
waitFor hydraTracer (remainingTime + 3 * blockTime) [n1] $
15901630
output "ReadyToFanout" ["headId" .= headId]
15911631
send n1 $ input "Fanout" []
15921632
waitMatch (20 * blockTime) n1 $ \v ->
15931633
guard $ v ^? key "tag" == Just "HeadIsFinalized"
15941634

1635+
-- Recover deposit #2
1636+
let path2 = BSC.unpack $ urlEncode False $ encodeUtf8 $ T.pack $ show (getTxId $ getTxBody tx2)
1637+
-- NOTE: we need to wait for the deadline to pass before we can recover the deposit
1638+
diff2 <- realToFrac . diffUTCTime deadline2 <$> getCurrentTime
1639+
threadDelay $ diff2 + 1
1640+
1641+
(`shouldReturn` "OK") $
1642+
parseUrlThrow ("DELETE " <> hydraNodeBaseUrl n1 <> "/commits/" <> path2)
1643+
>>= httpJSON
1644+
<&> getResponseBody @String
1645+
1646+
waitMatch 20 n1 $ \v -> do
1647+
guard $ v ^? key "tag" == Just "CommitRecovered"
1648+
guard $ v ^? key "recoveredUTxO" == Just (toJSON commitUTxO2)
1649+
1650+
(balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
1651+
`shouldReturn` lovelaceToValue (commitAmount * 2)
1652+
1653+
-- Assert final wallet balance
1654+
(balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
1655+
`shouldReturn` balance (commitUTxO1 <> commitUTxO2)
1656+
1657+
-- Open a new head
1658+
send n1 $ input "Init" []
1659+
headId2 <- waitMatch 10 n1 $ headIsInitializingWith (Set.fromList [alice])
1660+
1661+
-- Commit nothing
1662+
requestCommitTx n1 mempty >>= Backend.submitTransaction backend
1663+
1664+
waitFor hydraTracer (20 * blockTime) [n1] $
1665+
output "HeadIsOpen" ["utxo" .= object mempty, "headId" .= headId2]
1666+
1667+
-- Recover deposit #3
1668+
let path3 = BSC.unpack $ urlEncode False $ encodeUtf8 $ T.pack $ show (getTxId $ getTxBody tx3)
1669+
-- NOTE: we need to wait for the deadline to pass before we can recover the deposit
1670+
diff3 <- realToFrac . diffUTCTime deadline3 <$> getCurrentTime
1671+
threadDelay $ diff3 + 1
1672+
1673+
(`shouldReturn` "OK") $
1674+
parseUrlThrow ("DELETE " <> hydraNodeBaseUrl n1 <> "/commits/" <> path3)
1675+
>>= httpJSON
1676+
<&> getResponseBody @String
1677+
1678+
waitMatch 20 n1 $ \v -> do
1679+
guard $ v ^? key "tag" == Just "CommitRecovered"
1680+
guard $ v ^? key "recoveredUTxO" == Just (toJSON commitUTxO3)
1681+
1682+
(balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
1683+
`shouldReturn` lovelaceToValue (commitAmount * 3)
1684+
15951685
-- Assert final wallet balance
15961686
(balance <$> Backend.queryUTxOFor backend QueryTip walletVk)
1597-
`shouldReturn` balance commitUTxO
1687+
`shouldReturn` balance (commitUTxO1 <> commitUTxO2 <> commitUTxO3)
15981688
where
15991689
hydraTracer = contramap FromHydraNode tracer
16001690

hydra-cluster/test/Test/EndToEndSpec.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import Hydra.Cluster.Scenarios (
5454
canDecommit,
5555
canDepositPartially,
5656
canRecoverDeposit,
57-
canRecoverDepositWhenClosed,
57+
canRecoverDepositInAnyState,
5858
canResumeOnMemberAlreadyBootstrapped,
5959
canSeePendingDeposits,
6060
canSideLoadSnapshot,
@@ -312,11 +312,11 @@ spec = around (showLogsOnFailure "EndToEndSpec") $ do
312312
withBackend (contramap FromCardanoNode tracer) tmpDir $ \_ backend -> do
313313
publishHydraScriptsAs backend Faucet
314314
>>= canRecoverDeposit tracer tmpDir backend
315-
it "can recover deposit when closed" $ \tracer -> do
315+
it "can recover deposit in any state" $ \tracer -> do
316316
withClusterTempDir $ \tmpDir -> do
317317
withBackend (contramap FromCardanoNode tracer) tmpDir $ \_ backend -> do
318318
publishHydraScriptsAs backend Faucet
319-
>>= canRecoverDepositWhenClosed tracer tmpDir backend
319+
>>= canRecoverDepositInAnyState tracer tmpDir backend
320320
it "can see pending deposits" $ \tracer -> do
321321
withClusterTempDir $ \tmpDir -> do
322322
withBackend (contramap FromCardanoNode tracer) tmpDir $ \blockTime backend -> do

0 commit comments

Comments
 (0)