diff --git a/plutus-contract/src/Plutus/Contract/Wallet.hs b/plutus-contract/src/Plutus/Contract/Wallet.hs index 9dcb591f7e..7278ef9c18 100644 --- a/plutus-contract/src/Plutus/Contract/Wallet.hs +++ b/plutus-contract/src/Plutus/Contract/Wallet.hs @@ -23,12 +23,10 @@ module Plutus.Contract.Wallet( , ExportTxInput(..) , ExportTxRedeemer(..) , export - , finalize ) where import Cardano.Api qualified as C import Control.Applicative ((<|>)) -import Control.Lens ((&), (.~)) import Control.Monad ((>=>)) import Control.Monad.Error.Lens (throwing) import Control.Monad.Freer (Eff, Member) @@ -50,10 +48,8 @@ import Ledger qualified (ScriptPurpose (..)) import Ledger qualified as P import Ledger.Ada qualified as Ada import Ledger.Constraints (mustPayToPubKey) -import Ledger.Constraints.OffChain (UnbalancedTx (UnbalancedCardanoTx, UnbalancedEmulatorTx, unBalancedTxRequiredSignatories, unBalancedTxUtxoIndex, unBalancedTxValidityTimeRange), - mkTx, unBalancedTxTx) -import Ledger.Constraints.OffChain qualified as U -import Ledger.TimeSlot (SlotConfig, posixTimeRangeToContainedSlotRange) +import Ledger.Constraints.OffChain (UnbalancedTx (unBalancedTxRequiredSignatories, unBalancedTxUtxoIndex), mkTx, + unBalancedTxTx) import Ledger.Tx (CardanoTx, TxId (TxId), TxIn (..), TxOutRef, getCardanoTxInputs, txInRef) import Ledger.Validation (CardanoLedgerError, fromPlutusIndex, makeTransactionBody) import Ledger.Value (currencyMPSHash) @@ -258,30 +254,19 @@ export -> UnbalancedTx -> Either CardanoLedgerError ExportTx export params utx = - let utxFinal = finalize (P.pSlotConfig params) utx - requiredSigners = Set.toList (unBalancedTxRequiredSignatories utxFinal) + let requiredSigners = Set.toList (unBalancedTxRequiredSignatories utx) fromCardanoTx ctx = do - utxo <- fromPlutusIndex $ P.UtxoIndex (unBalancedTxUtxoIndex utxFinal) + utxo <- fromPlutusIndex $ P.UtxoIndex (unBalancedTxUtxoIndex utx) makeTransactionBody params utxo ctx in ExportTx <$> fmap (C.makeSignedTransaction []) (either fromCardanoTx (first Right . CardanoAPI.toCardanoTxBody params requiredSigners) - (unBalancedTxTx utxFinal)) - <*> first Right (mkInputs (P.pNetworkId params) (unBalancedTxUtxoIndex utxFinal)) + (unBalancedTxTx utx)) + <*> first Right (mkInputs (P.pNetworkId params) (unBalancedTxUtxoIndex utx)) <*> either (const $ Right []) (Right . mkRedeemers) (unBalancedTxTx utx) --- | when we use UnbalancedEmulatorTx, finalize computes the final validityRange and set it into the Tx. --- In the case of a UnbalancedCardanoTx, there's nothing to do here as the validityRange of the Tx is set when we process the --- constraints. -finalize :: SlotConfig -> UnbalancedTx -> UnbalancedTx -finalize slotConfig utx@UnbalancedEmulatorTx{unBalancedTxValidityTimeRange} = - utx & U.tx - . P.validRange - .~ posixTimeRangeToContainedSlotRange slotConfig unBalancedTxValidityTimeRange -finalize _ utx@UnbalancedCardanoTx{} = utx - mkInputs :: C.NetworkId -> Map Plutus.TxOutRef P.TxOut -> Either CardanoAPI.ToCardanoError [ExportTxInput] mkInputs networkId = traverse (uncurry (toExportTxInput networkId)) . Map.toList diff --git a/plutus-contract/src/Wallet/Emulator/Wallet.hs b/plutus-contract/src/Wallet/Emulator/Wallet.hs index ca5f8102bd..c3f77db6e9 100644 --- a/plutus-contract/src/Wallet/Emulator/Wallet.hs +++ b/plutus-contract/src/Wallet/Emulator/Wallet.hs @@ -58,7 +58,7 @@ import Ledger.Constraints.OffChain qualified as U import Ledger.Credential (Credential (PubKeyCredential, ScriptCredential)) import Ledger.Fee (estimateTransactionFee, makeAutoBalancedTransaction) import Ledger.Index.Internal (UtxoIndex (UtxoIndex, getIndex)) -import Ledger.Params (Params (Params, pNetworkId, pProtocolParams, pSlotConfig)) +import Ledger.Params (Params (Params, pNetworkId, pProtocolParams)) import Ledger.Tx (CardanoTx, ChainIndexTxOut, SomeCardanoApiTx, Tx (txFee, txMint), TxOut (TxOut)) import Ledger.Tx qualified as Tx import Ledger.Tx.CardanoAPI.Internal (makeTransactionBody, toCardanoTxOut, toCardanoTxOutDatum) @@ -69,7 +69,6 @@ import Plutus.ChainIndex qualified as ChainIndex import Plutus.ChainIndex.Api (UtxosResponse (page)) import Plutus.ChainIndex.Emulator (ChainIndexEmulatorState, ChainIndexQueryEffect) import Plutus.Contract.Checkpoint (CheckpointLogMsg) -import Plutus.Contract.Wallet (finalize) import Plutus.V1.Ledger.Api (PubKeyHash, TxOutRef, ValidatorHash, Value) import PlutusTx.Prelude qualified as PlutusTx import Prettyprinter (Pretty (pretty)) @@ -317,11 +316,10 @@ handleBalance :: ) => UnbalancedTx -> Eff effs CardanoTx -handleBalance utx' = do +handleBalance utx = do utxo <- get >>= ownOutputs - params@Params { pSlotConfig, pNetworkId } <- WAPI.getClientParams - let utx = finalize pSlotConfig utx' - requiredSigners = Set.toList (U.unBalancedTxRequiredSignatories utx) + params@Params { pNetworkId } <- WAPI.getClientParams + let requiredSigners = Set.toList (U.unBalancedTxRequiredSignatories utx) eitherTx = U.unBalancedTxTx utx plUtxo = traverse (Tx.toTxOut pNetworkId) utxo mappedUtxo <- either (throwError . WAPI.ToCardanoError) pure plUtxo diff --git a/plutus-ledger-constraints/src/Ledger/Constraints/OffChain.hs b/plutus-ledger-constraints/src/Ledger/Constraints/OffChain.hs index c93f59ad48..f951988921 100644 --- a/plutus-ledger-constraints/src/Ledger/Constraints/OffChain.hs +++ b/plutus-ledger-constraints/src/Ledger/Constraints/OffChain.hs @@ -43,7 +43,6 @@ module Ledger.Constraints.OffChain( , tx , requiredSignatories , utxoIndex - , validityTimeRange , emptyUnbalancedTx , adjustUnbalancedTx , adjustTxOut @@ -105,7 +104,8 @@ import Ledger.Constraints.TxConstraints (ScriptInputConstraint (ScriptInputConst import Ledger.Crypto (pubKeyHash) import Ledger.Index (minAdaTxOut) import Ledger.Orphans () -import Ledger.Params (Params (pNetworkId)) +import Ledger.Params (Params (pNetworkId, pSlotConfig)) +import Ledger.TimeSlot (posixTimeRangeToContainedSlotRange) import Ledger.Tx (ChainIndexTxOut (_ciTxOutReferenceScript), Language (PlutusV1, PlutusV2), ReferenceScript, TxOut (TxOut), TxOutRef, Versioned (Versioned), txOutValue) import Ledger.Tx qualified as Tx @@ -115,14 +115,13 @@ import Ledger.Typed.Scripts (Any, ConnectionError (UnknownRef), TypedValidator ( import Ledger.Validation (evaluateMinLovelaceOutput, fromPlutusTxOut) import Plutus.Script.Utils.Scripts qualified as P import Plutus.Script.Utils.V2.Typed.Scripts qualified as Typed -import Plutus.V1.Ledger.Api (Datum (Datum), DatumHash, POSIXTimeRange, Validator (getValidator), Value, - getMintingPolicy) +import Plutus.V1.Ledger.Api (Datum (Datum), DatumHash, Validator (getValidator), Value, getMintingPolicy) import Plutus.V1.Ledger.Scripts (MintingPolicy (MintingPolicy), MintingPolicyHash (MintingPolicyHash), Script, ScriptHash (ScriptHash), Validator (Validator), ValidatorHash (ValidatorHash)) import Plutus.V1.Ledger.Value qualified as Value import Plutus.V2.Ledger.Tx qualified as PV2 import PlutusTx (FromData, ToData (toBuiltinData)) -import PlutusTx.Lattice (BoundedMeetSemiLattice (top), JoinSemiLattice ((\/)), MeetSemiLattice ((/\))) +import PlutusTx.Lattice (JoinSemiLattice ((\/)), MeetSemiLattice ((/\))) import PlutusTx.Numeric qualified as N import Prettyprinter (Pretty (pretty), colon, hang, vsep, (<+>)) @@ -269,14 +268,6 @@ data UnbalancedTx , unBalancedTxUtxoIndex :: Map TxOutRef TxOut -- ^ Utxo lookups that are used for adding inputs to the 'UnbalancedTx'. -- Simply refers to 'slTxOutputs' of 'ScriptLookups'. - , unBalancedTxValidityTimeRange :: POSIXTimeRange - -- ^ The reason this is a separate field instead of setting the - -- 'Plutus.txValidRange' of 'Plutus.Tx' is because the 'Plutus.txValidRange' is - -- specified as a 'SlotRange', but the user must specify the validity - -- range in terms of 'POSIXTimeRange' instead. Thus, before submitting - -- this transaction to the blockchain, we must convert this - -- 'POSIXTimeRange' to 'SlotRange' using a 'SlotConfig'. See - -- 'Plutus.Contract.Wallet.finalize'. } | UnbalancedCardanoTx { unBalancedCardanoBuildTx :: C.CardanoBuildTx @@ -297,7 +288,6 @@ makeLensesFor , ("unBalancedCardanoBuildTx", "cardanoTx") , ("unBalancedTxRequiredSignatories", "requiredSignatories") , ("unBalancedTxUtxoIndex", "utxoIndex") - , ("unBalancedTxValidityTimeRange", "validityTimeRange") ] ''UnbalancedTx unBalancedTxTx :: UnbalancedTx -> Either C.CardanoBuildTx Tx.Tx @@ -305,15 +295,14 @@ unBalancedTxTx UnbalancedEmulatorTx{unBalancedEmulatorTx} = Right unBalancedE unBalancedTxTx UnbalancedCardanoTx{unBalancedCardanoBuildTx} = Left unBalancedCardanoBuildTx emptyUnbalancedTx :: UnbalancedTx -emptyUnbalancedTx = UnbalancedEmulatorTx mempty mempty mempty top +emptyUnbalancedTx = UnbalancedEmulatorTx mempty mempty mempty instance Pretty UnbalancedTx where - pretty (UnbalancedEmulatorTx utx rs utxo vr) = + pretty (UnbalancedEmulatorTx utx rs utxo) = vsep [ hang 2 $ vsep ["Tx:", pretty utx] , hang 2 $ vsep $ "Requires signatures:" : (pretty <$> Set.toList rs) , hang 2 $ vsep $ "Utxo index:" : (pretty <$> Map.toList utxo) - , hang 2 $ vsep ["Validity range:", pretty vr] ] pretty (UnbalancedCardanoTx utx rs utxo) = vsep @@ -702,8 +691,13 @@ processConstraint = \case let dvHash = P.datumHash dv unless (dvHash `elem` Map.keys datums) (throwError $ DatumNotFoundInTx dvHash) - MustValidateIn timeRange -> - unbalancedTx . validityTimeRange %= (timeRange /\) + MustValidateIn timeRange -> do + slotRange <- + gets ( flip posixTimeRangeToContainedSlotRange timeRange + . pSlotConfig + . cpsParams + ) + unbalancedTx . tx . Tx.validRange %= (slotRange /\) MustBeSignedBy pk -> unbalancedTx . requiredSignatories <>= Set.singleton pk MustSpendAtLeast vl -> valueSpentInputs <>= required vl diff --git a/plutus-tx-constraints/src/Ledger/Tx/Constraints/OffChain.hs b/plutus-tx-constraints/src/Ledger/Tx/Constraints/OffChain.hs index bdc5ab4ed1..53b1b83093 100644 --- a/plutus-tx-constraints/src/Ledger/Tx/Constraints/OffChain.hs +++ b/plutus-tx-constraints/src/Ledger/Tx/Constraints/OffChain.hs @@ -43,7 +43,6 @@ module Ledger.Tx.Constraints.OffChain( , txOuts , P.requiredSignatories , P.utxoIndex - , P.validityTimeRange , emptyUnbalancedTx , P.adjustUnbalancedTx , MkTxError(..) diff --git a/plutus-use-cases/test/Spec/crowdfundingEmulatorTestOutput.txt b/plutus-use-cases/test/Spec/crowdfundingEmulatorTestOutput.txt index 5d9a75c6ad..9ea8b35b15 100644 --- a/plutus-use-cases/test/Spec/crowdfundingEmulatorTestOutput.txt +++ b/plutus-use-cases/test/Spec/crowdfundingEmulatorTestOutput.txt @@ -34,14 +34,12 @@ Slot 1: W[2]: Balancing an unbalanced transaction: fee: Value (Map []) mps: signatures: - validity range: Interval {ivFrom = LowerBound NegInf True, ivTo = UpperBound PosInf True} + validity range: Interval {ivFrom = LowerBound NegInf True, ivTo = UpperBound (Finite (Slot {getSlot = 20})) False} data: ( 77ab184b7537cd4b1dc3730f6a8a76a3d3aad1642fae9d769aa5dae40be38b51 , "\128\164\244[V\184\141\DC19\218#\188L\222\136\166\254\253 =" )} Requires signatures: Utxo index: - Validity range: - (-∞ , POSIXTime 1596059111000 ] Slot 1: W[4]: Finished balancing: Tx 1392dd20a08de6c8f41ed6a1418bd6092c75f95ecbf5e3507e2039b601fc00ba: {inputs: @@ -208,7 +202,7 @@ Slot 20: W[1]: Balancing an unbalanced transaction: fee: Value (Map []) mps: signatures: - validity range: Interval {ivFrom = LowerBound NegInf True, ivTo = UpperBound PosInf True} + validity range: Interval {ivFrom = LowerBound (Finite (Slot {getSlot = 20})) True, ivTo = UpperBound (Finite (Slot {getSlot = 29})) True} data: ( 2cc2afd267462229babbc139837611310e4307bd6c7e870049c22fb02c2ad122 , ".\n\214\f2\a$\140\236\212}\189\227\215R\224\170\209A\214\184\248\SUB\194\198\236\162|" ) @@ -235,8 +229,6 @@ Slot 20: W[1]: Balancing an unbalanced transaction: ScriptCredential: 8ff252c8c5423de7925e0c556871c90ed904ec3beb3dab519e9bfd9f (no staking credential) with datum hash 77ab184b7537cd4b1dc3730f6a8a76a3d3aad1642fae9d769aa5dae40be38b51 and with no reference script ) - Validity range: - [ POSIXTime 1596059111000 , POSIXTime 1596059120999 ] Slot 20: W[1]: Finished balancing: Tx 0ef047e168d9ca4da973ed6010146ebc2bf02498a8e51f3058c958f8b1367ec3: {inputs: