Skip to content

Commit

Permalink
Merge pull request #437 from tweag/mm/no-value-utils
Browse files Browse the repository at this point in the history
Removing ValueUtils.hs
  • Loading branch information
mmontin authored Jul 18, 2024
2 parents 3603c99 + 3a46807 commit da69805
Show file tree
Hide file tree
Showing 19 changed files with 69 additions and 117 deletions.
2 changes: 1 addition & 1 deletion cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ package cardano-crypto-praos
source-repository-package
type: git
location: https://github.com/IntersectMBO/cardano-node-emulator
tag: 6b57e0ce51992d9d3113715e1c3036482dbd747e
tag: 645c1d04ba1c90aa76ad720e66215e754568b81e
subdir:
cardano-node-emulator
plutus-ledger
Expand Down
1 change: 0 additions & 1 deletion cooked-validators.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ library
Cooked.Tweak.TamperDatum
Cooked.Tweak.ValidityRange
Cooked.Validators
Cooked.ValueUtils
Cooked.Wallet
other-modules:
Paths_cooked_validators
Expand Down
1 change: 0 additions & 1 deletion src/Cooked.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,4 @@ import Cooked.ShowBS as X
import Cooked.Skeleton as X
import Cooked.Tweak as X
import Cooked.Validators as X
import Cooked.ValueUtils as X
import Cooked.Wallet as X
4 changes: 2 additions & 2 deletions src/Cooked/InitialDistribution.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import Control.Monad
import Cooked.MockChain.GenerateTx
import Cooked.MockChain.MinAda
import Cooked.Skeleton
import Cooked.ValueUtils
import Cooked.Wallet
import Data.Default
import Data.List
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V3 qualified as Api

-- * Initial distribution of funds
Expand Down Expand Up @@ -48,7 +48,7 @@ data InitialDistribution where

-- | 5 UTxOs with 100 Ada each, for each of the 'knownWallets'
instance Default InitialDistribution where
def = distributionFromList . zip knownWallets . repeat . replicate 5 $ ada 100
def = distributionFromList . zip knownWallets . repeat . replicate 5 $ Script.ada 100

instance Semigroup InitialDistribution where
i <> j = InitialDistribution (unInitialDistribution i <> unInitialDistribution j)
Expand Down
4 changes: 2 additions & 2 deletions src/Cooked/MockChain/Balancing.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import Cooked.MockChain.MinAda
import Cooked.MockChain.UtxoSearch
import Cooked.Output
import Cooked.Skeleton
import Cooked.ValueUtils
import Cooked.Wallet
import Data.Bifunctor
import Data.Function
Expand All @@ -27,6 +26,7 @@ import Data.Set (Set)
import Data.Set qualified as Set
import Optics.Core
import Plutus.Script.Utils.Ada qualified as Script
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V1.Value qualified as Api
import PlutusLedgerApi.V3 qualified as Api
import PlutusTx.Prelude qualified as PlutusTx
Expand Down Expand Up @@ -280,7 +280,7 @@ estimateTxSkelFee skel fee collateralIns returnCollateralWallet = do
-- words, this ensures that the following equation holds: input value + minted
-- value = output value + burned value + fee + deposits
computeBalancedTxSkel :: (MonadBlockChainBalancing m) => Wallet -> BalancingOutputs -> TxSkel -> Fee -> m TxSkel
computeBalancedTxSkel balancingWallet balancingUtxos txSkel@TxSkel {..} (lovelace -> feeValue) = do
computeBalancedTxSkel balancingWallet balancingUtxos txSkel@TxSkel {..} (Script.lovelace -> feeValue) = do
-- We compute the necessary values from the skeleton that are part of the
-- equation, except for the `feeValue` which we already have.
let (burnedValue, mintedValue) = Api.split $ txSkelMintsValue txSkelMints
Expand Down
6 changes: 3 additions & 3 deletions src/Cooked/MockChain/MinAda.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import Control.Monad.Except
import Cooked.MockChain.BlockChain
import Cooked.MockChain.GenerateTx
import Cooked.Skeleton
import Cooked.ValueUtils
import Optics.Core
import Plutus.Script.Utils.Ada qualified as Script
import Plutus.Script.Utils.Value qualified as Script

