Skip to content

Commit

Permalink
Implement makeAutoBalancedTransactionWithWalletOutputs
Browse files Browse the repository at this point in the history
  • Loading branch information
sjoerdvisscher committed Dec 1, 2022
1 parent 4aa6273 commit 41e7cc4
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 350 deletions.
Expand Up @@ -2,8 +2,6 @@

- Added 'Ledger.Value.currencyValueOf' function.

-->

### Security

- Fixed state machine thread token on-chain check in light of https://www.tweag.io/blog/2022-03-25-minswap-lp-vulnerability
12 changes: 0 additions & 12 deletions plutus-contract/src/Wallet/Emulator/LogMessages.hs
Expand Up @@ -48,12 +48,6 @@ instance Pretty RequestHandlerLogMsg where

data TxBalanceMsg =
BalancingUnbalancedTx UnbalancedTx
| NoOutputsAdded
| AddingPublicKeyOutputFor Value
| NoInputsAdded
| AddingInputsFor Value
| NoCollateralInputsAdded
| AddingCollateralInputsFor Value
| FinishedBalancing CardanoTx
| SigningTx CardanoTx
| SubmittingTx CardanoTx
Expand All @@ -70,12 +64,6 @@ data TxBalanceMsg =
instance Pretty TxBalanceMsg where
pretty = \case
BalancingUnbalancedTx utx -> hang 2 $ vsep ["Balancing an unbalanced transaction:", pretty utx]
NoOutputsAdded -> "No outputs added"
AddingPublicKeyOutputFor vl -> "Adding public key output for" <+> pretty vl
NoInputsAdded -> "No inputs added"
AddingInputsFor vl -> "Adding inputs for" <+> pretty vl
NoCollateralInputsAdded -> "No collateral inputs added"
AddingCollateralInputsFor vl -> "Adding collateral inputs for" <+> pretty vl
FinishedBalancing tx -> hang 2 $ vsep ["Finished balancing:", pretty tx]
SigningTx tx -> "Signing tx:" <+> pretty (getCardanoTxId tx)
SubmittingTx tx -> "Submitting tx:" <+> pretty (getCardanoTxId tx)
Expand Down
3 changes: 1 addition & 2 deletions plutus-contract/src/Wallet/Emulator/Types.hs
Expand Up @@ -62,8 +62,7 @@ module Wallet.Emulator.Types(
Wallet.Emulator.Chain.currentSlot,
processEmulated,
Wallet.Emulator.MultiAgent.fundsDistribution,
Wallet.Emulator.MultiAgent.emLog,
Wallet.Emulator.Wallet.selectCoin
Wallet.Emulator.MultiAgent.emLog
) where

import Cardano.Crypto.Wallet qualified as Crypto
Expand Down
280 changes: 31 additions & 249 deletions plutus-contract/src/Wallet/Emulator/Wallet.hs

Large diffs are not rendered by default.

Expand Up @@ -323,7 +323,7 @@ txConstraintsTxBuildFailWhenUsingV1Script =
checkPredicate "Tx.Constraints.mustReferenceOutput fails when trying to unlock funds in a PlutusV1 script"
(walletFundsChange w1 (Ada.adaValueOf (-5))
.&&. valueAtAddress mustReferenceOutputV1ValidatorAddress (== Ada.adaValueOf 5)
.&&. assertValidatedTransactionCountOfTotal 1 1 -- 2nd tx fails before validation
.&&. assertValidatedTransactionCountOfTotal 1 2
) $ do
void $ Trace.activateContract w1 mustReferenceOutputTxV1Contract tag
void $ Trace.waitNSlots 2
Expand Down
7 changes: 3 additions & 4 deletions plutus-contract/test/Spec/Emulator.hs
Expand Up @@ -16,7 +16,6 @@ import Cardano.Api.Shelley qualified as C
import Control.Lens ((&), (.~), (^.))
import Control.Monad (void)
import Control.Monad.Freer qualified as Eff
import Control.Monad.Freer.Error qualified as E
import Control.Monad.Freer.Writer (Writer, runWriter, tell)
import Data.ByteString.Lazy qualified as BSL
import Data.ByteString.Lazy.Char8 (pack)
Expand All @@ -33,6 +32,7 @@ import Ledger (CardanoTx (..), Language (PlutusV1), OnChainTx (Valid), PaymentPu
Versioned (Versioned, unversioned), cardanoTxMap, getCardanoTxOutRefs, getCardanoTxOutputs,
mkValidatorScript, onCardanoTx, outputs, txOutValue, unitDatum, unitRedeemer, unspentOutputs)
import Ledger.Ada qualified as Ada
import Ledger.Fee (selectCoin)
import Ledger.Generators (Mockchain (Mockchain))
import Ledger.Generators qualified as Gen
import Ledger.Index qualified as Index
Expand All @@ -52,10 +52,9 @@ import PlutusTx.Prelude qualified as PlutusTx
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.Golden (goldenVsString)
import Test.Tasty.Hedgehog (testPropertyNamed)
import Wallet (WalletAPIError, payToPaymentPublicKeyHash_, submitTxn)
import Wallet (payToPaymentPublicKeyHash_, submitTxn)
import Wallet.API qualified as W
import Wallet.Emulator.Chain qualified as Chain
import Wallet.Emulator.Types (selectCoin)
import Wallet.Graph qualified

