Skip to content

Commit 8f4aedc

Browse files
authored
Merge pull request #1176 from input-output-hk/calculate-min-utxo-value
Calculate min utxo value
2 parents d411872 + 1b7e1f6 commit 8f4aedc

File tree

16 files changed

+79
-34
lines changed

16 files changed

+79
-34
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ changes.
1010

1111
## [0.14.0] - UNRELEASED
1212

13+
- Remove hard-coded deposit of 2₳ from internal wallet. Now the wallet does only
14+
use as much deposit for script outputs as minimally needed and reduces the Ada
15+
locked throughout a head life-cycle.
16+
1317
- Increase maximum number of parties to 5
1418

1519
- **BREAKING** Sign the head identifier as part of snapshot signature

hydra-cardano-api/hydra-cardano-api.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ library
9292
, cardano-crypto-class >=2.1.1 && <2.2
9393
, cardano-ledger-allegra >=1.2.1 && <1.3
9494
, cardano-ledger-alonzo >=1.4 && <1.5
95+
, cardano-ledger-api >=1.5 && <1.6
9596
, cardano-ledger-babbage >=1.4.2 && <1.5
9697
, cardano-ledger-binary >=1.1.1 && <1.2
9798
, cardano-ledger-byron >=1.0.0 && <1.1

hydra-cardano-api/src/Hydra/Cardano/Api/TxOut.hs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import Hydra.Cardano.Api.TxIn (mkTxIn)
66
import Hydra.Cardano.Api.TxOutValue (mkTxOutValue)
77

88
import Cardano.Api.UTxO qualified as UTxO
9+
import Cardano.Ledger.Api qualified as Ledger
910
import Cardano.Ledger.Babbage.TxInfo qualified as Ledger
10-
import Cardano.Ledger.Core qualified as Ledger
1111
import Cardano.Ledger.Credential qualified as Ledger
1212
import Data.List qualified as List
1313
import Hydra.Cardano.Api.AddressInEra (fromPlutusAddress)
@@ -27,6 +27,14 @@ txOuts' (getTxBody -> txBody) =
2727
let TxBody TxBodyContent{txOuts} = txBody
2828
in txOuts
2929

30+
-- | Modify a 'TxOut' to set the minimum ada on the value.
31+
setMinUTxOValue ::
32+
Ledger.PParams LedgerEra ->
33+
TxOut CtxUTxO Era ->
34+
TxOut ctx Era
35+
setMinUTxOValue pparams =
36+
fromLedgerTxOut . Ledger.setMinCoinTxOut pparams . toLedgerTxOut
37+
3038
-- | Automatically balance a given output with the minimum required amount.
3139
-- Number of assets, presence of datum and/or reference scripts may affect this
3240
-- minimum value.

hydra-cardano-api/src/Hydra/Cardano/Api/Value.hs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ import PlutusLedgerApi.V2 qualified as Plutus
1616

1717
-- * Extras
1818

19-
-- | Calculate minimum value for a UTxO. Note that cardano-api defines a
20-
-- 'calculateMinimumUTxO' function but it is flawed (see NOTE below) and has an
21-
-- unsatisfactory API because it works across multiple era.
22-
-- XXX: Check if this is still true ^^^ and use it if not.
19+
-- | Calculate minimum ada as 'Value' for a 'TxOut'.
2320
minUTxOValue ::
2421
PParams LedgerEra ->
2522
TxOut CtxTx Era ->

hydra-node/hydra-node.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ test-suite tests
303303
, cardano-binary
304304
, cardano-crypto-class
305305
, cardano-ledger-alonzo
306+
, cardano-ledger-api
306307
, cardano-ledger-babbage:{cardano-ledger-babbage, testlib}
307308
, cardano-ledger-binary
308309
, cardano-ledger-core

hydra-node/src/Hydra/Chain/Direct/Tx.hs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,6 @@ data ClosedThreadOutput = ClosedThreadOutput
101101
hydraHeadV1AssetName :: AssetName
102102
hydraHeadV1AssetName = AssetName (fromBuiltin hydraHeadV1)
103103

104-
-- FIXME: sould not be hardcoded
105-
headValue :: Value
106-
headValue = lovelaceToValue (Lovelace 2_000_000)
107-
108104
-- * Create Hydra Head transactions
109105

110106
-- | Create the init transaction from some 'HeadParameters' and a single TxIn
@@ -133,7 +129,7 @@ mkHeadOutput :: NetworkId -> PolicyId -> TxOutDatum ctx -> TxOut ctx
133129
mkHeadOutput networkId tokenPolicyId datum =
134130
TxOut
135131
(mkScriptAddress @PlutusScriptV2 networkId headScript)
136-
(headValue <> valueFromList [(AssetId tokenPolicyId hydraHeadV1AssetName, 1)])
132+
(valueFromList [(AssetId tokenPolicyId hydraHeadV1AssetName, 1)])
137133
datum
138134
ReferenceScriptNone
139135
where
@@ -159,7 +155,7 @@ mkInitialOutput networkId seedTxIn (verificationKeyHash -> pkh) =
159155
where
160156
tokenPolicyId = HeadTokens.headPolicyId seedTxIn
161157
initialValue =
162-
headValue <> valueFromList [(AssetId tokenPolicyId (AssetName $ serialiseToRawBytes pkh), 1)]
158+
valueFromList [(AssetId tokenPolicyId (AssetName $ serialiseToRawBytes pkh), 1)]
163159
initialAddress =
164160
mkScriptAddress @PlutusScriptV2 networkId initialScript
165161
initialScript =

hydra-node/src/Hydra/Chain/Direct/Wallet.hs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import Cardano.Ledger.Alonzo.PlutusScriptApi (language)
1414
import Cardano.Ledger.Alonzo.Scripts (ExUnits (ExUnits), Tag (Spend), txscriptfee)
1515
import Cardano.Ledger.Alonzo.TxInfo (TranslationError)
1616
import Cardano.Ledger.Alonzo.TxWits (AlonzoTxWits (..), RdmrPtr (RdmrPtr), Redeemers (..), txdats, txscripts)
17-
import Cardano.Ledger.Api (TransactionScriptFailure, evalTxExUnits, ppMaxTxExUnitsL, ppPricesL)
17+
import Cardano.Ledger.Api (TransactionScriptFailure, ensureMinCoinTxOut, evalTxExUnits, outputsTxBodyL, ppMaxTxExUnitsL, ppPricesL)
1818
import Cardano.Ledger.Babbage.Tx (body, getLanguageView, hashScriptIntegrity, refScripts, wits)
1919
import Cardano.Ledger.Babbage.Tx qualified as Babbage
2020
import Cardano.Ledger.Babbage.TxBody (BabbageTxBody (..), outputs', spendInputs')
@@ -252,15 +252,21 @@ coverFee_ pparams systemStart epochInfo lookupUTxO walletUTxO partialTx@Babbage.
252252
(txrdmrs wits)
253253
needlesslyHighFee = calculateNeedlesslyHighFee adjustedRedeemers
254254

255+
-- Ensure we have at least the minimum amount of ada. NOTE: setMinCointTxOut
256+
-- would invalidate most Hydra protocol transactions.
257+
let txOuts = body ^. outputsTxBodyL <&> ensureMinCoinTxOut pparams
258+
259+
-- Add a change output
255260
change <-
256261
first ErrNotEnoughFunds $
257262
mkChange
258263
output
259264
resolvedInputs
260-
(toList $ outputs' body)
265+
(toList txOuts)
261266
needlesslyHighFee
267+
let newOutputs = txOuts <> StrictSeq.singleton change
268+
262269
let referenceScripts = refScripts @LedgerEra (Babbage.referenceInputs' body) (Ledger.UTxO utxo)
263-
newOutputs = outputs' body <> StrictSeq.singleton change
264270
langs =
265271
[ getLanguageView pparams l
266272
| (_hash, script) <- Map.toList $ Map.union (txscripts wits) referenceScripts

hydra-node/src/Hydra/Ledger/Cardano/Evaluate.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Cardano.Ledger.Alonzo.PlutusScriptApi qualified as Ledger
1818
import Cardano.Ledger.Alonzo.Scripts (CostModel, Prices (..), costModelsValid, emptyCostModels, mkCostModel, txscriptfee)
1919
import Cardano.Ledger.Alonzo.Scripts.Data qualified as Ledger
2020
import Cardano.Ledger.Alonzo.TxInfo (PlutusWithContext (PlutusWithContext), slotToPOSIXTime)
21-
import Cardano.Ledger.Api (ppCostModelsL, ppMaxBlockExUnitsL, ppMaxTxExUnitsL, ppMaxValSizeL, ppMinFeeAL, ppMinFeeBL, ppPricesL, ppProtocolVersionL)
21+
import Cardano.Ledger.Api (CoinPerByte (..), ppCoinsPerUTxOByteL, ppCostModelsL, ppMaxBlockExUnitsL, ppMaxTxExUnitsL, ppMaxValSizeL, ppMinFeeAL, ppMinFeeBL, ppPricesL, ppProtocolVersionL)
2222
import Cardano.Ledger.BaseTypes (BoundedRational (boundRational), ProtVer (..), natVersion)
2323
import Cardano.Ledger.Binary (getVersion)
2424
import Cardano.Ledger.Coin (Coin (Coin))
@@ -252,6 +252,7 @@ pparams =
252252
& ppMaxValSizeL .~ 1000000000
253253
& ppMinFeeAL .~ Coin 44
254254
& ppMinFeeBL .~ Coin 155381
255+
& ppCoinsPerUTxOByteL .~ CoinPerByte (Coin 4310)
255256
& ppMaxTxExUnitsL .~ toLedgerExUnits maxTxExecutionUnits
256257
& ppMaxBlockExUnitsL
257258
.~ toLedgerExUnits

hydra-node/test/Hydra/Chain/Direct/Contract/CollectCom.hs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import Hydra.Chain.Direct.Tx (
2828
InitialThreadOutput (..),
2929
assetNameFromVerificationKey,
3030
collectComTx,
31-
headValue,
3231
hydraHeadV1AssetName,
3332
mkCommitDatum,
3433
mkHeadId,
@@ -170,8 +169,7 @@ healthyCommitOutput party committed =
170169
commitAddress =
171170
mkScriptAddress @PlutusScriptV2 testNetworkId commitScript
172171
commitValue =
173-
headValue
174-
<> foldMap txOutValue committed
172+
foldMap txOutValue committed
175173
<> valueFromList
176174
[ (AssetId testPolicyId (assetNameFromVerificationKey cardanoKey), 1)
177175
]

hydra-node/test/Hydra/Chain/Direct/Contract/Commit.hs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import Hydra.Prelude
99
import Hydra.Chain.Direct.TxSpec ()
1010

1111
import Cardano.Api.UTxO qualified as UTxO
12+
import Cardano.Ledger.Api (bodyTxL)
13+
import Cardano.Ledger.Api.Tx.Body (EraTxBody (outputsTxBodyL), setMinCoinTxOut)
14+
import Control.Lens (mapped, (%~), (.~), (^.))
1215
import Data.List qualified as List
1316
import Data.Maybe (fromJust)
1417
import Hydra.Chain.Direct.Contract.Gen (genMintedOrBurnedValue)
@@ -42,12 +45,18 @@ import Test.QuickCheck (elements, oneof, scale, suchThat)
4245

4346
healthyCommitTx :: (Tx, UTxO)
4447
healthyCommitTx =
45-
(tx, lookupUTxO)
48+
(tx', lookupUTxO)
4649
where
4750
lookupUTxO =
4851
UTxO.singleton (healthyIntialTxIn, toUTxOContext healthyInitialTxOut)
4952
<> healthyCommittedUTxO
5053
<> registryUTxO scriptRegistry
54+
55+
tx' = fromLedgerTx . setOutputsMinValue $ toLedgerTx tx
56+
57+
setOutputsMinValue =
58+
bodyTxL . outputsTxBodyL . mapped %~ setMinCoinTxOut Fixture.pparams
59+
5160
tx =
5261
commitTx
5362
Fixture.testNetworkId
@@ -71,7 +80,9 @@ healthyIntialTxIn :: TxIn
7180
healthyIntialTxIn = generateWith arbitrary 42
7281

7382
healthyInitialTxOut :: TxOut CtxTx
74-
healthyInitialTxOut = mkInitialOutput Fixture.testNetworkId Fixture.testSeedInput commitVerificationKey
83+
healthyInitialTxOut =
84+
setMinUTxOValue Fixture.pparams . toUTxOContext $
85+
mkInitialOutput Fixture.testNetworkId Fixture.testSeedInput commitVerificationKey
7586

7687
-- NOTE: A UTxO of length 2 is picked to mutate it into cases where committing a
7788
-- single and empty UTxO.

0 commit comments

Comments
 (0)