Skip to content

Commit

Permalink
Prevent empty decommits (#1534)
Browse files Browse the repository at this point in the history
fix #1502 

Add a test that convinces us empty inputs in decommit tx are prevented.

---

<!-- 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
  • Loading branch information
ch1bo committed Jul 26, 2024
2 parents 713db26 + ce61a12 commit 2f4ac12
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
1 change: 0 additions & 1 deletion hydra-node/src/Hydra/HeadLogic.hs
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,6 @@ onOpenNetworkReqDec ::
tx ->
Outcome tx
onOpenNetworkReqDec env ledger ttl openState decommitTx =
-- TODO: require outputs(tx) ≠ ∅ to prevent decommit spam? See hydra#1502
-- Spec: wait txω =⊥ ∧ L̂ ◦ tx ≠ ⊥
waitOnApplicableDecommit $ \newLocalUTxO -> do
-- Spec: L̂ ← L̂ ◦ tx \ outputs(tx)
Expand Down
32 changes: 31 additions & 1 deletion hydra-node/test/Hydra/HeadLogicSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ import Hydra.Prelude
import Test.Hydra.Prelude

import Cardano.Api.UTxO qualified as UTxO
import Cardano.Ledger.Api (bodyTxL, inputsTxBodyL)
import Control.Lens ((.~))
import Data.List qualified as List
import Data.Map (notMember)
import Data.Set qualified as Set
import Hydra.API.ServerOutput (DecommitInvalidReason (..), ServerOutput (..))
import Hydra.Cardano.Api (genTxIn, mkVkAddress, txOutValue, unSlotNo, pattern TxValidityUpperBound)
import Hydra.Cardano.Api (fromLedgerTx, genTxIn, mkVkAddress, toLedgerTx, txOutValue, unSlotNo, pattern TxValidityUpperBound)
import Hydra.Chain (
ChainEvent (..),
HeadParameters (..),
Expand Down Expand Up @@ -670,6 +672,34 @@ spec =
} -> null localTxs
_ -> False

prop "empty inputs in decommit tx are prevented" $ \tx -> do
let ledger = cardanoLedger Fixture.defaultGlobals Fixture.defaultLedgerEnv
let st =
Open
OpenState
{ parameters = HeadParameters defaultContestationPeriod threeParties
, coordinatedHeadState =
CoordinatedHeadState
{ localUTxO = mempty
, allTxs = mempty
, localTxs = []
, confirmedSnapshot = InitialSnapshot testHeadId mempty
, seenSnapshot = NoSeenSnapshot
, decommitTx = Nothing
, version = 0
}
, chainState = Prelude.error "should not be used"
, headId = testHeadId
, headSeed = testHeadSeed
, currentSlot = ChainSlot 1
}

let tx' = fromLedgerTx (toLedgerTx tx & bodyTxL . inputsTxBodyL .~ mempty)
let input = receiveMessage $ ReqDec{transaction = tx'}
update bobEnv ledger st input `shouldSatisfy` \case
Wait WaitOnNotApplicableDecommitTx{notApplicableReason = DecommitTxInvalid{}} _ -> True
_ -> False

-- * Properties

prop_ignoresUnrelatedOnInitTx :: Property
Expand Down

0 comments on commit 2f4ac12

Please sign in to comment.