tests :: TestTree
Expand Down Expand Up @@ -137,7 +136,7 @@ selectCoinProp :: Property
selectCoinProp = property $ do
inputs <- forAll $ zip [(1 :: Integer) ..] <$> Gen.list (Range.linear 1 100) Gen.genValueNonNegative
target <- forAll Gen.genValueNonNegative
let result = Eff.run $ E.runError @WalletAPIError (selectCoin inputs target)
let result = selectCoin inputs target
case result of
Left _ ->
Hedgehog.assert $ not $ foldMap snd inputs `Value.geq` target
Expand Down
24 changes: 4 additions & 20 deletions plutus-ledger-constraints/src/Ledger/Constraints/OffChain.hs
Expand Up @@ -90,8 +90,7 @@ module Ledger.Constraints.OffChain(
) where

import Cardano.Api qualified as C
import Control.Lens (_2, alaf, at, makeClassyPrisms, makeLensesFor, preview, uses, view, (%=), (&), (.=), (.~), (<>=),
(^.), (^?))
import Control.Lens (_2, alaf, at, makeClassyPrisms, makeLensesFor, preview, uses, view, (%=), (.=), (<>=), (^.), (^?))
import Control.Lens.Extras (is)
import Control.Monad (forM_, guard)
import Control.Monad.Except (MonadError (catchError, throwError), runExcept, unless)
Expand All @@ -110,7 +109,7 @@ import Data.Semigroup (First (First, getFirst))
import Data.Set (Set)
import Data.Set qualified as Set
import GHC.Generics (Generic)
import Ledger (Redeemer (Redeemer), decoratedTxOutReferenceScript, outValue)
import Ledger (Redeemer (Redeemer), decoratedTxOutReferenceScript)
import Ledger.Ada qualified as Ada
import Ledger.Address (Address, PaymentPubKey (PaymentPubKey), PaymentPubKeyHash (PaymentPubKeyHash))
import Ledger.Constraints.TxConstraints (ScriptInputConstraint (ScriptInputConstraint, icRedeemer, icTxOutRef),
Expand All @@ -121,12 +120,12 @@ import Ledger.Constraints.TxConstraints (ScriptInputConstraint (ScriptInputConst
TxConstraints (TxConstraints, txConstraintFuns, txConstraints, txOwnInputs, txOwnOutputs),
TxOutDatum (TxOutDatumHash, TxOutDatumInTx, TxOutDatumInline))
import Ledger.Crypto (pubKeyHash)
import Ledger.Index (minAdaTxOut)
import Ledger.Index (adjustTxOut)
import Ledger.Orphans ()
import Ledger.Params (PParams, Params (pNetworkId, pSlotConfig))
import Ledger.TimeSlot (posixTimeRangeToContainedSlotRange)
import Ledger.Tx (DecoratedTxOut, Language (PlutusV1, PlutusV2), ReferenceScript, TxOut (TxOut), TxOutRef,
Versioned (Versioned), txOutValue)
Versioned (Versioned))
import Ledger.Tx qualified as Tx
import Ledger.Tx.CardanoAPI qualified as C
import Ledger.Typed.Scripts (Any, ConnectionError (UnknownRef), TypedValidator (tvValidator, tvValidatorHash),
Expand Down Expand Up @@ -563,21 +562,6 @@ mkTxWithParams params lookups txc = mkSomeTx params [SomeLookupsAndConstraints l
adjustUnbalancedTx :: PParams -> UnbalancedTx -> Either Tx.ToCardanoError ([Ada.Ada], UnbalancedTx)
adjustUnbalancedTx params = alaf Compose (tx . Tx.outputs . traverse) (adjustTxOut params)

-- | Adjust a single transaction output so it contains at least the minimum amount of Ada
-- and return the adjustment (if any) and the updated TxOut.
adjustTxOut :: PParams -> TxOut -> Either Tx.ToCardanoError ([Ada.Ada], TxOut)
adjustTxOut params txOut = do
-- Increasing the ada amount can also increase the size in bytes, so start with a rough estimated amount of ada
withMinAdaValue <- C.toCardanoTxOutValue $ txOutValue txOut \/ Ada.toValue (minAdaTxOut params txOut)
let txOutEstimate = txOut & outValue .~ withMinAdaValue
minAdaTxOutEstimated' = minAdaTxOut params txOutEstimate
missingLovelace = minAdaTxOutEstimated' - Ada.fromValue (txOutValue txOut)
if missingLovelace > 0
then do
adjustedLovelace <- C.toCardanoTxOutValue $ txOutValue txOut <> Ada.toValue missingLovelace
pure ([missingLovelace], txOut & outValue .~ adjustedLovelace)
else pure ([], txOut)


updateUtxoIndex
:: ( MonadReader (ScriptLookups a) m
Expand Down
@@ -1,15 +1,3 @@
<!--
A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Removed
- A bullet item for the Removed category.
-->
### Added

- `minAdaTxOut`, computes the minimum amount of Ada required for a `TxOut` more
Expand All @@ -18,22 +6,3 @@ Uncomment the section that is right (remove the HTML comment wrapper).
### Changed

- `minAdaTxOut` is now renamed `minAdaTxOutEstimated`.

<!--
### Deprecated
- A bullet item for the Deprecated category.
-->
<!--
### Fixed
- A bullet item for the Fixed category.
-->
<!--
### Security
- A bullet item for the Security category.
-->
@@ -0,0 +1,8 @@
### Added

- Added `makeAutoBalancedTransactionWithWalletOutputs` to `Ledger.Fee`.

### Changed

- Moved `adjustTxOut` into `Ledger.Index`
- Balancing no longer logs if and which inputs and outputs were added.

0 comments on commit 41e7cc4

Please sign in to comment.