-- | This provides the minimum amount of ada required in a given `TxSkelOut`. As
-- we need to transform our output into a Cardano output to compute this value,
Expand All @@ -41,10 +41,10 @@ getTxSkelOutMinAda Emulator.Params {..} txSkelOut =
-- https://github.com/input-output-hk/plutus-apps/blob/8706e6c7c525b4973a7b6d2ed7c9d0ef9cd4ef46/plutus-ledger/src/Ledger/Index.hs#L124
toTxSkelOutWithMinAda :: Emulator.Params -> TxSkelOut -> Either GenerateTxError TxSkelOut
toTxSkelOutWithMinAda params txSkelOut = do
let Script.Lovelace oldAda = txSkelOut ^. txSkelOutValueL % adaL
let Script.Lovelace oldAda = txSkelOut ^. txSkelOutValueL % Script.adaL
requiredAda <- getTxSkelOutMinAda params txSkelOut
if oldAda < requiredAda
then toTxSkelOutWithMinAda params $ txSkelOut & txSkelOutValueL % adaL .~ Script.Lovelace requiredAda
then toTxSkelOutWithMinAda params $ txSkelOut & txSkelOutValueL % Script.adaL .~ Script.Lovelace requiredAda
else return txSkelOut

-- | This transforms a skeleton by replacing all its `TxSkelOut` by their
Expand Down
43 changes: 0 additions & 43 deletions src/Cooked/ValueUtils.hs

This file was deleted.

14 changes: 1 addition & 13 deletions src/Cooked/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import Ledger.Address qualified as Ledger
import Ledger.CardanoWallet qualified as Ledger
import Ledger.Crypto qualified as Ledger
import PlutusLedgerApi.V3 qualified as Api
import Unsafe.Coerce

-- * MockChain Wallets

Expand Down Expand Up @@ -94,17 +93,6 @@ walletAddress w =
walletSK :: Wallet -> PrivateKey
walletSK = Ledger.unPaymentPrivateKey . Ledger.paymentPrivateKey

-- FIXME Massive hack to be able to open a 'MockPrivateKey'; this is needed
-- because the constructor and accessors to 'MockPrivateKey' are private.
-- Hence, we make an isomorphic datatype, 'unsafeCoerce' to this datatype then
-- extract whatever we need from it.
newtype HACK = HACK PrivateKey

-- | Retrieves a wallet's private staking key (secret key SK), if any
walletStakingSK :: Wallet -> Maybe PrivateKey
walletStakingSK = fmap hackUnMockPrivateKey . Ledger.mwStakeKey
where
-- To only be applied to @MockPrivateKey@; the function is polymorphic
-- because @MockPrivateKey@ is not exported either
hackUnMockPrivateKey :: a -> PrivateKey
hackUnMockPrivateKey x = let HACK y = unsafeCoerce x in y
walletStakingSK = fmap Ledger.unStakePrivateKey . Ledger.stakePrivateKey
5 changes: 3 additions & 2 deletions tests/Cooked/Attack/DoubleSatSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Optics.Core
import Plutus.Script.Utils.Ada qualified as Script
import Plutus.Script.Utils.Typed qualified as Script
import Plutus.Script.Utils.V3.Typed.Scripts qualified as Script
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V3 qualified as Api
import PlutusTx qualified
import PlutusTx.Prelude qualified as PlutusTx
Expand Down Expand Up @@ -115,8 +116,8 @@ bValidator =
customInitDist :: InitialDistribution
customInitDist =
def
<> InitialDistribution (paysScript aValidator ADatum . ada <$> [2, 3, 4, 5])
<> InitialDistribution (paysScript bValidator BDatum . ada <$> [6, 7])
<> InitialDistribution (paysScript aValidator ADatum . Script.ada <$> [2, 3, 4, 5])
<> InitialDistribution (paysScript bValidator BDatum . Script.ada <$> [6, 7])

