Skip to content

Commit fd42411

Browse files
authored
Observe correct deposit UTxO in Increment observation (#1924)
This PR fixes the bug we found where increment observation would pick the wrong deposit UTxO. --- <!-- Consider each and tick it off one way or the other --> * [x] CHANGELOG updated or not needed * [x] Documentation updated or not needed * [x] Haddocks updated or not needed * [x] No new TODOs introduced or explained herafter
2 parents dc8e77b + 1208e9c commit fd42411

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-2
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ changes.
2626
ETCD_AUTO_COMPACTION_RETENTION=168h
2727
```
2828
29+
- Fix a bug in increment observation where wrong deposited UTxO was picked up.
30+
2931
- Fix a bug where incremental commits / decommits were not correctly observed after restart of `hydra-node`. This was due to incorrect handling of internal chain state [#1894](https://github.com/cardano-scaling/hydra/pull/1894)
3032
3133
- Fix a bug where decoding `Party` information from chain would crash the node or chain observer.

hydra-node/hydra-node.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ test-suite tests
328328
, hydra-node
329329
, hydra-node:testlib
330330
, hydra-plutus
331+
, hydra-plutus-extras
331332
, hydra-prelude
332333
, hydra-test-utils
333334
, hydra-tx

hydra-node/test/Hydra/Chain/Direct/StateSpec.hs

+33-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import Hydra.Cardano.Api (
1919
UTxO,
2020
findRedeemerSpending,
2121
genTxIn,
22+
getTxBody,
23+
getTxId,
2224
hashScript,
2325
isScriptTxOut,
2426
lovelaceToValue,
@@ -70,6 +72,7 @@ import Hydra.Chain.Direct.State (
7072
getContestationDeadline,
7173
getKnownUTxO,
7274
initialize,
75+
maxGenParties,
7376
observeClose,
7477
observeCollect,
7578
observeCommit,
@@ -79,6 +82,7 @@ import Hydra.Chain.Direct.State (
7982
unsafeCollect,
8083
unsafeCommit,
8184
unsafeFanout,
85+
unsafeIncrement,
8286
unsafeObserveInitAndCommits,
8387
)
8488
import Hydra.Chain.Direct.State qualified as Transition
@@ -93,6 +97,7 @@ import Hydra.Ledger.Cardano.Evaluate (
9397
)
9498
import Hydra.Ledger.Cardano.Time (slotNoFromUTCTime)
9599
import Hydra.Plutus (initialValidatorScript)
100+
import Hydra.Plutus.Extras.Time (posixToUTCTime)
96101
import Hydra.Tx.Close (ClosedThreadOutput (closedContesters))
97102
import Hydra.Tx.ContestationPeriod (toNominalDiffTime)
98103
import Hydra.Tx.Deposit (DepositObservation (..), observeDepositTx)
@@ -110,6 +115,7 @@ import Hydra.Tx.Observe (
110115
observeCommitTx,
111116
observeDecrementTx,
112117
observeHeadTx,
118+
observeIncrementTx,
113119
observeInitTx,
114120
)
115121
import Hydra.Tx.Recover (RecoverObservation (..), observeRecoverTx)
@@ -148,7 +154,7 @@ import Test.QuickCheck (
148154
(===),
149155
(==>),
150156
)
151-
import Test.QuickCheck.Monadic (monadicIO, monadicST, pick)
157+
import Test.QuickCheck.Monadic (assert, assertWith, monadicIO, monadicST, monitor, pick)
152158
import Prelude qualified
153159

154160
spec :: Spec
@@ -348,6 +354,7 @@ spec = parallel $ do
348354
describe "increment" $ do
349355
propBelowSizeLimit maxTxSize forAllIncrement
350356
propIsValid forAllIncrement
357+
it "increment observation observes correct utxo" prop_incrementObservesCorrectUTxO
351358

352359
describe "decrement" $ do
353360
propBelowSizeLimit maxTxSize forAllDecrement
@@ -528,6 +535,31 @@ prop_canCloseFanoutEveryCollect = monadicST $ do
528535
checkCoverage
529536
(collectFails .||. collectCloseAndFanoutPass)
530537

538+
prop_incrementObservesCorrectUTxO :: Property
539+
prop_incrementObservesCorrectUTxO = monadicIO $ do
540+
(ctx, st@OpenState{headId}, _, txDeposit) <- pickBlind $ genDepositTx maxGenParties
541+
(_, _, _, txDeposit2) <- pickBlind $ genDepositTx maxGenParties
542+
case observeDepositTx (ctxNetworkId ctx) txDeposit of
543+
Nothing -> assertWith False "Deposit not observed"
544+
Just DepositObservation{depositTxId = depositedTxId, deadline} -> do
545+
cctx <- pickBlind $ pickChainContext ctx
546+
let slotNo = slotNoFromUTCTime systemStart slotLength (posixToUTCTime deadline)
547+
let version = 0
548+
let openUTxO = getKnownUTxO st
549+
-- NOTE: Use second deposit utxo deliberately here to test that the
550+
-- increment observation picks the correct one.
551+
-- We rely here on a fact that eventually this property will generate
552+
-- UTxO which would be wrongly picked up by the increment observation.
553+
let utxo = getKnownUTxO st <> utxoFromTx txDeposit <> utxoFromTx txDeposit2
554+
snapshot <- pickBlind $ Snapshot.genConfirmedSnapshot headId version 1 openUTxO (Just utxo) Nothing (ctxHydraSigningKeys ctx)
555+
let txIncrement = unsafeIncrement cctx utxo headId (ctxHeadParameters ctx) snapshot depositedTxId slotNo
556+
case observeIncrementTx utxo txIncrement of
557+
Nothing -> assertWith False "Increment not observed"
558+
Just IncrementObservation{depositTxId} -> do
559+
let txDepositId = getTxId (getTxBody txDeposit)
560+
monitor (counterexample $ "Expected TxId:" <> show depositTxId <> " Actual TxId:" <> show txDepositId)
561+
assert (depositTxId == txDepositId)
562+
531563
--
532564
-- Generic Properties
533565
--

hydra-tx/src/Hydra/Tx/Increment.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ observeIncrementTx ::
121121
observeIncrementTx utxo tx = do
122122
let inputUTxO = resolveInputsUTxO utxo tx
123123
(headInput, headOutput) <- findTxOutByScript inputUTxO Head.validatorScript
124-
(TxIn depositTxId _, depositOutput) <- findTxOutByScript utxo depositValidatorScript
124+
(TxIn depositTxId _, depositOutput) <- findTxOutByScript inputUTxO depositValidatorScript
125125
dat <- txOutScriptData $ toTxContext depositOutput
126126
-- we need to be able to decode the datum, no need to use it tho
127127
_ :: Deposit.DepositDatum <- fromScriptData dat

0 commit comments

Comments
 (0)