-- | Utxos generated from the initial distribution
aUtxo1, aUtxo2, aUtxo3, aUtxo4, bUtxo1, bUtxo2 :: (Api.TxOutRef, Api.TxOut)
Expand Down
49 changes: 25 additions & 24 deletions tests/Cooked/BalancingSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Ledger.Index qualified as Ledger
import ListT
import Optics.Core
import Plutus.Script.Utils.Ada qualified as Script
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V1.Value qualified as Api
import PlutusLedgerApi.V3 qualified as Api
import Test.Tasty
Expand All @@ -32,14 +33,14 @@ banana = permanentValue "banana"
initialDistributionBalancing :: InitialDistribution
initialDistributionBalancing =
InitialDistribution
[ paysPK alice (ada 2 <> apple 3),
paysPK alice (ada 25),
paysPK alice (ada 40 <> orange 6),
paysPK alice (ada 8),
paysPK alice (ada 30),
paysPK alice (lovelace 1280229 <> banana 3) `withDatum` (10 :: Integer),
paysPK alice (ada 1 <> banana 7) `withReferenceScript` (alwaysTrueValidator @MockContract),
paysPK alice (ada 105 <> banana 2) `withDatumHash` ()
[ paysPK alice (Script.ada 2 <> apple 3),
paysPK alice (Script.ada 25),
paysPK alice (Script.ada 40 <> orange 6),
paysPK alice (Script.ada 8),
paysPK alice (Script.ada 30),
paysPK alice (Script.lovelace 1280229 <> banana 3) `withDatum` (10 :: Integer),
paysPK alice (Script.ada 1 <> banana 7) `withReferenceScript` (alwaysTrueValidator @MockContract),
paysPK alice (Script.ada 105 <> banana 2) `withDatumHash` ()
]

type TestBalancingOutcome = (TxSkel, TxSkel, Integer, Set Api.TxOutRef, [Api.TxOutRef])
Expand Down Expand Up @@ -101,7 +102,7 @@ emptySearch = ListT.fromFoldable []
simplePaymentToBob :: (MonadBlockChain m) => Integer -> Integer -> Integer -> Integer -> (TxOpts -> TxOpts) -> m TestBalancingOutcome
simplePaymentToBob lv apples oranges bananas =
testingBalancingTemplate
(lovelace lv <> apple apples <> orange oranges <> banana bananas)
(Script.lovelace lv <> apple apples <> orange oranges <> banana bananas)
mempty
emptySearch
emptySearch
Expand All @@ -110,20 +111,20 @@ simplePaymentToBob lv apples oranges bananas =
bothPaymentsToBobAndAlice :: (MonadBlockChain m) => Integer -> (TxOpts -> TxOpts) -> m TestBalancingOutcome
bothPaymentsToBobAndAlice val =
testingBalancingTemplate
(lovelace val)
(lovelace val)
(Script.lovelace val)
(Script.lovelace val)
emptySearch
emptySearch
emptySearch

noBalanceMaxFee :: (MonadBlockChain m) => m ()
noBalanceMaxFee = do
maxFee <- snd <$> getMinAndMaxFee
((txOutRef, _) : _) <- runUtxoSearch $ utxosAtSearch alice `filterWithPred` ((== ada 30) . Api.txOutValue)
((txOutRef, _) : _) <- runUtxoSearch $ utxosAtSearch alice `filterWithPred` ((== Script.ada 30) . Api.txOutValue)
void $
validateTxSkel $
txSkelTemplate
{ txSkelOuts = [paysPK bob (lovelace (30_000_000 - maxFee))],
{ txSkelOuts = [paysPK bob (Script.lovelace (30_000_000 - maxFee))],
txSkelIns = Map.singleton txOutRef txSkelEmptyRedeemer,
txSkelOpts =
def
Expand All @@ -138,7 +139,7 @@ balanceReduceFee :: (MonadBlockChain m) => m (Integer, Integer, Integer, Integer
balanceReduceFee = do
let skelAutoFee =
txSkelTemplate
{ txSkelOuts = [paysPK bob (ada 50)],
{ txSkelOuts = [paysPK bob (Script.ada 50)],
txSkelSigners = [alice]
}
(skelBalanced, feeBalanced, cols, rColWal) <- balanceTxSkel skelAutoFee
Expand All @@ -160,7 +161,7 @@ reachingMagic = do
void $
validateTxSkel $
txSkelTemplate
{ txSkelOuts = [paysPK bob (ada 106 <> banana 12)],
{ txSkelOuts = [paysPK bob (Script.ada 106 <> banana 12)],
txSkelSigners = [alice],
txSkelOpts =
def
Expand Down Expand Up @@ -209,7 +210,7 @@ failsWithEmptyTxIns (MCEGenerationError (TxBodyError _ Cardano.TxBodyEmptyTxIns)
failsWithEmptyTxIns _ = testBool False

failsAtCollateralsWith :: (IsProp prop) => Integer -> MockChainError -> prop
failsAtCollateralsWith fee' (MCENoSuitableCollateral fee percentage val) = testBool $ fee == fee' && val == lovelace (1 + (fee * percentage) `div` 100)
failsAtCollateralsWith fee' (MCENoSuitableCollateral fee percentage val) = testBool $ fee == fee' && val == Script.lovelace (1 + (fee * percentage) `div` 100)
failsAtCollateralsWith _ _ = testBool False

failsAtCollaterals :: (IsProp prop) => MockChainError -> prop
Expand Down Expand Up @@ -241,19 +242,19 @@ tests =
testBalancingFailsWith
"Balancing does not occur when not requested, fails with too small inputs"
failsWithValueNotConserved
(testingBalancingTemplate (ada 50) mempty (aliceNAdaUtxos 8) emptySearch emptySearch (setCollateralWallet alice . setDontBalance . setFixedFee 1_000_000)),
(testingBalancingTemplate (Script.ada 50) mempty (aliceNAdaUtxos 8) emptySearch emptySearch (setCollateralWallet alice . setDontBalance . setFixedFee 1_000_000)),
testBalancingSucceedsWith
"It is still possible to balance the transaction by hand"
[hasFee 1_000_000, insNb 1, additionalOutsNb 0, colInsNb 1, retOutsNb 3]
(testingBalancingTemplate (ada 7) mempty (aliceNAdaUtxos 8) emptySearch emptySearch (setCollateralWallet alice . setDontBalance . setFixedFee 1_000_000)),
(testingBalancingTemplate (Script.ada 7) mempty (aliceNAdaUtxos 8) emptySearch emptySearch (setCollateralWallet alice . setDontBalance . setFixedFee 1_000_000)),
testBalancingFailsWith
"A collateral wallet needs to be provided when auto balancing is enabled"
failsLackOfCollateralWallet
(testingBalancingTemplate (ada 7) mempty (aliceNAdaUtxos 8) emptySearch emptySearch (setDontBalance . setFixedFee 1_000_000)),
(testingBalancingTemplate (Script.ada 7) mempty (aliceNAdaUtxos 8) emptySearch emptySearch (setDontBalance . setFixedFee 1_000_000)),
testBalancingSucceedsWith
"We can also directly give a set of collateral utxos"
[hasFee 1_000_000, insNb 1, additionalOutsNb 0, colInsNb 1, retOutsNb 3]
(testingBalancingTemplate (ada 7) mempty (aliceNAdaUtxos 8) emptySearch (aliceNAdaUtxos 8) (setDontBalance . setFixedFee 1_000_000))
(testingBalancingTemplate (Script.ada 7) mempty (aliceNAdaUtxos 8) emptySearch (aliceNAdaUtxos 8) (setDontBalance . setFixedFee 1_000_000))
],
testGroup
"Manual balancing with auto fee"
Expand All @@ -280,13 +281,13 @@ tests =
testSucceedsFrom
def
initialDistributionBalancing
(testingBalancingTemplate (ada 100) mempty emptySearch emptySearch (aliceNAdaUtxos 2) id),
(testingBalancingTemplate (Script.ada 100) mempty emptySearch emptySearch (aliceNAdaUtxos 2) id),
testCase "... but not always" $
testFailsFrom
def
failsAtCollaterals
initialDistributionBalancing
(testingBalancingTemplate (ada 100) mempty (utxosAtSearch alice) emptySearch (aliceNAdaUtxos 1) id),
(testingBalancingTemplate (Script.ada 100) mempty (utxosAtSearch alice) emptySearch (aliceNAdaUtxos 1) id),
testCase "Reaching magical spot with the exact balance during auto fee computation" $
testSucceedsFrom
def
Expand All @@ -309,7 +310,7 @@ tests =
(simplePaymentToBob 20_000_000 0 0 0 (setFixedFee 150_000)),
testBalancingFailsWith
"Fee are rightfully included in the balancing process, which fails when they are too high"
(failsAtBalancingWith (ada 1) alice)
(failsAtBalancingWith (Script.ada 1) alice)
(simplePaymentToBob 100_000_000 0 0 0 (setFixedFee 6_000_000)),
testBalancingFailsWith
"Collaterals are rightfully included in the balancing process, which fails when they are too high"
Expand Down Expand Up @@ -340,7 +341,7 @@ tests =
[hasFee 2_000_000, insNb 1, additionalOutsNb 1, colInsNb 1, retOutsNb 3]
(bothPaymentsToBobAndAlice 6_000_000 (setFixedFee 2_000_000 . setDontAdjustOutput)),
testBalancingSucceedsWith
"We can balance transactions with non-ada assets"
"We can balance transactions with non-Script.ada assets"
[hasFee 2_000_000, insNb 1, additionalOutsNb 1, colInsNb 1, retOutsNb 3]
(simplePaymentToBob 0 0 5 0 (setFixedFee 2_000_000 . setEnsureMinAda)),
testBalancingSucceedsWith
Expand Down
9 changes: 5 additions & 4 deletions tests/Cooked/BasicUsageSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Cooked
import Data.Default
import Data.Map qualified as Map
import Plutus.Script.Utils.Scripts qualified as Script
import Plutus.Script.Utils.Value qualified as Script
import PlutusLedgerApi.V3 qualified as Api
import Test.Tasty
import Test.Tasty.HUnit
Expand All @@ -19,7 +20,7 @@ pkToPk sender recipient amount =
void $
validateTxSkel $
txSkelTemplate
{ txSkelOuts = [paysPK recipient (ada amount)],
{ txSkelOuts = [paysPK recipient (Script.ada amount)],
txSkelSigners = [sender]
}

Expand All @@ -46,7 +47,7 @@ payToAlwaysTrueValidator =
head
<$> ( validateTxSkel' $
txSkelTemplate
{ txSkelOuts = [paysScript (alwaysTrueValidator @MockContract) () (ada 10)],
{ txSkelOuts = [paysScript (alwaysTrueValidator @MockContract) () (Script.ada 10)],
txSkelSigners = [alice]
}
)
Expand All @@ -58,7 +59,7 @@ consumeAlwaysTrueValidator = do
validateTxSkel $
txSkelTemplate
{ txSkelIns = Map.fromList [(outref, txSkelSomeRedeemer ())],
txSkelOuts = [paysPK alice (ada 10)],
txSkelOuts = [paysPK alice (Script.ada 10)],
txSkelSigners = [alice]
}

Expand All @@ -67,7 +68,7 @@ tests =
testGroup
"Basic usage"
[ testCase "Payment from alice to bob, with auto-balancing" $ testSucceedsFrom def def (pkToPk alice bob 10),
testCase "Circular payments of 10 ada between alice bob and carrie" $ testSucceedsFrom def def multiplePksToPks,
testCase "Circular payments of 10 Script.ada between alice bob and carrie" $ testSucceedsFrom def def multiplePksToPks,
testCase "Minting quick tokens" $ testSucceedsFrom def def mintingQuickValue,
testCase "Paying to the always true validator" $ testSucceedsFrom def def payToAlwaysTrueValidator,
testCase "Consuming the always true validator" $ testSucceedsFrom def def consumeAlwaysTrueValidator
Expand Down
Loading

0 comments on commit da69805

Please sign in to comment.