From 9d750e9a5f511f644b8ad2cdbf2b261425a5c939 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Mon, 19 Jun 2023 10:12:34 +0200 Subject: [PATCH 01/21] remove resourceT --- cabal.project | 2 +- dex-core/src/ErgoDex/Amm/Pool.hs | 95 +++++++++++-------- dex-core/src/ErgoDex/Amm/PoolActions.hs | 80 +++++----------- dex-core/src/ErgoDex/Amm/PoolSetup.hs | 1 + dex-core/test/Spec/Pool.hs | 29 +++--- ledger-sync/ledger-sync.cabal | 1 + .../EventSource/Persistence/LedgerHistory.hs | 92 ++++++++++++++---- .../src/Spectrum/EventSource/Stream.hs | 72 ++++++++------ ledger-sync/src/Spectrum/LedgerSync.hs | 21 ++-- .../Spectrum/LedgerSync/Data/LedgerUpdate.hs | 6 +- nix/pkgs/haskell/haskell.nix | 2 +- submit-api/src/SubmitAPI/Service.hs | 1 + submit-api/submit-api.cabal | 1 + wallet-api/src/WalletAPI/Utxos.hs | 2 +- 14 files changed, 228 insertions(+), 177 deletions(-) diff --git a/cabal.project b/cabal.project index a49ebb14..ef1d1ff6 100644 --- a/cabal.project +++ b/cabal.project @@ -313,7 +313,7 @@ source-repository-package source-repository-package type: git location: https://github.com/ergolabs/cardano-dex-contracts - tag: 2fb44f444897d84e313ceb4d3d467441385802dd + tag: 7850574a9b7f3e33cd7fc16f5fcdbbf0c8de68df subdir: cardano-dex-contracts-offchain diff --git a/dex-core/src/ErgoDex/Amm/Pool.hs b/dex-core/src/ErgoDex/Amm/Pool.hs index 0d4d2746..c7bce0d0 100644 --- a/dex-core/src/ErgoDex/Amm/Pool.hs +++ b/dex-core/src/ErgoDex/Amm/Pool.hs @@ -11,6 +11,7 @@ import Ledger import Ledger.Value (assetClassValue, assetClassValueOf) import PlutusTx.IsData.Class import PlutusTx.Sqrt +import Plutus.V1.Ledger.Api (StakingCredential(..)) import PlutusTx.Numeric (AdditiveMonoid(zero)) import Ledger.Ada (lovelaceValueOf) import Plutus.Script.Utils.V2.Address (mkValidatorAddress) @@ -42,42 +43,49 @@ data PoolFee = PoolFee } deriving (Show, Eq, Generic, FromJSON, ToJSON) data Pool = Pool - { poolId :: PoolId - , poolReservesX :: Amount X - , poolReservesY :: Amount Y - , poolLiquidity :: Amount Liquidity - , poolCoinX :: Coin X - , poolCoinY :: Coin Y - , poolCoinLq :: Coin Liquidity - , poolFee :: PoolFee - , outCollateral :: Amount Lovelace + { poolId :: PoolId + , poolReservesX :: Amount X + , poolReservesY :: Amount Y + , poolLiquidity :: Amount Liquidity + , poolCoinX :: Coin X + , poolCoinY :: Coin Y + , poolCoinLq :: Coin Liquidity + , poolFee :: PoolFee + , outCollateral :: Amount Lovelace + , stakeAdminPolicy :: [CurrencySymbol] + , lqBound :: Amount X + , stakeCred :: Maybe StakingCredential } deriving (Show, Eq, Generic, FromJSON, ToJSON) feeDen :: Integer feeDen = 1000 instance FromLedger Pool where - parseFromLedger fout@FullTxOut{fullTxOutDatum=(KnownDatum (Datum d)), ..} = --todo add also check for address + parseFromLedger fout@FullTxOut{fullTxOutDatum=(KnownDatum (Datum d)), fullTxOutAddress=Address{..}, ..} = --todo add also check for address case fromBuiltinData d of (Just PoolConfig{..}) -> do let - rx = Amount $ assetClassValueOf fullTxOutValue poolX - ry = Amount $ assetClassValueOf fullTxOutValue poolY - rlq = Amount $ assetClassValueOf fullTxOutValue poolLq - nft = Amount $ assetClassValueOf fullTxOutValue poolNft - lq = maxLqCapAmount - rlq -- actual LQ emission + rx = Amount $ assetClassValueOf fullTxOutValue poolX + ry = Amount $ assetClassValueOf fullTxOutValue poolY + rlq = Amount $ assetClassValueOf fullTxOutValue poolLq + nft = Amount $ assetClassValueOf fullTxOutValue poolNft + lqBoundAmount = Amount lqBound + lq = maxLqCapAmount - rlq -- actual LQ emission collateral = if W.isAda poolX || W.isAda poolY then zero else minSafeOutputAmount when (rx == 0 || ry == 0 || rlq == 0 || nft /= 1) Nothing Just $ OnChain fout Pool - { poolId = PoolId $ Coin poolNft - , poolReservesX = rx - , poolReservesY = ry - , poolLiquidity = lq - , poolCoinX = Coin poolX - , poolCoinY = Coin poolY - , poolCoinLq = Coin poolLq - , poolFee = PoolFee poolFeeNum feeDen - , outCollateral = collateral + { poolId = PoolId $ Coin poolNft + , poolReservesX = rx + , poolReservesY = ry + , poolLiquidity = lq + , poolCoinX = Coin poolX + , poolCoinY = Coin poolY + , poolCoinLq = Coin poolLq + , poolFee = PoolFee poolFeeNum feeDen + , outCollateral = collateral + , stakeAdminPolicy = stakeAdminPolicy + , lqBound = lqBoundAmount + , stakeCred = addressStakingCredential } _ -> Nothing parseFromLedger _ = Nothing @@ -85,12 +93,15 @@ instance FromLedger Pool where instance ToLedger PoolValidatorV1 Pool where toLedger (PoolValidator poolValidator) Pool{..} = TxOutCandidate - { txOutCandidateAddress = mkValidatorAddress poolValidator + { txOutCandidateAddress = poolAddress , txOutCandidateValue = poolValue , txOutCandidateDatum = KnownDatum $ Datum $ toBuiltinData poolConf , txOutCandidateRefScript = Nothing } where + poolAddress = (mkValidatorAddress poolValidator) { + addressStakingCredential = stakeCred + } nft = unPoolId poolId poolLqReserves = maxLqCapAmount - poolLiquidity poolValue = assetClassValue (unCoin nft) 1 <> @@ -100,11 +111,13 @@ instance ToLedger PoolValidatorV1 Pool where lovelaceValueOf (unAmount outCollateral) poolConf = PoolConfig - { poolNft = unCoin nft - , poolX = unCoin poolCoinX - , poolY = unCoin poolCoinY - , poolLq = unCoin poolCoinLq - , poolFeeNum = poolFeeNum' poolFee + { poolNft = unCoin nft + , poolX = unCoin poolCoinX + , poolY = unCoin poolCoinY + , poolLq = unCoin poolCoinLq + , poolFeeNum = poolFeeNum' poolFee + , stakeAdminPolicy = stakeAdminPolicy + , lqBound = unAmount lqBound } data PoolInitError @@ -112,6 +125,7 @@ data PoolInitError | InsufficientInitialLiqudity (Amount Liquidity) deriving (Show, Eq) +-- todo: remove me initPool :: PoolValidator V1 -> S.PoolConfig @@ -128,15 +142,18 @@ initPool poolValidator S.PoolConfig{..} burnLq (inX, inY) = do then zero else minSafeOutputAmount pool = Pool - { poolId = PoolId poolNft - , poolReservesX = inX - , poolReservesY = inY - , poolLiquidity = releasedLq - , poolCoinX = poolX - , poolCoinY = poolY - , poolCoinLq = poolLq - , poolFee = PoolFee poolFeeNum feeDen - , outCollateral = outCollateral + { poolId = PoolId poolNft + , poolReservesX = inX + , poolReservesY = inY + , poolLiquidity = releasedLq + , poolCoinX = poolX + , poolCoinY = poolY + , poolCoinLq = poolLq + , poolFee = PoolFee poolFeeNum feeDen + , stakeAdminPolicy = [] + , lqBound = 10000 + , outCollateral = outCollateral + , stakeCred = Nothing } poolOut = toLedger poolValidator pool pure (Predicted poolOut pool, releasedLq) diff --git a/dex-core/src/ErgoDex/Amm/PoolActions.hs b/dex-core/src/ErgoDex/Amm/PoolActions.hs index 3dd77d42..8e336b73 100644 --- a/dex-core/src/ErgoDex/Amm/PoolActions.hs +++ b/dex-core/src/ErgoDex/Amm/PoolActions.hs @@ -1,7 +1,6 @@ module ErgoDex.Amm.PoolActions ( PoolActions(..) , OrderExecErr(..) - , PoolActionsConfig(..) , mkPoolActions , AmmValidators(..) , fetchValidatorsV1 @@ -9,7 +8,6 @@ module ErgoDex.Amm.PoolActions import Control.Exception.Base import qualified Data.Set as Set -import Dhall (FromDhall) import Data.Bifunctor import Data.Tuple import RIO @@ -31,15 +29,12 @@ import qualified ErgoDex.Contracts.Proxy.Order as O import ErgoDex.Contracts.Types import CardanoTx.Models -data PoolActionsConfig = PoolActionsConfig - { safeTxFeeLovalace :: Integer - } deriving (Generic, FromDhall) - data OrderExecErr = PriceTooHigh | PoolMismatch PoolId PoolId | EmptyPool PoolId | PoolNotFoundInFinalTx PoolId + | InsufficientPoolLqForSwap PoolId deriving (Show) instance Exception OrderExecErr @@ -65,11 +60,11 @@ data PoolActions = PoolActions , runRedeem :: [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool) } -mkPoolActions :: PoolActionsConfig -> PaymentPubKeyHash -> AmmValidators V1 -> PoolActions -mkPoolActions cfg executorPkh AmmValidators{..} = PoolActions - { runSwap = runSwap' cfg executorPkh poolV swapV - , runDeposit = runDeposit' cfg executorPkh poolV depositV - , runRedeem = runRedeem' cfg executorPkh poolV redeemV +mkPoolActions :: PaymentPubKeyHash -> AmmValidators V1 -> PoolActions +mkPoolActions executorPkh AmmValidators{..} = PoolActions + { runSwap = runSwap' executorPkh poolV swapV + , runDeposit = runDeposit' executorPkh poolV depositV + , runRedeem = runRedeem' executorPkh poolV redeemV } newtype PoolIn = PoolIn FullTxOut @@ -93,15 +88,14 @@ mkOrderInputs action (PoolValidator pv) ov' (PoolIn poolOut) (OrderIn orderOut) in Set.fromList [poolIn, orderIn] runSwap' - :: PoolActionsConfig - -> PaymentPubKeyHash + :: PaymentPubKeyHash -> PoolValidator V1 -> SwapValidator V1 -> [FullTxOut] -> OnChain Swap -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool) -runSwap' PoolActionsConfig{..} executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do +runSwap' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do let inputs = mkOrderInputs P.Swap pv sv (PoolIn poolOut) (OrderIn swapOut) pp@(Predicted nextPoolOut _) = applySwap pv pool (AssetAmount swapBase swapBaseIn) @@ -109,6 +103,7 @@ runSwap' PoolActionsConfig{..} executorPkh pv sv refInputs (OnChain swapOut Swap when (swapPoolId /= poolId pool) (Left $ PoolMismatch swapPoolId (poolId pool)) when (getAmount quoteOutput < swapMinQuoteOut) (Left PriceTooHigh) + when (lqBound pool <= poolReservesX pool * 2) (Left $ InsufficientPoolLqForSwap (poolId pool)) let exFee = assetAmountRawValue quoteOutput * exFeePerTokenNum `div` exFeePerTokenDen @@ -128,23 +123,14 @@ runSwap' PoolActionsConfig{..} executorPkh pv sv refInputs (OnChain swapOut Swap <> Ada.lovelaceValueOf (negate exFee) -- Remove Batcher Fee rewardValue = assetAmountValue quoteOutput <> residualValue - - executorRewardPkh = pubKeyHashAddress executorPkh Nothing - exexutorRewardOut = - TxOutCandidate - { txOutCandidateAddress = executorRewardPkh - , txOutCandidateValue = Ada.lovelaceValueOf (exFee - safeTxFeeLovalace) - , txOutCandidateDatum = EmptyDatum - , txOutCandidateRefScript = Nothing - } txCandidate = TxCandidate { txCandidateInputs = inputs , txCandidateRefIns = refInputs - , txCandidateOutputs = [nextPoolOut, rewardOut, exexutorRewardOut] + , txCandidateOutputs = [nextPoolOut, rewardOut] , txCandidateValueMint = mempty , txCandidateMintInputs = mempty - , txCandidateChangePolicy = Just . ReturnTo $ rewardAddr + , txCandidateChangePolicy = Just $ ReturnTo $ pubKeyHashAddress executorPkh Nothing , txCandidateValidRange = Interval.always , txCandidateSigners = mempty } @@ -152,15 +138,14 @@ runSwap' PoolActionsConfig{..} executorPkh pv sv refInputs (OnChain swapOut Swap Right (txCandidate, pp) runDeposit' - :: PoolActionsConfig - -> PaymentPubKeyHash + :: PaymentPubKeyHash -> PoolValidator V1 -> DepositValidator V1 -> [FullTxOut] -> OnChain Deposit -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool) -runDeposit' PoolActionsConfig{..} executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOut, pool@Pool{..}) = do +runDeposit' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOut, pool@Pool{..}) = do when (depositPoolId /= poolId) (Left $ PoolMismatch depositPoolId poolId) let inputs = mkOrderInputs P.Deposit pv dv (PoolIn poolOut) (OrderIn depositOut) @@ -206,22 +191,13 @@ runDeposit' PoolActionsConfig{..} executorPkh pv dv refInputs (OnChain depositOu <> Ada.lovelaceValueOf (negate $ unAmount exFee) -- Remove Fee rewardValue = residualValue <> mintLqValue <> alignmentValue - executorRewardPkh = pubKeyHashAddress executorPkh Nothing - exexutorRewardOut = - TxOutCandidate - { txOutCandidateAddress = executorRewardPkh - , txOutCandidateValue = Ada.lovelaceValueOf $ (unAmount exFee - safeTxFeeLovalace) - , txOutCandidateDatum = EmptyDatum - , txOutCandidateRefScript = Nothing - } - txCandidate = TxCandidate { txCandidateInputs = inputs , txCandidateRefIns = refInputs - , txCandidateOutputs = [nextPoolOut, rewardOut, exexutorRewardOut] + , txCandidateOutputs = [nextPoolOut, rewardOut] , txCandidateValueMint = mempty , txCandidateMintInputs = mempty - , txCandidateChangePolicy = Just . ReturnTo $ rewardAddr + , txCandidateChangePolicy = Just $ ReturnTo $ pubKeyHashAddress executorPkh Nothing , txCandidateValidRange = Interval.always , txCandidateSigners = mempty } @@ -229,15 +205,14 @@ runDeposit' PoolActionsConfig{..} executorPkh pv dv refInputs (OnChain depositOu Right (txCandidate, pp) runRedeem' - :: PoolActionsConfig - -> PaymentPubKeyHash + :: PaymentPubKeyHash -> PoolValidator V1 -> RedeemValidator V1 -> [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool) -runRedeem' PoolActionsConfig{..} executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, pool@Pool{..}) = do +runRedeem' executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, pool@Pool{..}) = do when (redeemPoolId /= poolId) (Left $ PoolMismatch redeemPoolId poolId) let inputs = mkOrderInputs P.Redeem pv rv (PoolIn poolOut) (OrderIn redeemOut) @@ -245,7 +220,7 @@ runRedeem' PoolActionsConfig{..} executorPkh pv rv refInputs (OnChain redeemOut pp@(Predicted nextPoolOut _) = applyRedeem pv pool redeemLqIn burnLqValue = assetClassValue (unCoin redeemLq) (negate $ unAmount redeemLqIn) - + exFee = unAmount $ unExFee redeemExFee rewardAddr = pubKeyHashAddress (PaymentPubKeyHash redeemRewardPkh) redeemRewardSPkh @@ -260,29 +235,20 @@ runRedeem' PoolActionsConfig{..} executorPkh pv rv refInputs (OnChain redeemOut (outX, outY) = sharesAmount pool redeemLqIn initValue = fullTxOutValue redeemOut negatedExFe = Ada.lovelaceValueOf . negate $ exFee - residualValue = - initValue - <> burnLqValue + residualValue = + initValue + <> burnLqValue <> negatedExFe -- Remove LQ input and ExFee rewardValue = assetAmountValue outX <> assetAmountValue outY <> residualValue - - executorRewardPkh = pubKeyHashAddress executorPkh Nothing - exexutorRewardOut = - TxOutCandidate - { txOutCandidateAddress = executorRewardPkh - , txOutCandidateValue = Ada.lovelaceValueOf (exFee - safeTxFeeLovalace) - , txOutCandidateDatum = EmptyDatum - , txOutCandidateRefScript = Nothing - } txCandidate = TxCandidate { txCandidateInputs = inputs , txCandidateRefIns = refInputs - , txCandidateOutputs = [nextPoolOut, rewardOut, exexutorRewardOut] + , txCandidateOutputs = [nextPoolOut, rewardOut] , txCandidateValueMint = mempty , txCandidateMintInputs = mempty - , txCandidateChangePolicy = Just . ReturnTo $ rewardAddr + , txCandidateChangePolicy = Just $ ReturnTo $ pubKeyHashAddress executorPkh Nothing , txCandidateValidRange = Interval.always , txCandidateSigners = mempty } diff --git a/dex-core/src/ErgoDex/Amm/PoolSetup.hs b/dex-core/src/ErgoDex/Amm/PoolSetup.hs index ea0d8f43..8d7ca8ca 100644 --- a/dex-core/src/ErgoDex/Amm/PoolSetup.hs +++ b/dex-core/src/ErgoDex/Amm/PoolSetup.hs @@ -44,6 +44,7 @@ mkPoolSetup pv changeAddr = PoolSetup { poolDeploy = poolDeploy' pv burnLqInitial changeAddr } +-- todo: remove me poolDeploy' :: PoolValidatorV1 -> Amount Liquidity diff --git a/dex-core/test/Spec/Pool.hs b/dex-core/test/Spec/Pool.hs index a85002c8..be4592f5 100644 --- a/dex-core/test/Spec/Pool.hs +++ b/dex-core/test/Spec/Pool.hs @@ -80,7 +80,7 @@ initialLiquidityTests = testGroup "InitialLiquidity" initialLiquidityAmount poolLq (Amount 10, Amount 11) @?= Right (AssetAmount poolLq 11) ] -poolConf = S.PoolConfig poolNft poolX poolY poolLq poolFeeNum +poolConf = S.PoolConfig poolNft poolX poolY poolLq poolFeeNum [] 0 sufficientInitDepositX = Amount 800 @@ -91,20 +91,25 @@ initDepositY = Amount 2000 releasedLq = Amount 265 nativePool = Pool - { poolId = PoolId poolNft - , poolReservesX = sufficientInitDepositX - , poolReservesY = initDepositY - , poolLiquidity = releasedLq - , poolCoinX = poolX - , poolCoinY = poolY - , poolCoinLq = poolLq - , poolFee = PoolFee poolFeeNum feeDen - , outCollateral = minSafeOutputAmount + { poolId = PoolId poolNft + , poolReservesX = sufficientInitDepositX + , poolReservesY = initDepositY + , poolLiquidity = releasedLq + , poolCoinX = poolX + , poolCoinY = poolY + , poolCoinLq = poolLq + , poolFee = PoolFee poolFeeNum feeDen + , outCollateral = minSafeOutputAmount + , stakeAdminPolicy = [] + , lqBound = Amount 0 + , stakeCred = Nothing } +-- todo: remove me initPoolTests = testGroup "NonNativePoolInit" - [ HH.testProperty "init_non_native_pool_sufficient_liquidity" initNonNativePoolSufficientLiquidity - , HH.testProperty "init_non_native_pool_insufficient_liquidity" initNonNativePoolInsufficientLiquidity + [ + -- HH.testProperty "init_non_native_pool_sufficient_liquidity" initNonNativePoolSufficientLiquidity + -- , HH.testProperty "init_non_native_pool_insufficient_liquidity" initNonNativePoolInsufficientLiquidity ] initNonNativePoolInsufficientLiquidity :: Property diff --git a/ledger-sync/ledger-sync.cabal b/ledger-sync/ledger-sync.cabal index 7ffa302b..b053219a 100755 --- a/ledger-sync/ledger-sync.cabal +++ b/ledger-sync/ledger-sync.cabal @@ -164,3 +164,4 @@ library , dependent-sum-template >= 0.1 && < 0.2 , dependent-map >= 0.3 && < 0.5 , aeson-gadt-th + , strict-containers diff --git a/ledger-sync/src/Spectrum/EventSource/Persistence/LedgerHistory.hs b/ledger-sync/src/Spectrum/EventSource/Persistence/LedgerHistory.hs index d14ef9ec..9e3b996b 100755 --- a/ledger-sync/src/Spectrum/EventSource/Persistence/LedgerHistory.hs +++ b/ledger-sync/src/Spectrum/EventSource/Persistence/LedgerHistory.hs @@ -2,6 +2,7 @@ module Spectrum.EventSource.Persistence.LedgerHistory ( LedgerHistory(..) , mkLedgerHistory , mkRuntimeLedgerHistory + , TestStack(..) ) where import RIO @@ -10,6 +11,7 @@ import RIO , newIORef , readIORef , writeIORef + , atomicModifyIORef' , (<&>) , isJust ) @@ -34,6 +36,42 @@ import Spectrum.EventSource.Persistence.Config ( LedgerStoreConfig (..) ) import Spectrum.Common.Persistence.Serialization (serialize, deserializeM) import Control.Monad.Catch (MonadThrow) +import Data.List (uncons) +import GHC.IORef (IORef(IORef)) +import Data.Foldable (find) + +data TestStack m k = TestStack + { push :: k -> m () + , pop :: m (Maybe k) + , readFirst :: m (Maybe k) + , exists :: k -> m Bool + } + +mkTestStack :: (MonadIO f, MonadIO m, Eq k) => f (TestStack m k) +mkTestStack = do + listRef <- newIORef [] + let size = 100 + return TestStack + { push = \elem -> do + atomicModifyIORef' listRef (\listStack -> + if length listStack > size + then + let + (newStack, _) = splitAt (size `div` 2) listStack + in (elem : newStack, ()) + else (elem : listStack, ()) + ) + , pop = + atomicModifyIORef' listRef (\listStack -> + case uncons listStack of + Nothing -> ([], Nothing) + Just (element, newStack) -> (newStack, Just element) + ) + , readFirst = readIORef listRef <&> (\list -> uncons list <&> fst) + , exists = \key -> do + list <- readIORef listRef + pure $ elem key list + } data LedgerHistory m = LedgerHistory { setTip :: ConcretePoint -> m () @@ -73,34 +111,50 @@ mkLedgerHistory MakeLogging{..} LedgerStoreConfig{..} = do } -- | Runtime-only storage primarily for tests. -mkRuntimeLedgerHistory :: (MonadIO m, MonadThrow m) => MakeLogging m m -> m (LedgerHistory m) -mkRuntimeLedgerHistory MakeLogging{..} = do +mkRuntimeLedgerHistory :: (MonadIO m, MonadThrow m) => m (LedgerHistory m) +mkRuntimeLedgerHistory = do + tipsStack <- mkTestStack + blockStorage <- newIORef [] store <- newIORef mempty - logging <- forComponent "LedgerHistory" - pure $ attachLogging logging LedgerHistory + --logging <- forComponent "LedgerHistory" + pure $ LedgerHistory { setTip = \p -> do - s <- readIORef store - writeIORef store $ Map.insert lastPointKey (serialize p) s + push tipsStack p + -- s <- readIORef store + -- writeIORef store $ Map.insert lastPointKey (serialize p) s , getTip = do - s <- readIORef store - mapM deserializeM $ Map.lookup lastPointKey s + pop tipsStack + -- s <- readIORef store + -- mapM deserializeM $ Map.lookup lastPointKey s , putBlock = \point blk -> do - s <- readIORef store - writeIORef store $ Map.insert (serialize point) (serialize blk) s + atomicModifyIORef' blockStorage (\blockList -> + if length blockList > 100 + then + let + (newStorage, _) = splitAt (100 `div` 2) blockList + in ((point, blk) : newStorage, ()) + else ((point, blk) : blockList, ()) + ) + -- push blocksStack (point, blk) + -- s <- readIORef store + -- writeIORef store $ Map.insert (serialize point) (serialize blk) s , getBlock = \point -> do - s <- readIORef store - mapM deserializeM $ Map.lookup (serialize point) s + s <- readIORef blockStorage + pure $ find (\(testP, _) -> point == testP) s <&> snd , pointExists = \point -> do s <- readIORef store pure $ Map.member (serialize point) s , dropBlock = \point -> do - s <- readIORef store - let - pkey = serialize point - exists = Map.member pkey s - if exists - then writeIORef store (Map.delete pkey s) $> True - else pure False + atomicModifyIORef' blockStorage (\blockList -> + (filter (\(testP, _) -> testP /= point) blockList, ()) + ) >> pure True + -- s <- readIORef store + -- let + -- pkey = serialize point + -- exists = Map.member pkey s + -- if exists + -- then writeIORef store (Map.delete pkey s) $> True + -- else pure False } attachLogging :: Monad m => Logging m -> LedgerHistory m -> LedgerHistory m diff --git a/ledger-sync/src/Spectrum/EventSource/Stream.hs b/ledger-sync/src/Spectrum/EventSource/Stream.hs index 5346b4c1..2b8b0cc3 100755 --- a/ledger-sync/src/Spectrum/EventSource/Stream.hs +++ b/ledger-sync/src/Spectrum/EventSource/Stream.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE RecordWildCards #-} module Spectrum.EventSource.Stream ( EventSource(..) , mkLedgerEventSource @@ -10,16 +12,18 @@ import RIO import Data.ByteString.Short ( toShort ) -import Control.Monad.Trans.Control - ( MonadBaseControl ) +import Ledger + ( TxId ) + +import qualified Data.Foldable as Foldable + import Control.Monad.IO.Class ( MonadIO ) import Control.Monad.Catch ( MonadThrow ) import Control.Monad ( join ) -import Control.Monad.Trans.Resource - ( MonadResource ) +import Data.Sequence.Strict import Streamly.Prelude as S @@ -36,10 +40,13 @@ import Ouroboros.Consensus.Cardano.Block import Ouroboros.Consensus.Block ( Point ) +import Spectrum.EventSource.Data.Tx (MinimalTx(..), MinimalConfirmedTx (..)) + import Cardano.Ledger.Alonzo.TxSeq ( TxSeq(txSeqTxns) ) import qualified Cardano.Ledger.Block as Ledger import qualified Cardano.Crypto.Hash as CC +import Data.List import Spectrum.LedgerSync.Protocol.Client ( Block ) @@ -59,7 +66,7 @@ import Spectrum.EventSource.Types , ConcreteHash (ConcreteHash) ) import Spectrum.EventSource.Persistence.LedgerHistory - ( LedgerHistory (..), mkLedgerHistory ) + ( LedgerHistory (..), mkLedgerHistory, mkRuntimeLedgerHistory ) import Spectrum.EventSource.Data.TxEvent ( TxEvent(AppliedTx, UnappliedTx, PendingTx) ) import Spectrum.EventSource.Data.TxContext @@ -73,7 +80,8 @@ import Spectrum.LedgerSync.Data.MempoolUpdate import Spectrum.EventSource.Persistence.Config ( LedgerStoreConfig ) import Spectrum.Prelude.HigherKind - ( LiftK (liftK) ) + ( LiftK (liftK), type (~>) ) +import qualified Streamly.Internal.Data.Stream.IsStream as S newtype EventSource s m ctx = EventSource { upstream :: s m (TxEvent ctx) @@ -82,7 +90,8 @@ newtype EventSource s m ctx = EventSource mkLedgerEventSource :: forall f m s env. ( Monad f - , MonadResource f + , MonadIO f + , MonadThrow f , LiftK m f , IsStream s , Monad (s m) @@ -93,14 +102,15 @@ mkLedgerEventSource , HasType LedgerStoreConfig env ) => LedgerSync m + -> m ~> f -> f (EventSource s m 'LedgerCtx) -mkLedgerEventSource lsync = do - mklog@MakeLogging{..} <- askContext +mkLedgerEventSource lsync fToM = do + MakeLogging{..} <- askContext :: f (MakeLogging f m) EventSourceConfig{startAt} <- askContext - lhcong <- askContext + -- lhcong <- askContext logging <- forComponent "LedgerEventSource" - persistence <- mkLedgerHistory mklog lhcong + persistence <- fToM mkRuntimeLedgerHistory liftK $ seekToBeginning logging persistence lsync startAt pure $ EventSource @@ -110,7 +120,6 @@ mkLedgerEventSource lsync = do mkMempoolTxEventSource :: forall f m s env. ( Monad f - , MonadResource f , IsStream s , Monad (s m) , MonadAsync m @@ -151,7 +160,6 @@ processUpdate ( IsStream s , Monad (s m) , MonadIO m - , MonadBaseControl IO m , MonadThrow m ) => Logging m @@ -161,37 +169,35 @@ processUpdate processUpdate _ LedgerHistory{..} - (RollForward (BlockBabbage (ShelleyBlock (Ledger.Block (Praos.Header hBody _) txs) hHash))) = + (RollForward block@(BlockBabbage (ShelleyBlock (Ledger.Block (Praos.Header hBody _) txs) hHash)) _) = let txs' = txSeqTxns txs slotNo = Praos.hbSlotNo hBody point = ConcretePoint slotNo (ConcreteHash ch) where ch = OneEraHash . toShort . CC.hashToBytes . unShelleyHash $ hHash - in S.before (setTip point) - $ S.fromFoldable txs' & S.map (AppliedTx . fromBabbageLedgerTx hHash slotNo) + txsParsed = txs' <&> fromBabbageLedgerTx hHash slotNo + txsIds = Foldable.toList (txsParsed <&> (\(MinimalLedgerTx MinimalConfirmedTx{..}) -> txId)) :: [TxId] + parsedTxs = txsParsed <&> AppliedTx + in S.before (setTip point >> putBlock point (BlockLinks point txsIds)) $ S.fromFoldable parsedTxs processUpdate logging lh (RollBackward point) = streamUnappliedTxs logging lh point -processUpdate Logging{..} _ upd = S.before (errorM $ "Cannot process update " <> show upd) mempty +processUpdate Logging{..} _ upd = S.before (errorM $ "Cannot process update " <> show upd) (S.fromList []) processMempoolUpdate :: forall s m. ( IsStream s , MonadIO m - , MonadBaseControl IO m - , MonadThrow m ) => Logging m -> MempoolUpdate Block -> s m (TxEvent 'MempoolCtx) processMempoolUpdate _ (NewTx (GenTxBabbage (ShelleyTx _ x)) slot) = S.fromList [PendingTx $ fromMempoolBabbageLedgerTx x slot] -processMempoolUpdate Logging{..} _ = S.before (errorM @String "Cannot process mempool update") mempty +processMempoolUpdate Logging{..} _ = S.before (errorM @String "Cannot process mempool update") $ S.fromList [] streamUnappliedTxs :: forall s m. ( IsStream s , Monad (s m) , MonadIO m - , MonadBaseControl IO m - , MonadThrow m ) => Logging m -> LedgerHistory m @@ -209,15 +215,19 @@ streamUnappliedTxs Logging{..} LedgerHistory{..} point = join $ S.fromEffect $ d let emitTxs = S.fromFoldable (Prelude.reverse txIds <&> UnappliedTx) -- unapply txs in reverse order if toPoint prevPoint == point then emitTxs - else emitTxs <> rollbackOne prevPoint - Nothing -> mempty - tipM <- getTip - case tipM of - Just tip -> - if knownPoint - then infoM ("Rolling back to point " <> show point) $> rollbackOne tip - else errorM ("An attempt to roll back to an unknown point " <> show point) $> mempty - Nothing -> pure mempty + else S.append emitTxs (rollbackOne prevPoint) + Nothing -> S.fromList [] + if knownPoint + then do + tipM <- getTip + case tipM of + Just tip -> infoM ("Rolling back to point " <> show point) $> rollbackOne tip + Nothing -> errorM ("An attempt to roll back to an unknown point. (Empty tipM) " <> show point) $> S.fromList [] + else errorM ("An attempt to roll back to an unknown point " <> show point) $> S.fromList [] + -- tipM <- getTip + -- case tipM of + -- Just tip -> + -- Nothing -> pure mempty seekToBeginning :: Monad m diff --git a/ledger-sync/src/Spectrum/LedgerSync.hs b/ledger-sync/src/Spectrum/LedgerSync.hs index 5fa8fd05..fa49b59b 100755 --- a/ledger-sync/src/Spectrum/LedgerSync.hs +++ b/ledger-sync/src/Spectrum/LedgerSync.hs @@ -36,12 +36,12 @@ import Spectrum.LedgerSync.Data.LedgerUpdate import qualified Spectrum.LedgerSync.Data.LedgerUpdate as Update import qualified Spectrum.LedgerSync.Data.MempoolUpdate as MempoolUpdate import Spectrum.LedgerSync.Protocol.Data.ChainSync - ( RequestNextResponse(RollBackward, RollForward, block, point), + ( RequestNextResponse(RollBackward, RollForward, block, point, tip), RequestNext(RequestNext), ChainSyncResponse(RequestNextRes, FindIntersectRes), ChainSyncRequest(RequestNextReq, FindIntersectReq), FindIntersect(FindIntersect), - FindIntersectResponse (IntersectionFound) ) + FindIntersectResponse (IntersectionFound)) import Ouroboros.Consensus.Block ( StandardHash ) @@ -55,8 +55,7 @@ import Ouroboros.Consensus.Cardano.Block ( GenTx ) import Spectrum.LedgerSync.Config - ( NetworkParameters(NetworkParameters, slotsPerEpoch, networkMagic), - NodeSocketConfig(..) ) + ( NetworkParameters(NetworkParameters, slotsPerEpoch, networkMagic), NodeSocketConfig(..)) import Spectrum.LedgerSync.Exception ( ChainSyncInitFailed(ChainSyncInitFailed) ) import Spectrum.LedgerSync.Protocol.ChainSync @@ -93,18 +92,14 @@ mkLedgerSync , MonadMask m , MonadST m , MonadIO m - , MonadReader env m - , HasType NodeSocketConfig env - , HasType NetworkParameters env - , HasType (MakeLogging m m) env ) => UnliftIO m -> Tracer m TraceClient + -> MakeLogging m m + -> NodeSocketConfig + -> NetworkParameters -> m (LedgerSync m) -mkLedgerSync unliftIO tr = do - MakeLogging{..} <- askContext - NodeSocketConfig{nodeSocketPath, maxInFlight} <- askContext - NetworkParameters{slotsPerEpoch,networkMagic} <- askContext +mkLedgerSync unliftIO tr MakeLogging{..} NodeSocketConfig{..} NetworkParameters{..} = do l@Logging{..} <- forComponent "LedgerSync" (outQ, inQ) <- atomically $ (,) <$> newTQueue <*> newTQueue @@ -173,7 +168,7 @@ tryPull' outQ inQ = do atomically $ tryReadTQueue inQ <&> (<&> extractUpdate) extractUpdate :: ChainSyncResponse block -> LedgerUpdate block -extractUpdate (RequestNextRes RollForward{block}) = Update.RollForward block +extractUpdate (RequestNextRes RollForward{block, tip}) = Update.RollForward block tip extractUpdate (RequestNextRes RollBackward{point}) = Update.RollBackward point extractUpdate _ = undefined diff --git a/ledger-sync/src/Spectrum/LedgerSync/Data/LedgerUpdate.hs b/ledger-sync/src/Spectrum/LedgerSync/Data/LedgerUpdate.hs index 5b00a885..55633154 100755 --- a/ledger-sync/src/Spectrum/LedgerSync/Data/LedgerUpdate.hs +++ b/ledger-sync/src/Spectrum/LedgerSync/Data/LedgerUpdate.hs @@ -1,9 +1,9 @@ module Spectrum.LedgerSync.Data.LedgerUpdate where -import Ouroboros.Consensus.Block - ( Point ) +import Ouroboros.Network.Block + ( Point (..), Tip (..) ) data LedgerUpdate block - = RollForward block + = RollForward block (Tip block) | RollBackward (Point block) deriving (Eq, Show) diff --git a/nix/pkgs/haskell/haskell.nix b/nix/pkgs/haskell/haskell.nix index 8724a2dd..e5424271 100644 --- a/nix/pkgs/haskell/haskell.nix +++ b/nix/pkgs/haskell/haskell.nix @@ -43,7 +43,7 @@ let "https://github.com/input-output-hk/cardano-ledger"."c7c63dabdb215ebdaed8b63274965966f2bf408f" = "zTQbMOGPD1Oodv6VUsfF6NUiXkbN8SWI98W3Atv4wbI="; "https://github.com/input-output-hk/plutus-apps"."593ffafa59dd30ad28cfaf144c526c66328595d2" = "CIuI/Nz7O67ljOHDg7UBbXgWuIE7VPRdPX4VK0/DI3A="; "https://github.com/input-output-hk/hedgehog-extras"."714ee03a5a786a05fc57ac5d2f1c2edce4660d85" = "6KQFEzb9g2a0soVvwLKESEbA+a8ygpROcMr6bkatROE="; - "https://github.com/ergolabs/cardano-dex-contracts"."2fb44f444897d84e313ceb4d3d467441385802dd" = "Kih0IS6Ty3EnXlgqAyF04nWIWJAnHOEVfraebh5RsNI="; + "https://github.com/ergolabs/cardano-dex-contracts"."7850574a9b7f3e33cd7fc16f5fcdbbf0c8de68df" = "1jzh8o3SdkZflVLLglT45iCcmgDSAg6b1P7fTwwmgPM="; "https://github.com/ergolabs/hlog"."19dfa3a6e696a3f63fc3539cd6b7a3fc4d999853" = "Lvmj1oLuXmktrboXh/BrXqLPf8FxSCXIf99GnBXu0Bk="; "https://github.com/daleiz/rocksdb-haskell"."109af08f95b40f458d4933e3725ecb3e59337c39" = "1i1ya491fapa0g96527krarv0w0iybizqcz518741iw06hhpikiy"; }; diff --git a/submit-api/src/SubmitAPI/Service.hs b/submit-api/src/SubmitAPI/Service.hs index 4db0c728..513febad 100644 --- a/submit-api/src/SubmitAPI/Service.hs +++ b/submit-api/src/SubmitAPI/Service.hs @@ -19,6 +19,7 @@ import qualified NetworkAPI.Service as Network import NetworkAPI.Types import WalletAPI.Utxos import WalletAPI.Vault +import Cardano.Crypto.DSIGN.SchnorrSecp256k1 data Transactions f era = Transactions { estimateTxFee :: Set.Set Sdk.FullCollateralTxIn -> Sdk.TxCandidate -> f C.Lovelace diff --git a/submit-api/submit-api.cabal b/submit-api/submit-api.cabal index e2555f14..feaf36ec 100644 --- a/submit-api/submit-api.cabal +++ b/submit-api/submit-api.cabal @@ -111,6 +111,7 @@ library cardano-ledger-shelley, cardano-ledger-core, cardano-ledger-shelley-ma, + cardano-crypto-class, cardano-ledger-byron, cardano-ledger-babbage, ouroboros-consensus, diff --git a/wallet-api/src/WalletAPI/Utxos.hs b/wallet-api/src/WalletAPI/Utxos.hs index 3d5f9211..531600ee 100644 --- a/wallet-api/src/WalletAPI/Utxos.hs +++ b/wallet-api/src/WalletAPI/Utxos.hs @@ -93,7 +93,7 @@ selectUtxos'' logging explorer ustore@UtxoStore{..} pkh strict requiredValue = d let entriesLeft = Explorer.total utxoBatch - (offset + limit) if entriesLeft > 0 - then fetchUtxos (offset + limit) limit + then pure () -- fetchUtxos (offset + limit) limit else pure () extractAssets v = Set.fromList (flattenValue v <&> (\(cs, tn, _) -> (cs, tn))) From 0cdf6ab45d3b2d12c6aec51af667c0bfcc085358 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Thu, 20 Jul 2023 21:08:34 +0200 Subject: [PATCH 02/21] fix pool parsing --- dex-core/src/ErgoDex/ScriptsValidators.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dex-core/src/ErgoDex/ScriptsValidators.hs b/dex-core/src/ErgoDex/ScriptsValidators.hs index d1459004..f56e012a 100644 --- a/dex-core/src/ErgoDex/ScriptsValidators.hs +++ b/dex-core/src/ErgoDex/ScriptsValidators.hs @@ -41,7 +41,7 @@ parsePool Logging{..} ScriptsValidators{poolValidator} out@FullTxOut{..} = do let pool = parseFromLedger out :: Maybe (OnChain Pool) poolAddress = mkValidatorAddress poolValidator - if fullTxOutAddress == poolAddress + if (PV2.addressCredential fullTxOutAddress) == (PV2.addressCredential poolAddress) then case pool of Just a -> do infoM ("Pool found in: " ++ show out) From 48a7ab076823062b7159dfe411a2c054187bc82b Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Thu, 20 Jul 2023 21:29:00 +0200 Subject: [PATCH 03/21] add debug --- dex-core/src/ErgoDex/ScriptsValidators.hs | 4 ++-- submit-api/test/Main.hs | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/dex-core/src/ErgoDex/ScriptsValidators.hs b/dex-core/src/ErgoDex/ScriptsValidators.hs index f56e012a..21d2bbbe 100644 --- a/dex-core/src/ErgoDex/ScriptsValidators.hs +++ b/dex-core/src/ErgoDex/ScriptsValidators.hs @@ -44,12 +44,12 @@ parsePool Logging{..} ScriptsValidators{poolValidator} out@FullTxOut{..} = do if (PV2.addressCredential fullTxOutAddress) == (PV2.addressCredential poolAddress) then case pool of Just a -> do - infoM ("Pool found in: " ++ show out) + infoM ("Pool found in: " ++ show out ++ ". Out address:" ++ show fullTxOutAddress ++ ". pool address: " ++ show poolAddress) pure $ Just $ Confirmed out a _ -> do infoM ("Pool not found in: " ++ show out) pure Nothing - else pure Nothing + else infoM ("Pool not found in: " ++ show out ++ ". Out address:" ++ show fullTxOutAddress ++ ". pool address: " ++ show poolAddress) >> pure Nothing mkScriptsValidators :: (MonadIO m) => ScriptsConfig -> m ScriptsValidators mkScriptsValidators ScriptsConfig{..} = do diff --git a/submit-api/test/Main.hs b/submit-api/test/Main.hs index 3b4b316c..5dbca7e0 100644 --- a/submit-api/test/Main.hs +++ b/submit-api/test/Main.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE OverloadedStrings #-} + module Main where import qualified Data.Text.Encoding as E @@ -8,9 +10,13 @@ import Test.Tasty.HUnit import Spec.Transaction import System.Exit (exitFailure) import Control.Monad (unless) +import CardanoTx.Address main :: IO () -main = defaultMain tests +main = do + print $ show $ readShellyAddress "addr1x9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evkqwx9ghwy6quk2fhu5g0ek8rth7z4zxr5ev975ph34q5fsq2amyd" + print $ show $ readShellyAddress "addr1w9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evsg37dfw" + --defaultMain tests tests = testGroup "SubmitApi" [ buildTxBodyTests From c7d67ab6ae50ef2ec9b6e0542a9831e4b536ab5b Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Thu, 20 Jul 2023 21:48:32 +0200 Subject: [PATCH 04/21] fix swap op operation --- dex-core/src/ErgoDex/Amm/PoolActions.hs | 2 +- dex-core/src/ErgoDex/ScriptsValidators.hs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dex-core/src/ErgoDex/Amm/PoolActions.hs b/dex-core/src/ErgoDex/Amm/PoolActions.hs index 8e336b73..ab38e496 100644 --- a/dex-core/src/ErgoDex/Amm/PoolActions.hs +++ b/dex-core/src/ErgoDex/Amm/PoolActions.hs @@ -103,7 +103,7 @@ runSwap' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFeePerTok when (swapPoolId /= poolId pool) (Left $ PoolMismatch swapPoolId (poolId pool)) when (getAmount quoteOutput < swapMinQuoteOut) (Left PriceTooHigh) - when (lqBound pool <= poolReservesX pool * 2) (Left $ InsufficientPoolLqForSwap (poolId pool)) + when (poolReservesX pool * 2 <= lqBound pool) (Left $ InsufficientPoolLqForSwap (poolId pool)) let exFee = assetAmountRawValue quoteOutput * exFeePerTokenNum `div` exFeePerTokenDen diff --git a/dex-core/src/ErgoDex/ScriptsValidators.hs b/dex-core/src/ErgoDex/ScriptsValidators.hs index 21d2bbbe..f56e012a 100644 --- a/dex-core/src/ErgoDex/ScriptsValidators.hs +++ b/dex-core/src/ErgoDex/ScriptsValidators.hs @@ -44,12 +44,12 @@ parsePool Logging{..} ScriptsValidators{poolValidator} out@FullTxOut{..} = do if (PV2.addressCredential fullTxOutAddress) == (PV2.addressCredential poolAddress) then case pool of Just a -> do - infoM ("Pool found in: " ++ show out ++ ". Out address:" ++ show fullTxOutAddress ++ ". pool address: " ++ show poolAddress) + infoM ("Pool found in: " ++ show out) pure $ Just $ Confirmed out a _ -> do infoM ("Pool not found in: " ++ show out) pure Nothing - else infoM ("Pool not found in: " ++ show out ++ ". Out address:" ++ show fullTxOutAddress ++ ". pool address: " ++ show poolAddress) >> pure Nothing + else pure Nothing mkScriptsValidators :: (MonadIO m) => ScriptsConfig -> m ScriptsValidators mkScriptsValidators ScriptsConfig{..} = do From 5efbb44fc0d5f1a30da1071482de629b5a3dabcf Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 23 Jul 2023 17:09:09 +0200 Subject: [PATCH 05/21] update pool uplc --- cabal.project | 2 +- nix/pkgs/haskell/haskell.nix | 2 +- submit-api/test/Main.hs | 355 +++++++++++++++++++++++++++++++++-- 3 files changed, 343 insertions(+), 16 deletions(-) diff --git a/cabal.project b/cabal.project index ef1d1ff6..ff6f7669 100644 --- a/cabal.project +++ b/cabal.project @@ -313,7 +313,7 @@ source-repository-package source-repository-package type: git location: https://github.com/ergolabs/cardano-dex-contracts - tag: 7850574a9b7f3e33cd7fc16f5fcdbbf0c8de68df + tag: 3a1e67fb856b73838ddcd6108e73909c9c4769e8 subdir: cardano-dex-contracts-offchain diff --git a/nix/pkgs/haskell/haskell.nix b/nix/pkgs/haskell/haskell.nix index e5424271..80117903 100644 --- a/nix/pkgs/haskell/haskell.nix +++ b/nix/pkgs/haskell/haskell.nix @@ -43,7 +43,7 @@ let "https://github.com/input-output-hk/cardano-ledger"."c7c63dabdb215ebdaed8b63274965966f2bf408f" = "zTQbMOGPD1Oodv6VUsfF6NUiXkbN8SWI98W3Atv4wbI="; "https://github.com/input-output-hk/plutus-apps"."593ffafa59dd30ad28cfaf144c526c66328595d2" = "CIuI/Nz7O67ljOHDg7UBbXgWuIE7VPRdPX4VK0/DI3A="; "https://github.com/input-output-hk/hedgehog-extras"."714ee03a5a786a05fc57ac5d2f1c2edce4660d85" = "6KQFEzb9g2a0soVvwLKESEbA+a8ygpROcMr6bkatROE="; - "https://github.com/ergolabs/cardano-dex-contracts"."7850574a9b7f3e33cd7fc16f5fcdbbf0c8de68df" = "1jzh8o3SdkZflVLLglT45iCcmgDSAg6b1P7fTwwmgPM="; + "https://github.com/ergolabs/cardano-dex-contracts"."3a1e67fb856b73838ddcd6108e73909c9c4769e8" = "Z/mlhsyPE5uVg7y6g/sOl9Y7gfA4cIxBIdky8cnXceE="; "https://github.com/ergolabs/hlog"."19dfa3a6e696a3f63fc3539cd6b7a3fc4d999853" = "Lvmj1oLuXmktrboXh/BrXqLPf8FxSCXIf99GnBXu0Bk="; "https://github.com/daleiz/rocksdb-haskell"."109af08f95b40f458d4933e3725ecb3e59337c39" = "1i1ya491fapa0g96527krarv0w0iybizqcz518741iw06hhpikiy"; }; diff --git a/submit-api/test/Main.hs b/submit-api/test/Main.hs index 5dbca7e0..7d507f44 100644 --- a/submit-api/test/Main.hs +++ b/submit-api/test/Main.hs @@ -1,25 +1,352 @@ +{-# LANGUAGE TypeApplications #-} {-# LANGUAGE OverloadedStrings #-} - +{-# LANGUAGE RecordWildCards #-} module Main where import qualified Data.Text.Encoding as E import Test.Tasty import Test.Tasty.HUnit - -import Spec.Transaction -import System.Exit (exitFailure) -import Control.Monad (unless) +import PlutusTx.Builtins.Internal hiding (fst) +import PlutusTx +import ErgoDex.Contracts.Pool import CardanoTx.Address +import qualified Data.ByteString as BS +import qualified Data.ByteString.Base16 as Hex +import qualified Data.Text.Encoding as T +import qualified Data.ByteString.Short as SBS +import qualified Data.ByteString.Lazy as LBS +import Codec.Serialise (serialise, deserialise) +import Data.Aeson as Json ( encode ) +import qualified Data.Text.Encoding as E +import qualified Data.ByteString.Base16 as Hex +import Plutus.Script.Utils.V2.Scripts +import qualified Plutus.V2.Ledger.Api as PlutusV2 +import qualified Data.Text as T +import Plutus.V1.Ledger.Value (AssetClass(..), assetClassValueOf, flattenValue, CurrencySymbol(..), TokenName(..)) +import Plutus.V1.Ledger.Api +import ErgoDex.PValidators +import Cardano.Api (writeFileTextEnvelope, Error(displayError), ScriptDataJsonSchema (ScriptDataJsonDetailedSchema)) +import Cardano.Api.Shelley (PlutusScript (..), PlutusScriptV2) +import qualified Plutus.V1.Ledger.Scripts as Plutus +import qualified Cardano.Api as C +import qualified Plutus.Script.Utils.V2.Address as PV2 +import Cardano.Api (scriptDataToJson) +import Cardano.Api.Shelley ( fromPlutusData ) +import WalletAPI.TrustStore (importTrustStoreFromCardano, SecretFile (SecretFile), KeyPass (KeyPass)) +import qualified Ledger as PV2 +import CardanoTx.Address (readShellyAddress) +import Plutus.Script.Utils.V1.Address (mkValidatorAddress) +import Hedgehog.Internal.Show (Value(Integer)) + + +data TokenInfo = TokenInfo + { curSymbol :: String + , tokenName :: String + } deriving Eq + +instance Show TokenInfo where + show TokenInfo{..} = curSymbol ++ "." ++ tokenName + +adaTokenInfo :: TokenInfo +adaTokenInfo = TokenInfo "" "" + +isAda :: TokenInfo -> Bool +isAda ti = ti == adaTokenInfo + +data PoolInfo = PoolInfo + { name :: String + , tokenX :: TokenInfo + , tokenY :: TokenInfo + , tokenNft :: TokenInfo + , tokenLP :: TokenInfo + , lqBound :: Integer + , authKeys :: [String] + , threshold :: Integer + , initialXQty :: Integer + , initialYQty :: Integer + , allowStaking :: Bool + } + +lqInitQty = 9223372036854775807 + +workDir :: String +workDir = "/home/bromel/test-mainnet-pools/" + +mintingPolicyNamePostfix :: String +mintingPolicyNamePostfix = "_mintingPolicy" + +stakingScriptNamePostfix :: String +stakingScriptNamePostfix = "_stakingScript" + +poolDatumPostfix :: String +poolDatumPostfix = "_poolDatum" + +uplcExtension :: String +uplcExtension = ".uplc" + +plutusExtension :: String +plutusExtension = ".plutus" + +jsonExtension :: String +jsonExtension = ".json" + +uplcPolicyPath :: PoolInfo -> String +uplcPolicyPath PoolInfo{..} = workDir ++ name ++ mintingPolicyNamePostfix ++ uplcExtension + +plutusPolicyPath :: PoolInfo -> String +plutusPolicyPath PoolInfo{..} = workDir ++ name ++ mintingPolicyNamePostfix ++ plutusExtension + +uplcStakingScriptPath :: String -> String +uplcStakingScriptPath pkh = workDir ++ pkh ++ stakingScriptNamePostfix ++ uplcExtension + +plutusStakingScriptPath :: String -> String +plutusStakingScriptPath pkh = workDir ++ pkh ++ stakingScriptNamePostfix ++ plutusExtension + +poolDatumPath :: PoolInfo -> String +poolDatumPath PoolInfo{..} = workDir ++ name ++ poolDatumPostfix ++ jsonExtension + +poolMainnetServerDatumPath :: String -> PoolInfo -> String +poolMainnetServerDatumPath mainnetWorkDir PoolInfo{..} = mainnetWorkDir ++ name ++ poolDatumPostfix ++ jsonExtension + +dq = "\"" main :: IO () main = do - print $ show $ readShellyAddress "addr1x9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evkqwx9ghwy6quk2fhu5g0ek8rth7z4zxr5ev975ph34q5fsq2amyd" - print $ show $ readShellyAddress "addr1w9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evsg37dfw" - --defaultMain tests - -tests = testGroup "SubmitApi" - [ buildTxBodyTests - , buildTxBodyContentTests - , buildBalancedTxTests - ] \ No newline at end of file + -- defaultMain tests + let + wallet1PubKeyHash = "9b697975d20d891cc1713a3c4d3f881490880a780019337037ef079c" + wallet2PubKeyHash = "a6e1973e53af80c473cafb288235864f66240d305d9ce9df992125ea" + + mintingSignatures = [wallet1PubKeyHash, wallet2PubKeyHash] + + signaturesThreshold = 2 + + lqQty = 9223372036854775807 + + snekPool = PoolInfo + { name = "snekPool" + , tokenX = adaTokenInfo + , tokenY = TokenInfo "279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f" "534e454b" + , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "4144415f20534e454b5f4e4654" + , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "4144415f20534e454b5f4c51" + , lqBound = 1000 + , authKeys = [] + , threshold = signaturesThreshold + , initialXQty = 4000000 + , initialYQty = 4000 + , allowStaking = True + } + sundaePool = PoolInfo + { name = "sundaePool" + , tokenX = adaTokenInfo + , tokenY = TokenInfo "9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d77" "53554e444145" + , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "4144415f53554e4441455f4e4654" + , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "4144415F53554E4441455F4C51" + , lqBound = 5000000 + , authKeys = [] + , threshold = signaturesThreshold + , initialXQty = 10000000 + , initialYQty = 1000000 + , allowStaking = True + } + snekSundaePool = PoolInfo + { name = "snekSundaePool" + , tokenX = TokenInfo "279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f" "534e454b" + , tokenY = TokenInfo "9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d77" "53554e444145" + , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "534E454B5F53554E4441455F4E4654" + , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "534E454B5F53554E4441455F4C51" + , lqBound = 5000000 + , authKeys = [] + , threshold = signaturesThreshold + , initialXQty = 900 + , initialYQty = 3000000 + , allowStaking = False + } + pools = [snekPool, sundaePool, snekSundaePool] + + -- Step 1. Converting uplc produced by cardano-contracts onchain repo to plutus + + -- convertUplcMintingPolicy `traverse` pools + + -- Step 1.5 (optional) + + -- convertUplcStakingScript wallet2PubKeyHash + + -- Step 2. Datums creation. Will produce output for cardano-cli. Also necessary to copy all datums from test to mainnet machine + + -- createDatumJson `traverse` pools + + -- Step 3. Require manual steps for creation staking certs + -- Also we cannot retrive original min utxo value for inline datums. So, set it manually + -- More Also, we cannot determine change. So, set it manually too + + -- let + -- poolAddressWithStaking = "addr1x9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evkqwx9ghwy6quk2fhu5g0ek8rth7z4zxr5ev975ph34q5fsq2amyd" + -- poolAddress = "addr1w9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evsg37dfw" + -- -- on mainnet machine + -- origDatumWorkDir = "/root/plutus-scripts-for-mainnet/test-pools/datums/" + + -- bootstrapAddressString = "" + -- bootstrapAddressVKeyPath = "" + + -- minUtxoValueForPool = 3223960 + + -- res = (\pi -> poolCLICreationOutput pi poolAddressWithStaking poolAddress minUtxoValueForPool origDatumWorkDir) `fmap` pools + + -- folded = foldr (\acc nextPool -> acc ++ "\n" ++ nextPool) "" res + + -- putStr folded + + -- end + + testJson + + pool <- poolValidator + swap <- swapValidator + redeem <- redeemValidator + deposit <- depositValidator + + print $ mkValidatorAddress pool + print $ mkValidatorAddress swap + print $ mkValidatorAddress redeem + print $ mkValidatorAddress deposit + + print $ readShellyAddress "addr1x9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evkqwx9ghwy6quk2fhu5g0ek8rth7z4zxr5ev975ph34q5fsq2amyd" + + pure () + +-- poolDatum = PoolConfig spectrumTokenNFTClass spectrumTokenAClass spectrumTokenBClass spectrumTokenLPClass 995 + +-- poolDatumData = toData poolDatum + +-- datumStr = (T.decodeUtf8 . Hex.encode $ (LBS.toStrict $ serialise $ poolDatumData)) + +--- Pool creation stuff --- + +-- return cardano-cli string for pool and lp charge for user +poolCLICreationOutput :: PoolInfo -> String -> String -> Integer -> String -> String +poolCLICreationOutput pi@PoolInfo{..} poolAddressWithStaking poolAddress minUtxoValue origDatumWorkDir = + let + adaValue = if isAda tokenX then show initialXQty else show minUtxoValue + tokenXValue = if isAda tokenX then "" else "+" ++ dq ++ show initialXQty ++ " " ++ show tokenX ++ dq + tokenYValue = "+" ++ dq ++ show initialYQty ++ " " ++ show tokenY ++ dq + tokenNftValue = "+" ++ dq ++ "1 " ++ show tokenNft ++ dq + + charge = floor . sqrt . fromIntegral $ (initialXQty * initialYQty) + + tokenLpValue = "+" ++ dq ++ show (lqInitQty - charge) ++ " " ++ show tokenLP ++ dq + + address = if allowStaking then poolAddressWithStaking else poolAddress + + toCardanoCliPoolValue = "--tx-out " ++ address ++ "+" ++ adaValue ++ tokenXValue ++ tokenYValue ++ tokenNftValue ++ tokenLpValue ++ " \\" + + toCardanoCliDatum = "--tx-out-inline-datum-file " ++ poolMainnetServerDatumPath origDatumWorkDir pi ++ " \\" + + in toCardanoCliPoolValue ++ ['\n'] ++ toCardanoCliDatum + +--- Datum creation stuff --- + +createDatumJson :: PoolInfo -> IO () +createDatumJson pi@PoolInfo{..} = do + let + convertedNft = tokenInfo2CS tokenNft + convertedX = tokenInfo2CS tokenX + convertedY = tokenInfo2CS tokenY + convertedLP = tokenInfo2CS tokenLP + + policies <- + if allowStaking + then do + mpPolicy <- getPoolMintingPolicy pi + let + (PlutusV2.MintingPolicyHash mpPolicyHash) = mintingPolicyHash mpPolicy + mpCS = CurrencySymbol mpPolicyHash + pure [mpCS] + else pure [] + + let poolConfig = PoolConfig convertedNft convertedX convertedY convertedLP 995 policies lqBound + + writeDatumToJson pi poolConfig + pure () + +writeDatumToJson :: PoolInfo -> PoolConfig -> IO () +writeDatumToJson pi poolDatum = + LBS.writeFile (poolDatumPath pi) (Json.encode + . scriptDataToJson ScriptDataJsonDetailedSchema + . fromPlutusData + . toData + $ poolDatum ) + +testJson :: IO () +testJson = + print (Json.encode + . scriptDataToJson ScriptDataJsonDetailedSchema + . fromPlutusData + . toData + $ (0 :: Integer) ) + +--- Minting policies stuff --- + +convertUplcMintingPolicy :: PoolInfo -> IO () +convertUplcMintingPolicy pi@PoolInfo{..} = + if allowStaking + then do + bytes <- BS.readFile (uplcPolicyPath pi) + let + shortBS = SBS.toShort bytes + scr :: PlutusScript PlutusScriptV2 + scr = PlutusScriptSerialised shortBS + writeFileTextEnvelope (plutusPolicyPath pi) Nothing scr + pure () + else pure () + +getPoolMintingPolicy :: PoolInfo -> IO PV2.MintingPolicy +getPoolMintingPolicy pi = do + bytes <- BS.readFile (uplcPolicyPath pi) + let + script = deserialise (LBS.fromStrict bytes) + pure (PlutusV2.MintingPolicy script) + +--- Staking scripts stuff --- + +convertUplcStakingScript :: String -> IO () +convertUplcStakingScript pkh = do + bytes <- BS.readFile (uplcStakingScriptPath pkh) + let + shortBS = SBS.toShort bytes + scr :: PlutusScript PlutusScriptV2 + scr = PlutusScriptSerialised shortBS + writeFileTextEnvelope (plutusStakingScriptPath pkh) Nothing scr + pure () + +tokenInfo2CS :: TokenInfo -> AssetClass +tokenInfo2CS TokenInfo{..} = + let + convertedCS = CurrencySymbol $ BuiltinByteString $ mkByteString $ T.pack curSymbol + convertedTN = TokenName $ BuiltinByteString $ mkByteString $ T.pack tokenName + in AssetClass (convertedCS, convertedTN) + +textToPubKeyHash :: String -> PubKeyHash +textToPubKeyHash = PubKeyHash . BuiltinByteString . mkByteString . T.pack + +mkByteString :: T.Text -> BS.ByteString +mkByteString input = unsafeFromEither (Hex.decode . E.encodeUtf8 $ input) + +unsafeFromEither :: (Show b) => Either b a -> a +unsafeFromEither (Left err) = Prelude.error ("Err:" ++ show err) +unsafeFromEither (Right value) = value + +-- writeDataDatum2 :: FilePath -> IO () +-- writeDataDatum2 file = do +-- LBS.writeFile file (Json.encode +-- . scriptDataToJson ScriptDataJsonDetailedSchema +-- . fromPlutusData +-- . toData +-- $ (poolDatum) ) + +-- tests = testGroup "SubmitApi" +-- [ buildTxBodyTests +-- , buildTxBodyContentTests +-- , buildBalancedTxTests +-- ] \ No newline at end of file From 988719ba8a11acd057db8870b4504c49dec63ec3 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 23 Jul 2023 17:27:48 +0200 Subject: [PATCH 06/21] fix deps --- cabal.project | 2 +- dex-core/test/Spec/Pool.hs | 2 +- nix/pkgs/haskell/haskell.nix | 2 +- submit-api/test/Main.hs | 13 +++++-------- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/cabal.project b/cabal.project index ff6f7669..e49a7e07 100644 --- a/cabal.project +++ b/cabal.project @@ -313,7 +313,7 @@ source-repository-package source-repository-package type: git location: https://github.com/ergolabs/cardano-dex-contracts - tag: 3a1e67fb856b73838ddcd6108e73909c9c4769e8 + tag: b4330de32e2d8be821a8a4fd3fd2d24508c280d7 subdir: cardano-dex-contracts-offchain diff --git a/dex-core/test/Spec/Pool.hs b/dex-core/test/Spec/Pool.hs index be4592f5..2139f70f 100644 --- a/dex-core/test/Spec/Pool.hs +++ b/dex-core/test/Spec/Pool.hs @@ -80,7 +80,7 @@ initialLiquidityTests = testGroup "InitialLiquidity" initialLiquidityAmount poolLq (Amount 10, Amount 11) @?= Right (AssetAmount poolLq 11) ] -poolConf = S.PoolConfig poolNft poolX poolY poolLq poolFeeNum [] 0 +poolConf = S.PoolConfig poolNft poolX poolY poolLq poolFeeNum sufficientInitDepositX = Amount 800 diff --git a/nix/pkgs/haskell/haskell.nix b/nix/pkgs/haskell/haskell.nix index 80117903..101c8f6b 100644 --- a/nix/pkgs/haskell/haskell.nix +++ b/nix/pkgs/haskell/haskell.nix @@ -43,7 +43,7 @@ let "https://github.com/input-output-hk/cardano-ledger"."c7c63dabdb215ebdaed8b63274965966f2bf408f" = "zTQbMOGPD1Oodv6VUsfF6NUiXkbN8SWI98W3Atv4wbI="; "https://github.com/input-output-hk/plutus-apps"."593ffafa59dd30ad28cfaf144c526c66328595d2" = "CIuI/Nz7O67ljOHDg7UBbXgWuIE7VPRdPX4VK0/DI3A="; "https://github.com/input-output-hk/hedgehog-extras"."714ee03a5a786a05fc57ac5d2f1c2edce4660d85" = "6KQFEzb9g2a0soVvwLKESEbA+a8ygpROcMr6bkatROE="; - "https://github.com/ergolabs/cardano-dex-contracts"."3a1e67fb856b73838ddcd6108e73909c9c4769e8" = "Z/mlhsyPE5uVg7y6g/sOl9Y7gfA4cIxBIdky8cnXceE="; + "https://github.com/ergolabs/cardano-dex-contracts"."b4330de32e2d8be821a8a4fd3fd2d24508c280d7" = "exJoEIagnfPYqW3Tj96/Q/A/dR9c2jW5KPSahXfazfg="; "https://github.com/ergolabs/hlog"."19dfa3a6e696a3f63fc3539cd6b7a3fc4d999853" = "Lvmj1oLuXmktrboXh/BrXqLPf8FxSCXIf99GnBXu0Bk="; "https://github.com/daleiz/rocksdb-haskell"."109af08f95b40f458d4933e3725ecb3e59337c39" = "1i1ya491fapa0g96527krarv0w0iybizqcz518741iw06hhpikiy"; }; diff --git a/submit-api/test/Main.hs b/submit-api/test/Main.hs index 7d507f44..0fbb6a79 100644 --- a/submit-api/test/Main.hs +++ b/submit-api/test/Main.hs @@ -200,19 +200,16 @@ main = do -- end - testJson - pool <- poolValidator swap <- swapValidator redeem <- redeemValidator deposit <- depositValidator - print $ mkValidatorAddress pool - print $ mkValidatorAddress swap - print $ mkValidatorAddress redeem - print $ mkValidatorAddress deposit - - print $ readShellyAddress "addr1x9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evkqwx9ghwy6quk2fhu5g0ek8rth7z4zxr5ev975ph34q5fsq2amyd" + let + shortBS = SBS.toShort $ LBS.toStrict $ serialise (unValidatorScript pool) + scr :: PlutusScript PlutusScriptV2 + scr = PlutusScriptSerialised shortBS + writeFileTextEnvelope "/home/bromel/projects/cardano-dex-sdk-haskell/submit-api/pool.plutus" Nothing scr pure () From c86d2dc8a9c564d68057fb34ba2b8aae0d71b411 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Tue, 25 Jul 2023 12:07:19 +0200 Subject: [PATCH 07/21] add debug --- dex-core/src/ErgoDex/Amm/PoolActions.hs | 137 +++++-- .../src/SubmitAPI/Internal/Balancing.hs | 4 + submit-api/test/Main.hs | 348 +----------------- 3 files changed, 121 insertions(+), 368 deletions(-) diff --git a/dex-core/src/ErgoDex/Amm/PoolActions.hs b/dex-core/src/ErgoDex/Amm/PoolActions.hs index ab38e496..42f20a46 100644 --- a/dex-core/src/ErgoDex/Amm/PoolActions.hs +++ b/dex-core/src/ErgoDex/Amm/PoolActions.hs @@ -28,6 +28,8 @@ import qualified ErgoDex.Contracts.Pool as P import qualified ErgoDex.Contracts.Proxy.Order as O import ErgoDex.Contracts.Types import CardanoTx.Models +import System.Logging.Hlog (Logging (Logging)) +import Plutus.V1.Ledger.Value (Value) data OrderExecErr = PriceTooHigh @@ -46,6 +48,30 @@ data AmmValidators ver = AmmValidators , redeemV :: RedeemValidator ver } +-- debug order info +data OrderInfo = RedeemInfo { redeem :: Redeem + , redeemOut :: FullTxOut + , burnLqValue :: Maybe Value + , realExFee :: Maybe Integer + , outXAndY :: Maybe (AssetAmount X, AssetAmount Y) + , exFee :: Maybe Integer + } + | SwapInfo { swap :: Swap + , swapOut :: FullTxOut + , realQuoteOutput :: AssetAmount Quote + , realExFee :: Maybe Integer + , realRV :: Maybe Value + } + | DepositInfo { deposit :: Deposit + , depositOut :: FullTxOut + , inXAndY :: Maybe (Amount X, Amount Y) + , netXAndY :: Maybe (Amount X, Amount Y) + , rewardLPAndCharge :: Maybe (Amount Liquidity, (Amount X, Amount Y)) + , mintLqValue :: Maybe Value + , depositExFee :: Maybe (Amount Lovelace) + } + deriving (Show) + fetchValidatorsV1 :: MonadIO m => m (AmmValidators V1) fetchValidatorsV1 = AmmValidators @@ -55,9 +81,9 @@ fetchValidatorsV1 = <*> fetchRedeemValidatorV1 data PoolActions = PoolActions - { runSwap :: [FullTxOut] -> OnChain Swap -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool) - , runDeposit :: [FullTxOut] -> OnChain Deposit -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool) - , runRedeem :: [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool) + { runSwap :: [FullTxOut] -> OnChain Swap -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) + , runDeposit :: [FullTxOut] -> OnChain Deposit -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) + , runRedeem :: [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) } mkPoolActions :: PaymentPubKeyHash -> AmmValidators V1 -> PoolActions @@ -94,16 +120,22 @@ runSwap' -> [FullTxOut] -> OnChain Swap -> (FullTxOut, Pool) - -> Either OrderExecErr (TxCandidate, Predicted Pool) -runSwap' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do + -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) +runSwap' executorPkh pv sv refInputs (OnChain swapOut s@Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do let inputs = mkOrderInputs P.Swap pv sv (PoolIn poolOut) (OrderIn swapOut) pp@(Predicted nextPoolOut _) = applySwap pv pool (AssetAmount swapBase swapBaseIn) quoteOutput = outputAmount pool (AssetAmount swapBase swapBaseIn) - - when (swapPoolId /= poolId pool) (Left $ PoolMismatch swapPoolId (poolId pool)) - when (getAmount quoteOutput < swapMinQuoteOut) (Left PriceTooHigh) - when (poolReservesX pool * 2 <= lqBound pool) (Left $ InsufficientPoolLqForSwap (poolId pool)) + initSwapInfo = SwapInfo + { swap = s + , swapOut = swapOut + , realQuoteOutput = quoteOutput + , realExFee = Nothing + , realRV = Nothing + } + when (swapPoolId /= poolId pool) (Left $ (PoolMismatch swapPoolId (poolId pool), initSwapInfo)) + when (getAmount quoteOutput < swapMinQuoteOut) (Left (PriceTooHigh, initSwapInfo)) + when (poolReservesX pool * 2 <= lqBound pool) (Left $ (InsufficientPoolLqForSwap (poolId pool), initSwapInfo)) let exFee = assetAmountRawValue quoteOutput * exFeePerTokenNum `div` exFeePerTokenDen @@ -118,24 +150,32 @@ runSwap' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFeePerTok where initValue = fullTxOutValue swapOut residualValue = - initValue + initValue <> assetClassValue (unCoin swapBase) (negate $ unAmount swapBaseIn) -- Remove Base input <> Ada.lovelaceValueOf (negate exFee) -- Remove Batcher Fee rewardValue = assetAmountValue quoteOutput <> residualValue - txCandidate = TxCandidate - { txCandidateInputs = inputs - , txCandidateRefIns = refInputs - , txCandidateOutputs = [nextPoolOut, rewardOut] - , txCandidateValueMint = mempty - , txCandidateMintInputs = mempty - , txCandidateChangePolicy = Just $ ReturnTo $ pubKeyHashAddress executorPkh Nothing - , txCandidateValidRange = Interval.always - , txCandidateSigners = mempty + fullSwapInfo = SwapInfo + { swap = s + , swapOut = swapOut + , realQuoteOutput = quoteOutput + , realExFee = Just exFee + , realRV = Just (txOutCandidateValue rewardOut) } - Right (txCandidate, pp) + txCandidate = TxCandidate + { txCandidateInputs = inputs + , txCandidateRefIns = refInputs + , txCandidateOutputs = [nextPoolOut, rewardOut] + , txCandidateValueMint = mempty + , txCandidateMintInputs = mempty + , txCandidateChangePolicy = Just $ ReturnTo $ pubKeyHashAddress executorPkh Nothing + , txCandidateValidRange = Interval.always + , txCandidateSigners = mempty + } + + Right (txCandidate, pp, fullSwapInfo) runDeposit' :: PaymentPubKeyHash @@ -144,9 +184,20 @@ runDeposit' -> [FullTxOut] -> OnChain Deposit -> (FullTxOut, Pool) - -> Either OrderExecErr (TxCandidate, Predicted Pool) -runDeposit' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOut, pool@Pool{..}) = do - when (depositPoolId /= poolId) (Left $ PoolMismatch depositPoolId poolId) + -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) +runDeposit' executorPkh pv dv refInputs (OnChain depositOut d@Deposit{..}) (poolOut, pool@Pool{..}) = do + let + initDepositInfo = DepositInfo + { deposit = d + , depositOut = depositOut + , inXAndY = Nothing + , netXAndY = Nothing + , rewardLPAndCharge = Nothing + , mintLqValue = Nothing + , depositExFee = Nothing + } + + when (depositPoolId /= poolId) (Left $ ((PoolMismatch depositPoolId poolId), initDepositInfo)) let inputs = mkOrderInputs P.Deposit pv dv (PoolIn poolOut) (OrderIn depositOut) @@ -154,7 +205,7 @@ runDeposit' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOu bimap entryAmount entryAmount $ if assetEntryClass (fst depositPair) == unCoin poolCoinX then depositPair - else swap depositPair + else Data.Tuple.swap depositPair where entryAmount (AssetEntry (_, v)) = Amount v exFee = unExFee depositExFee @@ -191,6 +242,16 @@ runDeposit' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOu <> Ada.lovelaceValueOf (negate $ unAmount exFee) -- Remove Fee rewardValue = residualValue <> mintLqValue <> alignmentValue + finalDepositInfo = DepositInfo + { deposit = d + , depositOut = depositOut + , inXAndY = Just (inX, inY) + , netXAndY = Just (netInX, netInY) + , rewardLPAndCharge = Just $ rewardLp pool (netInX, netInY) + , mintLqValue = Just mintLqValue + , depositExFee = Just exFee + } + txCandidate = TxCandidate { txCandidateInputs = inputs , txCandidateRefIns = refInputs @@ -202,7 +263,7 @@ runDeposit' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOu , txCandidateSigners = mempty } - Right (txCandidate, pp) + Right (txCandidate, pp, finalDepositInfo) runRedeem' :: PaymentPubKeyHash @@ -211,9 +272,18 @@ runRedeem' -> [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) - -> Either OrderExecErr (TxCandidate, Predicted Pool) -runRedeem' executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, pool@Pool{..}) = do - when (redeemPoolId /= poolId) (Left $ PoolMismatch redeemPoolId poolId) + -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) +runRedeem' executorPkh pv rv refInputs (OnChain redeemOut r@Redeem{..}) (poolOut, pool@Pool{..}) = do + let + initRedeemInfo = RedeemInfo + { redeem = r + , redeemOut = redeemOut + , burnLqValue = Nothing + , realExFee = Nothing + , outXAndY = Nothing + , exFee = Nothing + } + when (redeemPoolId /= poolId) (Left $ ((PoolMismatch redeemPoolId poolId), initRedeemInfo)) let inputs = mkOrderInputs P.Redeem pv rv (PoolIn poolOut) (OrderIn redeemOut) @@ -242,6 +312,15 @@ runRedeem' executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, rewardValue = assetAmountValue outX <> assetAmountValue outY <> residualValue + finalRedeemInfo = RedeemInfo + { redeem = r + , redeemOut = redeemOut + , burnLqValue = Just burnLqValue + , realExFee = Just exFee + , outXAndY = Just (sharesAmount pool redeemLqIn) + , exFee = Just exFee + } + txCandidate = TxCandidate { txCandidateInputs = inputs , txCandidateRefIns = refInputs @@ -253,4 +332,4 @@ runRedeem' executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, , txCandidateSigners = mempty } - Right (txCandidate, pp) + Right (txCandidate, pp, finalRedeemInfo) diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 4cc0696a..8b865f71 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -15,6 +15,7 @@ import Data.Ratio import Cardano.Api import Cardano.Api.Shelley (ProtocolParameters(..), PoolId, ReferenceScript (..), fromShelleyLovelace) import qualified Cardano.Ledger.Coin as Ledger +import Debug.Trace makeTransactionBodyAutoBalance :: forall era mode. @@ -271,8 +272,11 @@ makeTransactionBodyAutoBalance eraInMode systemstart history pparams -> ProtocolParameters -> Either TxBodyErrorAutoBalance () checkMinUTxOValue txout@(TxOut addr v _ _) pparams' = do + traceM $ "Going to check min utxo for box: " ++ show txout minUTxO <- first TxBodyErrorMinUTxOMissingPParams $ calculateMinimumUTxO era txout pparams' + traceM $ "Min utxo is: " ++ show minUTxO + traceM $ "Lovelace in box is: " ++ show (txOutValueToLovelace v) let chargeBoxWillBeMerged = addr == changeaddr if txOutValueToLovelace v >= selectLovelace minUTxO || chargeBoxWillBeMerged then Right () diff --git a/submit-api/test/Main.hs b/submit-api/test/Main.hs index 0fbb6a79..3b4b316c 100644 --- a/submit-api/test/Main.hs +++ b/submit-api/test/Main.hs @@ -1,349 +1,19 @@ -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RecordWildCards #-} module Main where import qualified Data.Text.Encoding as E import Test.Tasty import Test.Tasty.HUnit -import PlutusTx.Builtins.Internal hiding (fst) -import PlutusTx -import ErgoDex.Contracts.Pool -import CardanoTx.Address -import qualified Data.ByteString as BS -import qualified Data.ByteString.Base16 as Hex -import qualified Data.Text.Encoding as T -import qualified Data.ByteString.Short as SBS -import qualified Data.ByteString.Lazy as LBS -import Codec.Serialise (serialise, deserialise) -import Data.Aeson as Json ( encode ) -import qualified Data.Text.Encoding as E -import qualified Data.ByteString.Base16 as Hex -import Plutus.Script.Utils.V2.Scripts -import qualified Plutus.V2.Ledger.Api as PlutusV2 -import qualified Data.Text as T -import Plutus.V1.Ledger.Value (AssetClass(..), assetClassValueOf, flattenValue, CurrencySymbol(..), TokenName(..)) -import Plutus.V1.Ledger.Api -import ErgoDex.PValidators -import Cardano.Api (writeFileTextEnvelope, Error(displayError), ScriptDataJsonSchema (ScriptDataJsonDetailedSchema)) -import Cardano.Api.Shelley (PlutusScript (..), PlutusScriptV2) -import qualified Plutus.V1.Ledger.Scripts as Plutus -import qualified Cardano.Api as C -import qualified Plutus.Script.Utils.V2.Address as PV2 -import Cardano.Api (scriptDataToJson) -import Cardano.Api.Shelley ( fromPlutusData ) -import WalletAPI.TrustStore (importTrustStoreFromCardano, SecretFile (SecretFile), KeyPass (KeyPass)) -import qualified Ledger as PV2 -import CardanoTx.Address (readShellyAddress) -import Plutus.Script.Utils.V1.Address (mkValidatorAddress) -import Hedgehog.Internal.Show (Value(Integer)) - -data TokenInfo = TokenInfo - { curSymbol :: String - , tokenName :: String - } deriving Eq - -instance Show TokenInfo where - show TokenInfo{..} = curSymbol ++ "." ++ tokenName - -adaTokenInfo :: TokenInfo -adaTokenInfo = TokenInfo "" "" - -isAda :: TokenInfo -> Bool -isAda ti = ti == adaTokenInfo - -data PoolInfo = PoolInfo - { name :: String - , tokenX :: TokenInfo - , tokenY :: TokenInfo - , tokenNft :: TokenInfo - , tokenLP :: TokenInfo - , lqBound :: Integer - , authKeys :: [String] - , threshold :: Integer - , initialXQty :: Integer - , initialYQty :: Integer - , allowStaking :: Bool - } - -lqInitQty = 9223372036854775807 - -workDir :: String -workDir = "/home/bromel/test-mainnet-pools/" - -mintingPolicyNamePostfix :: String -mintingPolicyNamePostfix = "_mintingPolicy" - -stakingScriptNamePostfix :: String -stakingScriptNamePostfix = "_stakingScript" - -poolDatumPostfix :: String -poolDatumPostfix = "_poolDatum" - -uplcExtension :: String -uplcExtension = ".uplc" - -plutusExtension :: String -plutusExtension = ".plutus" - -jsonExtension :: String -jsonExtension = ".json" - -uplcPolicyPath :: PoolInfo -> String -uplcPolicyPath PoolInfo{..} = workDir ++ name ++ mintingPolicyNamePostfix ++ uplcExtension - -plutusPolicyPath :: PoolInfo -> String -plutusPolicyPath PoolInfo{..} = workDir ++ name ++ mintingPolicyNamePostfix ++ plutusExtension - -uplcStakingScriptPath :: String -> String -uplcStakingScriptPath pkh = workDir ++ pkh ++ stakingScriptNamePostfix ++ uplcExtension - -plutusStakingScriptPath :: String -> String -plutusStakingScriptPath pkh = workDir ++ pkh ++ stakingScriptNamePostfix ++ plutusExtension - -poolDatumPath :: PoolInfo -> String -poolDatumPath PoolInfo{..} = workDir ++ name ++ poolDatumPostfix ++ jsonExtension - -poolMainnetServerDatumPath :: String -> PoolInfo -> String -poolMainnetServerDatumPath mainnetWorkDir PoolInfo{..} = mainnetWorkDir ++ name ++ poolDatumPostfix ++ jsonExtension - -dq = "\"" +import Spec.Transaction +import System.Exit (exitFailure) +import Control.Monad (unless) main :: IO () -main = do - -- defaultMain tests - let - wallet1PubKeyHash = "9b697975d20d891cc1713a3c4d3f881490880a780019337037ef079c" - wallet2PubKeyHash = "a6e1973e53af80c473cafb288235864f66240d305d9ce9df992125ea" - - mintingSignatures = [wallet1PubKeyHash, wallet2PubKeyHash] - - signaturesThreshold = 2 - - lqQty = 9223372036854775807 - - snekPool = PoolInfo - { name = "snekPool" - , tokenX = adaTokenInfo - , tokenY = TokenInfo "279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f" "534e454b" - , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "4144415f20534e454b5f4e4654" - , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "4144415f20534e454b5f4c51" - , lqBound = 1000 - , authKeys = [] - , threshold = signaturesThreshold - , initialXQty = 4000000 - , initialYQty = 4000 - , allowStaking = True - } - sundaePool = PoolInfo - { name = "sundaePool" - , tokenX = adaTokenInfo - , tokenY = TokenInfo "9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d77" "53554e444145" - , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "4144415f53554e4441455f4e4654" - , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "4144415F53554E4441455F4C51" - , lqBound = 5000000 - , authKeys = [] - , threshold = signaturesThreshold - , initialXQty = 10000000 - , initialYQty = 1000000 - , allowStaking = True - } - snekSundaePool = PoolInfo - { name = "snekSundaePool" - , tokenX = TokenInfo "279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f" "534e454b" - , tokenY = TokenInfo "9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d77" "53554e444145" - , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "534E454B5F53554E4441455F4E4654" - , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "534E454B5F53554E4441455F4C51" - , lqBound = 5000000 - , authKeys = [] - , threshold = signaturesThreshold - , initialXQty = 900 - , initialYQty = 3000000 - , allowStaking = False - } - pools = [snekPool, sundaePool, snekSundaePool] - - -- Step 1. Converting uplc produced by cardano-contracts onchain repo to plutus - - -- convertUplcMintingPolicy `traverse` pools - - -- Step 1.5 (optional) - - -- convertUplcStakingScript wallet2PubKeyHash - - -- Step 2. Datums creation. Will produce output for cardano-cli. Also necessary to copy all datums from test to mainnet machine - - -- createDatumJson `traverse` pools - - -- Step 3. Require manual steps for creation staking certs - -- Also we cannot retrive original min utxo value for inline datums. So, set it manually - -- More Also, we cannot determine change. So, set it manually too - - -- let - -- poolAddressWithStaking = "addr1x9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evkqwx9ghwy6quk2fhu5g0ek8rth7z4zxr5ev975ph34q5fsq2amyd" - -- poolAddress = "addr1w9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evsg37dfw" - -- -- on mainnet machine - -- origDatumWorkDir = "/root/plutus-scripts-for-mainnet/test-pools/datums/" - - -- bootstrapAddressString = "" - -- bootstrapAddressVKeyPath = "" - - -- minUtxoValueForPool = 3223960 - - -- res = (\pi -> poolCLICreationOutput pi poolAddressWithStaking poolAddress minUtxoValueForPool origDatumWorkDir) `fmap` pools - - -- folded = foldr (\acc nextPool -> acc ++ "\n" ++ nextPool) "" res - - -- putStr folded - - -- end - - pool <- poolValidator - swap <- swapValidator - redeem <- redeemValidator - deposit <- depositValidator - - let - shortBS = SBS.toShort $ LBS.toStrict $ serialise (unValidatorScript pool) - scr :: PlutusScript PlutusScriptV2 - scr = PlutusScriptSerialised shortBS - writeFileTextEnvelope "/home/bromel/projects/cardano-dex-sdk-haskell/submit-api/pool.plutus" Nothing scr - - pure () - --- poolDatum = PoolConfig spectrumTokenNFTClass spectrumTokenAClass spectrumTokenBClass spectrumTokenLPClass 995 - --- poolDatumData = toData poolDatum - --- datumStr = (T.decodeUtf8 . Hex.encode $ (LBS.toStrict $ serialise $ poolDatumData)) - ---- Pool creation stuff --- - --- return cardano-cli string for pool and lp charge for user -poolCLICreationOutput :: PoolInfo -> String -> String -> Integer -> String -> String -poolCLICreationOutput pi@PoolInfo{..} poolAddressWithStaking poolAddress minUtxoValue origDatumWorkDir = - let - adaValue = if isAda tokenX then show initialXQty else show minUtxoValue - tokenXValue = if isAda tokenX then "" else "+" ++ dq ++ show initialXQty ++ " " ++ show tokenX ++ dq - tokenYValue = "+" ++ dq ++ show initialYQty ++ " " ++ show tokenY ++ dq - tokenNftValue = "+" ++ dq ++ "1 " ++ show tokenNft ++ dq - - charge = floor . sqrt . fromIntegral $ (initialXQty * initialYQty) - - tokenLpValue = "+" ++ dq ++ show (lqInitQty - charge) ++ " " ++ show tokenLP ++ dq - - address = if allowStaking then poolAddressWithStaking else poolAddress - - toCardanoCliPoolValue = "--tx-out " ++ address ++ "+" ++ adaValue ++ tokenXValue ++ tokenYValue ++ tokenNftValue ++ tokenLpValue ++ " \\" - - toCardanoCliDatum = "--tx-out-inline-datum-file " ++ poolMainnetServerDatumPath origDatumWorkDir pi ++ " \\" - - in toCardanoCliPoolValue ++ ['\n'] ++ toCardanoCliDatum - ---- Datum creation stuff --- - -createDatumJson :: PoolInfo -> IO () -createDatumJson pi@PoolInfo{..} = do - let - convertedNft = tokenInfo2CS tokenNft - convertedX = tokenInfo2CS tokenX - convertedY = tokenInfo2CS tokenY - convertedLP = tokenInfo2CS tokenLP - - policies <- - if allowStaking - then do - mpPolicy <- getPoolMintingPolicy pi - let - (PlutusV2.MintingPolicyHash mpPolicyHash) = mintingPolicyHash mpPolicy - mpCS = CurrencySymbol mpPolicyHash - pure [mpCS] - else pure [] - - let poolConfig = PoolConfig convertedNft convertedX convertedY convertedLP 995 policies lqBound - - writeDatumToJson pi poolConfig - pure () - -writeDatumToJson :: PoolInfo -> PoolConfig -> IO () -writeDatumToJson pi poolDatum = - LBS.writeFile (poolDatumPath pi) (Json.encode - . scriptDataToJson ScriptDataJsonDetailedSchema - . fromPlutusData - . toData - $ poolDatum ) - -testJson :: IO () -testJson = - print (Json.encode - . scriptDataToJson ScriptDataJsonDetailedSchema - . fromPlutusData - . toData - $ (0 :: Integer) ) - ---- Minting policies stuff --- - -convertUplcMintingPolicy :: PoolInfo -> IO () -convertUplcMintingPolicy pi@PoolInfo{..} = - if allowStaking - then do - bytes <- BS.readFile (uplcPolicyPath pi) - let - shortBS = SBS.toShort bytes - scr :: PlutusScript PlutusScriptV2 - scr = PlutusScriptSerialised shortBS - writeFileTextEnvelope (plutusPolicyPath pi) Nothing scr - pure () - else pure () - -getPoolMintingPolicy :: PoolInfo -> IO PV2.MintingPolicy -getPoolMintingPolicy pi = do - bytes <- BS.readFile (uplcPolicyPath pi) - let - script = deserialise (LBS.fromStrict bytes) - pure (PlutusV2.MintingPolicy script) - ---- Staking scripts stuff --- - -convertUplcStakingScript :: String -> IO () -convertUplcStakingScript pkh = do - bytes <- BS.readFile (uplcStakingScriptPath pkh) - let - shortBS = SBS.toShort bytes - scr :: PlutusScript PlutusScriptV2 - scr = PlutusScriptSerialised shortBS - writeFileTextEnvelope (plutusStakingScriptPath pkh) Nothing scr - pure () - -tokenInfo2CS :: TokenInfo -> AssetClass -tokenInfo2CS TokenInfo{..} = - let - convertedCS = CurrencySymbol $ BuiltinByteString $ mkByteString $ T.pack curSymbol - convertedTN = TokenName $ BuiltinByteString $ mkByteString $ T.pack tokenName - in AssetClass (convertedCS, convertedTN) - -textToPubKeyHash :: String -> PubKeyHash -textToPubKeyHash = PubKeyHash . BuiltinByteString . mkByteString . T.pack - -mkByteString :: T.Text -> BS.ByteString -mkByteString input = unsafeFromEither (Hex.decode . E.encodeUtf8 $ input) - -unsafeFromEither :: (Show b) => Either b a -> a -unsafeFromEither (Left err) = Prelude.error ("Err:" ++ show err) -unsafeFromEither (Right value) = value - --- writeDataDatum2 :: FilePath -> IO () --- writeDataDatum2 file = do --- LBS.writeFile file (Json.encode --- . scriptDataToJson ScriptDataJsonDetailedSchema --- . fromPlutusData --- . toData --- $ (poolDatum) ) +main = defaultMain tests --- tests = testGroup "SubmitApi" --- [ buildTxBodyTests --- , buildTxBodyContentTests --- , buildBalancedTxTests --- ] \ No newline at end of file +tests = testGroup "SubmitApi" + [ buildTxBodyTests + , buildTxBodyContentTests + , buildBalancedTxTests + ] \ No newline at end of file From f70b66a889091fd93ded501bdc625104e0e80461 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sat, 29 Jul 2023 15:38:42 +0200 Subject: [PATCH 08/21] add unsafe order execution --- dex-core/src/ErgoDex/Amm/PoolActions.hs | 226 +++++++- .../src/SubmitAPI/Internal/Balancing.hs | 37 +- .../src/SubmitAPI/Internal/Transaction.hs | 21 + submit-api/submit-api.cabal | 6 + submit-api/test/Main.hs | 496 +++++++++++++++++- 5 files changed, 762 insertions(+), 24 deletions(-) diff --git a/dex-core/src/ErgoDex/Amm/PoolActions.hs b/dex-core/src/ErgoDex/Amm/PoolActions.hs index 42f20a46..3ffa72d1 100644 --- a/dex-core/src/ErgoDex/Amm/PoolActions.hs +++ b/dex-core/src/ErgoDex/Amm/PoolActions.hs @@ -81,16 +81,22 @@ fetchValidatorsV1 = <*> fetchRedeemValidatorV1 data PoolActions = PoolActions - { runSwap :: [FullTxOut] -> OnChain Swap -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) - , runDeposit :: [FullTxOut] -> OnChain Deposit -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) - , runRedeem :: [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) + { runSwapWithDebug :: [FullTxOut] -> OnChain Swap -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) + , runDepositWithDebug :: [FullTxOut] -> OnChain Deposit -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) + , runRedeemWithDebug :: [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) + , runSwap :: [FullTxOut] -> OnChain Swap -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) + , runDeposit :: [FullTxOut] -> OnChain Deposit -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) + , runRedeem :: [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) } mkPoolActions :: PaymentPubKeyHash -> AmmValidators V1 -> PoolActions mkPoolActions executorPkh AmmValidators{..} = PoolActions - { runSwap = runSwap' executorPkh poolV swapV - , runDeposit = runDeposit' executorPkh poolV depositV - , runRedeem = runRedeem' executorPkh poolV redeemV + { runSwapWithDebug = runSwapWithDebug' executorPkh poolV swapV + , runDepositWithDebug = runDepositWithDebug' executorPkh poolV depositV + , runRedeemWithDebug = runRedeemWithDebug' executorPkh poolV redeemV + , runSwap = runSwapUnsafe' executorPkh poolV swapV + , runDeposit = runDepositUnsafe' executorPkh poolV depositV + , runRedeem = runRedeemUnsafe' executorPkh poolV redeemV } newtype PoolIn = PoolIn FullTxOut @@ -113,7 +119,203 @@ mkOrderInputs action (PoolValidator pv) ov' (PoolIn poolOut) (OrderIn orderOut) orderIn = mkScriptTxIn orderOut ov (Redeemer $ toBuiltinData $ O.OrderRedeemer poolIx orderIx 1 O.Apply) in Set.fromList [poolIn, orderIn] -runSwap' +runSwapUnsafe' + :: PaymentPubKeyHash + -> PoolValidator V1 + -> SwapValidator V1 + -> [FullTxOut] + -> OnChain Swap + -> (FullTxOut, Pool) + -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) +runSwapUnsafe' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do + let + inputs = mkOrderInputs P.Swap pv sv (PoolIn poolOut) (OrderIn swapOut) + pp@(Predicted nextPoolOut _) = applySwap pv pool (AssetAmount swapBase swapBaseIn) + quoteOutput = outputAmount pool (AssetAmount swapBase swapBaseIn) + + when (swapPoolId /= poolId pool) (Left $ PoolMismatch swapPoolId (poolId pool)) + when (getAmount quoteOutput < swapMinQuoteOut) (Left PriceTooHigh) + when (poolReservesX pool * 2 <= lqBound pool) (Left $ InsufficientPoolLqForSwap (poolId pool)) + + let + fee = 300000 + exFee = assetAmountRawValue quoteOutput * exFeePerTokenNum `div` exFeePerTokenDen + rewardAddr = pubKeyHashAddress (PaymentPubKeyHash swapRewardPkh) swapRewardSPkh + rewardOut = + TxOutCandidate + { txOutCandidateAddress = rewardAddr + , txOutCandidateValue = rewardValue + , txOutCandidateDatum = EmptyDatum + , txOutCandidateRefScript = Nothing + } + where + initValue = fullTxOutValue swapOut + residualValue = + initValue + <> assetClassValue (unCoin swapBase) (negate $ unAmount swapBaseIn) -- Remove Base input + <> Ada.lovelaceValueOf (negate exFee) -- Remove Batcher Fee + + rewardValue = assetAmountValue quoteOutput <> residualValue + + executorRewardOut = + TxOutCandidate + { txOutCandidateAddress = rewardAddr + , txOutCandidateValue = Ada.lovelaceValueOf (exFee - fee) + , txOutCandidateDatum = EmptyDatum + , txOutCandidateRefScript = Nothing + } + + txCandidate = TxCandidate + { txCandidateInputs = inputs + , txCandidateRefIns = refInputs + , txCandidateOutputs = [nextPoolOut, rewardOut, executorRewardOut] + , txCandidateValueMint = mempty + , txCandidateMintInputs = mempty + , txCandidateChangePolicy = Just $ ReturnTo $ pubKeyHashAddress executorPkh Nothing + , txCandidateValidRange = Interval.always + , txCandidateSigners = mempty + } + + Right (txCandidate, pp, exFee - fee) + +runDepositUnsafe' + :: PaymentPubKeyHash + -> PoolValidator V1 + -> DepositValidator V1 + -> [FullTxOut] + -> OnChain Deposit + -> (FullTxOut, Pool) + -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) +runDepositUnsafe' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOut, pool@Pool{..}) = do + when (depositPoolId /= poolId) (Left $ PoolMismatch depositPoolId poolId) + let + fee = 300000 + inputs = mkOrderInputs P.Deposit pv dv (PoolIn poolOut) (OrderIn depositOut) + + (inX, inY) = + bimap entryAmount entryAmount $ + if assetEntryClass (fst depositPair) == unCoin poolCoinX + then depositPair + else Data.Tuple.swap depositPair + where entryAmount (AssetEntry (_, v)) = Amount v + + exFee = unExFee depositExFee + + (netInX, netInY) + | isAda poolCoinX = (inX - retagAmount exFee - retagAmount adaCollateral, inY) + | isAda poolCoinY = (inX, inY - retagAmount exFee - retagAmount adaCollateral) + | otherwise = (inX, inY) + + (unlockedLq, (Amount changeX, Amount changeY)) = rewardLp pool (netInX, netInY) + + alignmentValue = + assetClassValue (unCoin poolCoinY) changeY + <> assetClassValue (unCoin poolCoinX) changeX + + pp@(Predicted nextPoolOut _) = applyDeposit pv pool (netInX, netInY) + + mintLqValue = assetAmountValue (AssetAmount poolCoinLq unlockedLq) + + rewardAddr = pubKeyHashAddress (PaymentPubKeyHash depositRewardPkh) depositRewardSPkh + rewardOut = + TxOutCandidate + { txOutCandidateAddress = rewardAddr + , txOutCandidateValue = rewardValue + , txOutCandidateDatum = EmptyDatum + , txOutCandidateRefScript = Nothing + } + where + initValue = fullTxOutValue depositOut + residualValue = + initValue + <> assetClassValue (unCoin poolCoinX) (negate $ unAmount netInX) -- Remove X net input + <> assetClassValue (unCoin poolCoinY) (negate $ unAmount netInY) -- Remove Y net input + <> Ada.lovelaceValueOf (negate $ unAmount exFee) -- Remove Fee + rewardValue = residualValue <> mintLqValue <> alignmentValue + + executorRewardOut = + TxOutCandidate + { txOutCandidateAddress = rewardAddr + , txOutCandidateValue = Ada.lovelaceValueOf (unAmount exFee - fee) + , txOutCandidateDatum = EmptyDatum + , txOutCandidateRefScript = Nothing + } + + txCandidate = TxCandidate + { txCandidateInputs = inputs + , txCandidateRefIns = refInputs + , txCandidateOutputs = [nextPoolOut, rewardOut, executorRewardOut] + , txCandidateValueMint = mempty + , txCandidateMintInputs = mempty + , txCandidateChangePolicy = Just $ ReturnTo $ pubKeyHashAddress executorPkh Nothing + , txCandidateValidRange = Interval.always + , txCandidateSigners = mempty + } + + Right (txCandidate, pp, unAmount exFee - fee) + +runRedeemUnsafe' + :: PaymentPubKeyHash + -> PoolValidator V1 + -> RedeemValidator V1 + -> [FullTxOut] + -> OnChain Redeem + -> (FullTxOut, Pool) + -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) +runRedeemUnsafe' executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, pool@Pool{..}) = do + when (redeemPoolId /= poolId) (Left $ PoolMismatch redeemPoolId poolId) + let + fee = 300000 + + inputs = mkOrderInputs P.Redeem pv rv (PoolIn poolOut) (OrderIn redeemOut) + + pp@(Predicted nextPoolOut _) = applyRedeem pv pool redeemLqIn + + burnLqValue = assetClassValue (unCoin redeemLq) (negate $ unAmount redeemLqIn) + + exFee = unAmount $ unExFee redeemExFee + + rewardAddr = pubKeyHashAddress (PaymentPubKeyHash redeemRewardPkh) redeemRewardSPkh + rewardOut = + TxOutCandidate + { txOutCandidateAddress = rewardAddr + , txOutCandidateValue = rewardValue + , txOutCandidateDatum = EmptyDatum + , txOutCandidateRefScript = Nothing + } + where + (outX, outY) = sharesAmount pool redeemLqIn + initValue = fullTxOutValue redeemOut + negatedExFe = Ada.lovelaceValueOf . negate $ exFee + residualValue = + initValue + <> burnLqValue + <> negatedExFe -- Remove LQ input and ExFee + + rewardValue = assetAmountValue outX <> assetAmountValue outY <> residualValue + + executorRewardOut = + TxOutCandidate + { txOutCandidateAddress = rewardAddr + , txOutCandidateValue = Ada.lovelaceValueOf (exFee - fee) + , txOutCandidateDatum = EmptyDatum + , txOutCandidateRefScript = Nothing + } + + txCandidate = TxCandidate + { txCandidateInputs = inputs + , txCandidateRefIns = refInputs + , txCandidateOutputs = [nextPoolOut, rewardOut, executorRewardOut] + , txCandidateValueMint = mempty + , txCandidateMintInputs = mempty + , txCandidateChangePolicy = Just $ ReturnTo $ pubKeyHashAddress executorPkh Nothing + , txCandidateValidRange = Interval.always + , txCandidateSigners = mempty + } + + Right (txCandidate, pp, exFee - fee) + +runSwapWithDebug' :: PaymentPubKeyHash -> PoolValidator V1 -> SwapValidator V1 @@ -121,7 +323,7 @@ runSwap' -> OnChain Swap -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) -runSwap' executorPkh pv sv refInputs (OnChain swapOut s@Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do +runSwapWithDebug' executorPkh pv sv refInputs (OnChain swapOut s@Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do let inputs = mkOrderInputs P.Swap pv sv (PoolIn poolOut) (OrderIn swapOut) pp@(Predicted nextPoolOut _) = applySwap pv pool (AssetAmount swapBase swapBaseIn) @@ -177,7 +379,7 @@ runSwap' executorPkh pv sv refInputs (OnChain swapOut s@Swap{swapExFee=ExFeePerT Right (txCandidate, pp, fullSwapInfo) -runDeposit' +runDepositWithDebug' :: PaymentPubKeyHash -> PoolValidator V1 -> DepositValidator V1 @@ -185,7 +387,7 @@ runDeposit' -> OnChain Deposit -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) -runDeposit' executorPkh pv dv refInputs (OnChain depositOut d@Deposit{..}) (poolOut, pool@Pool{..}) = do +runDepositWithDebug' executorPkh pv dv refInputs (OnChain depositOut d@Deposit{..}) (poolOut, pool@Pool{..}) = do let initDepositInfo = DepositInfo { deposit = d @@ -265,7 +467,7 @@ runDeposit' executorPkh pv dv refInputs (OnChain depositOut d@Deposit{..}) (pool Right (txCandidate, pp, finalDepositInfo) -runRedeem' +runRedeemWithDebug' :: PaymentPubKeyHash -> PoolValidator V1 -> RedeemValidator V1 @@ -273,7 +475,7 @@ runRedeem' -> OnChain Redeem -> (FullTxOut, Pool) -> Either (OrderExecErr, OrderInfo) (TxCandidate, Predicted Pool, OrderInfo) -runRedeem' executorPkh pv rv refInputs (OnChain redeemOut r@Redeem{..}) (poolOut, pool@Pool{..}) = do +runRedeemWithDebug' executorPkh pv rv refInputs (OnChain redeemOut r@Redeem{..}) (poolOut, pool@Pool{..}) = do let initRedeemInfo = RedeemInfo { redeem = r diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 8b865f71..120d5e2f 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -7,7 +7,7 @@ import RIO (isJust) import Data.Bifunctor (first) import Data.Map (Map) import qualified Data.Map as Map -import Data.Maybe (fromMaybe, catMaybes) +import Data.Maybe (catMaybes) import Data.Functor ((<&>)) import Data.Set (Set) import Data.Ratio @@ -16,6 +16,37 @@ import Cardano.Api import Cardano.Api.Shelley (ProtocolParameters(..), PoolId, ReferenceScript (..), fromShelleyLovelace) import qualified Cardano.Ledger.Coin as Ledger import Debug.Trace +import Control.FromSum + +makeTransactionBodyBalanceUnsafe + :: forall era. + IsShelleyBasedEra era + => TxBodyContent BuildTx era + -> AddressInEra era -- ^ Change address + -> Integer + -> Either TxBodyErrorAutoBalance (BalancedTxBody era) +makeTransactionBodyBalanceUnsafe txbodycontent changeaddr changeValue = do + let era' = cardanoEra + retColSup <- maybeToEitherOr (totalAndReturnCollateralSupportedInEra era') TxBodyErrorMissingParamMinUTxO -- incorrect error + let + fee = 300000 + reqAmt = 1300000 + totalCollateral = TxTotalCollateral retColSup (Lovelace reqAmt) + (retColl, reqCol) = + ( TxReturnCollateral + retColSup + (TxOut changeaddr (lovelaceToTxOutValue (Lovelace reqAmt)) TxOutDatumNone ReferenceScriptNone) + , totalCollateral + ) + explicitTxFees <- first (const TxBodyErrorByronEraNotSupported) $ + txFeesExplicitInEra era' + txBody0 <- first TxBodyError $ makeTransactionBody txbodycontent + { txOuts = txOuts txbodycontent + , txFee = TxFeeExplicit explicitTxFees $ Lovelace fee + , txReturnCollateral = retColl + , txTotalCollateral = reqCol + } + return (BalancedTxBody txBody0 (TxOut changeaddr (lovelaceToTxOutValue (Lovelace changeValue)) TxOutDatumNone ReferenceScriptNone) (Lovelace fee)) makeTransactionBodyAutoBalance :: forall era mode. @@ -258,9 +289,9 @@ makeTransactionBodyAutoBalance eraInMode systemstart history pparams | otherwise = do let chargeBoxWillBeMerged = isJust $ find (\(TxOut boxAddr _ _ _) -> boxAddr == changeaddr) outs if chargeBoxWillBeMerged - then + then Right () - else + else case checkMinUTxOValue (TxOut changeaddr balance TxOutDatumNone ReferenceScriptNone) pparams of Left (TxBodyErrorMinUTxONotMet txOutAny minUTxO) -> Left $ TxBodyErrorAdaBalanceTooSmall txOutAny minUTxO (txOutValueToLovelace balance) diff --git a/submit-api/src/SubmitAPI/Internal/Transaction.hs b/submit-api/src/SubmitAPI/Internal/Transaction.hs index 3e9ab19b..d6172299 100644 --- a/submit-api/src/SubmitAPI/Internal/Transaction.hs +++ b/submit-api/src/SubmitAPI/Internal/Transaction.hs @@ -60,6 +60,27 @@ buildBalancedTx SystemEnv{..} refScriptsMap network defaultChangeAddr collateral absorbBalancingError (Left e) = throwM $ BalancingError $ T.pack $ displayError e absorbBalancingError (Right a) = pure a +buildBalancedTxUnsafe + :: (MonadThrow f) + => SystemEnv + -> Map P.Script C.TxIn + -> NetworkId + -> Sdk.ChangeAddress + -> Set.Set Sdk.FullCollateralTxIn + -> Sdk.TxCandidate + -> Integer + -> f (BalancedTxBody BabbageEra) +buildBalancedTxUnsafe SystemEnv{..} refScriptsMap network defaultChangeAddr collateral txc@Sdk.TxCandidate{..} changeValue = do + txBody <- buildTxBodyContent pparams network refScriptsMap collateral txc + changeAddr <- absorbError $ case txCandidateChangePolicy of + Just (Sdk.ReturnTo addr) -> Interop.toCardanoAddressInEra network addr + _ -> Interop.toCardanoAddressInEra network $ Sdk.getAddress defaultChangeAddr + absorbBalancingError $ + Balancing.makeTransactionBodyBalanceUnsafe txBody changeAddr changeValue + where + absorbBalancingError (Left e) = throwM $ BalancingError $ T.pack $ displayError e + absorbBalancingError (Right a) = pure a + estimateTxFee :: (MonadThrow f) => ProtocolParameters diff --git a/submit-api/submit-api.cabal b/submit-api/submit-api.cabal index feaf36ec..f959a94c 100644 --- a/submit-api/submit-api.cabal +++ b/submit-api/submit-api.cabal @@ -90,6 +90,7 @@ library cardano-slotting, cardano-api, mtl, + from-sum, plutus-ledger, bytestring, aeson, @@ -134,8 +135,10 @@ test-suite submit-api-tests , base , HUnit , hedgehog + , rio , tasty , tasty-hunit + , transformers , tasty-hedgehog , aeson , text @@ -158,6 +161,9 @@ test-suite submit-api-tests , cardano-tx , network-api , wallet-api + , cardano-cli , serialise , cardano-dex-contracts-offchain , cardano-ledger-alonzo + , memory + , quickblue \ No newline at end of file diff --git a/submit-api/test/Main.hs b/submit-api/test/Main.hs index 3b4b316c..86002f3a 100644 --- a/submit-api/test/Main.hs +++ b/submit-api/test/Main.hs @@ -1,19 +1,497 @@ +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE RankNTypes #-} module Main where import qualified Data.Text.Encoding as E import Test.Tasty import Test.Tasty.HUnit +import PlutusTx.Builtins.Internal hiding (fst) +import PlutusTx +import ErgoDex.Contracts.Pool +import qualified Data.ByteString as BS +import qualified Data.ByteString.Base16 as Hex +import qualified Plutus.V2.Ledger.Contexts as PV2L +import qualified Data.Text.Encoding as T +import qualified Data.ByteString.Short as SBS +import qualified Data.ByteString.Lazy as LBS +import Codec.Serialise (serialise, deserialise) +import Data.Aeson as Json ( encode ) +import qualified Data.Text.Encoding as E +import qualified Data.ByteString.Base16 as Hex +import Plutus.Script.Utils.V2.Scripts +import qualified Plutus.V2.Ledger.Api as PlutusV2 +import qualified Data.Text as T +import Plutus.V1.Ledger.Value (AssetClass(..), assetClassValueOf, flattenValue, CurrencySymbol(..), TokenName(..)) +import Plutus.V1.Ledger.Api +import ErgoDex.PValidators +import Cardano.CLI.Shelley.Run.Transaction +import Cardano.Api (writeFileTextEnvelope, Error(displayError), ScriptDataJsonSchema (ScriptDataJsonDetailedSchema), InAnyCardanoEra (InAnyCardanoEra), EraInMode (BabbageEraInCardanoMode), IsShelleyBasedEra) +import Cardano.Api.Shelley (PlutusScript (..), PlutusScriptV2, serialiseToRawBytes, TxInMode (TxInMode)) +import qualified Plutus.V1.Ledger.Scripts as Plutus +import qualified Cardano.Api as C +import qualified Plutus.Script.Utils.V2.Address as PV2 +import Cardano.Api (scriptDataToJson) +import Data.ByteArray.Encoding (Base(..), convertToBase) +import Cardano.Api.Shelley ( fromPlutusData ) +import WalletAPI.TrustStore (importTrustStoreFromCardano, SecretFile (SecretFile), KeyPass (KeyPass), mkTrustStore) +import qualified Ledger as PV2 +import CardanoTx.Address (readShellyAddress) +import WalletAPI.Vault (Vault (getPaymentKeyHash), mkVault) +import qualified Explorer.Types as Explorer +import qualified Plutus.V1.Ledger.Api as P +import Cardano.Ledger.Alonzo.Data (Data(..)) +import qualified Plutus.V1.Ledger.Bytes as Data +import ErgoDex.Contracts.Proxy.Deposit (DepositConfig(..)) +import Plutus.V2.Ledger.Tx (OutputDatum(..)) +import Ledger.Ada (lovelaceValueOf) +import Ledger.Value (assetClassValue) +import qualified PlutusTx.AssocMap as Map +import qualified Plutus.V1.Ledger.Interval as Interval +import ErgoDex.Contracts.Proxy.Order (OrderRedeemer(OrderRedeemer), OrderAction (Refund)) +import Control.Monad.IO.Class (MonadIO(liftIO)) +import RIO (lift, (&)) +import Control.Monad.Trans.Except (runExceptT) -import Spec.Transaction -import System.Exit (exitFailure) -import Control.Monad (unless) + +data TokenInfo = TokenInfo + { curSymbol :: String + , tokenName :: String + } deriving Eq + +instance Show TokenInfo where + show TokenInfo{..} = curSymbol ++ "." ++ tokenName + +adaTokenInfo :: TokenInfo +adaTokenInfo = TokenInfo "" "" + +isAda :: TokenInfo -> Bool +isAda ti = ti == adaTokenInfo + +data PoolInfo = PoolInfo + { name :: String + , tokenX :: TokenInfo + , tokenY :: TokenInfo + , tokenNft :: TokenInfo + , tokenLP :: TokenInfo + , lqBound :: Integer + , authKeys :: [String] + , threshold :: Integer + , initialXQty :: Integer + , initialYQty :: Integer + , allowStaking :: Bool + } + +lqInitQty = 9223372036854775807 + +workDir :: String +workDir = "/home/bromel/test-mainnet-pools/" + +mintingPolicyNamePostfix :: String +mintingPolicyNamePostfix = "_mintingPolicy" + +stakingScriptNamePostfix :: String +stakingScriptNamePostfix = "_stakingScript" + +poolDatumPostfix :: String +poolDatumPostfix = "_poolDatum" + +uplcExtension :: String +uplcExtension = ".uplc" + +plutusExtension :: String +plutusExtension = ".plutus" + +jsonExtension :: String +jsonExtension = ".json" + +uplcPolicyPath :: PoolInfo -> String +uplcPolicyPath PoolInfo{..} = workDir ++ name ++ mintingPolicyNamePostfix ++ uplcExtension + +plutusPolicyPath :: PoolInfo -> String +plutusPolicyPath PoolInfo{..} = workDir ++ name ++ mintingPolicyNamePostfix ++ plutusExtension + +uplcStakingScriptPath :: String -> String +uplcStakingScriptPath pkh = workDir ++ pkh ++ stakingScriptNamePostfix ++ uplcExtension + +plutusStakingScriptPath :: String -> String +plutusStakingScriptPath pkh = workDir ++ pkh ++ stakingScriptNamePostfix ++ plutusExtension + +poolDatumPath :: PoolInfo -> String +poolDatumPath PoolInfo{..} = workDir ++ name ++ poolDatumPostfix ++ jsonExtension + +poolMainnetServerDatumPath :: String -> PoolInfo -> String +poolMainnetServerDatumPath mainnetWorkDir PoolInfo{..} = mainnetWorkDir ++ name ++ poolDatumPostfix ++ jsonExtension + +dq = "\"" main :: IO () -main = defaultMain tests +main = do + txFile + +txFile :: IO () +txFile = do + txFinal <- runExceptT $ readFileTx "/home/bromel/projects/cardano-dex-sdk-haskell/submit-api/test/txNormal.signed" + liftIO $ print (show (eraseLeft txFinal)) + pure () + +eraseRight :: Either a b -> Either a () +eraseRight (Right _) = Right () +eraseRight (Left l) = Left l + +eraseLeft :: Either a b -> Either () b +eraseLeft (Right l) = Right l +eraseLeft (Left _) = Left () + +test3 = do + deposit <- depositValidator + + let + depositAddress = PV2.mkValidatorAddress deposit + + inputAda = lovelaceValueOf 11929173 + + snekAssetClass = tokenInfo2CS $ TokenInfo "279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3f" "534e454b" + inputSnek = assetClassValue snekAssetClass 10000 + + poolNft = tokenInfo2CS $ TokenInfo "4a27465112a39464e6dd5ee470c552ebb3cb42925d5ec04014967908" "534E454B5F4144415F4E4654" + poolLp = tokenInfo2CS $ TokenInfo "7bddf2c27f257eeeef3e892758b479e09c89a73642499797f2a97f3c" "534E454B5F4144415F4C51" + + inputDatum = DepositConfig + { poolNft = poolNft + , tokenA = tokenInfo2CS adaTokenInfo + , tokenB = snekAssetClass + , tokenLp = poolLp + , exFee = 1500000 + , rewardPkh = PubKeyHash $ BuiltinByteString $ mkByteString $ T.pack "719bee424a97b58b3dca88fe5da6feac6494aa7226f975f3506c5b25" + , stakePkh = Just $ PubKeyHash $ BuiltinByteString $ mkByteString $ T.pack "7846f6bb07f5b2825885e4502679e699b4e60a0c4609a46bc35454cd" + , collateralAda = 0 + } + + refundInput = PV2L.TxInInfo { + txInInfoOutRef = TxOutRef { + txOutRefId = TxId $ BuiltinByteString $ mkByteString $ T.pack "818804916028d33eef09eb2c5dac47d2c38094eeba21daac65c1627afd82884d", + txOutRefIdx = 0 + }, + txInInfoResolved = PlutusV2.TxOut { + txOutAddress = depositAddress, + txOutValue = inputAda <> inputSnek, + txOutDatum = OutputDatum $ Datum $ toBuiltinData inputDatum, + txOutReferenceScript = Just $ scriptHash (unValidatorScript deposit) + } + } + + unknownReferenceInput = refundInput + + depositRefInputAda = lovelaceValueOf 1226634 + + depositReferenceInput = PV2L.TxInInfo { + txInInfoOutRef = TxOutRef { + txOutRefId = TxId $ BuiltinByteString $ mkByteString $ T.pack "fc9e99fd12a13a137725da61e57a410e36747d513b965993d92c32c67df9259a", + txOutRefIdx = 0 + }, + txInInfoResolved = PlutusV2.TxOut { + txOutAddress = Address + (PubKeyCredential $ PubKeyHash $ BuiltinByteString $ mkByteString $ T.pack "a6e1973e53af80c473cafb288235864f66240d305d9ce9df992125ea") + (Just $ StakingHash $ PubKeyCredential $ PubKeyHash $ BuiltinByteString $ mkByteString $ T.pack "3f70ef0595dbc750d6575d814af8da0cdb53e778dae4895e85ef239e"), + txOutValue = depositRefInputAda, + txOutDatum = NoOutputDatum, + txOutReferenceScript = Nothing + } + } + + userTxOutAda = lovelaceValueOf 10452541 + + userTxOut = PlutusV2.TxOut { + txOutAddress = Address + (PubKeyCredential $ PubKeyHash $ BuiltinByteString $ mkByteString $ T.pack "21bcdaa800d642aa94d62ab43524de3481a7790b69172e7e3ef882ec") + (Just $ StakingHash $ PubKeyCredential $ PubKeyHash $ BuiltinByteString $ mkByteString $ T.pack "7846f6bb07f5b2825885e4502679e699b4e60a0c4609a46bc35454cd"), + txOutValue = userTxOutAda <> inputSnek, + txOutDatum = NoOutputDatum, + txOutReferenceScript = Nothing + } + + spendingRef = TxOutRef { + txOutRefId = TxId $ BuiltinByteString $ mkByteString $ T.pack "818804916028d33eef09eb2c5dac47d2c38094eeba21daac65c1627afd82884d", + txOutRefIdx = 0 + } + + orderRedeemer = toBuiltinData $ OrderRedeemer 0 0 0 Refund + + txId = TxId $ BuiltinByteString $ mkByteString $ T.pack "349709cb602d3ae5405e8fba4888c4f31706345c183014efe1b5388447aadca8" + + ctx = PV2L.TxInfo + { txInfoInputs = [refundInput] -- ^ Transaction inputs + , txInfoReferenceInputs = [unknownReferenceInput, depositReferenceInput] -- ^ Transaction reference inputs + , txInfoOutputs = [userTxOut] -- ^ Transaction outputs + , txInfoFee = lovelaceValueOf 1476632 -- ^ The fee paid by this transaction. + , txInfoMint = lovelaceValueOf 0 -- ^ The 'Value' minted by this transaction. + , txInfoDCert = [] -- ^ Digests of certificates included in this transaction + , txInfoWdrl = Map.empty -- ^ Withdrawals + , txInfoValidRange = Interval.always -- ^ The valid range for the transaction. + , txInfoSignatories = [ + PubKeyHash $ BuiltinByteString $ mkByteString $ T.pack "21bcdaa800d642aa94d62ab43524de3481a7790b69172e7e3ef882ec", + PubKeyHash $ BuiltinByteString $ mkByteString $ T.pack "719bee424a97b58b3dca88fe5da6feac6494aa7226f975f3506c5b25" -- collateral signature + datum + ] -- ^ Signatures provided with the transaction, attested that they all signed the tx + , txInfoRedeemers = Map.fromList [(Spending spendingRef, Redeemer orderRedeemer)] + , txInfoData = Map.empty + , txInfoId = txId + -- ^ Hash of the pending transaction (excluding witnesses) + } + + print depositAddress + + print $ show $ toBuiltinData ctx + -- print $ readShellyAddress "addr1q9cehmjzf2tmtzeae2y0uhdxl6kxf992wgn0ja0n2pk9kftcgmmtkpl4k2p93p0y2qn8ne5eknnq5rzxpxjxhs652nxsqwq3mt" + pure () + +test123 = do + let + trustStore = mkTrustStore @_ @C.PaymentKey C.AsPaymentKey (SecretFile "/home/bromel/projects/cardano-dex-sdk-haskell/wallet1TS.json") + vault = mkVault trustStore $ KeyPass $ T.pack "test1234" :: Vault IO + + mkPCred = Explorer.PaymentCred . T.decodeUtf8 . convertToBase Base16 . serialiseToRawBytes + + pkh <- getPaymentKeyHash vault + + let + address = (mkPCred pkh) + + print address + + -- defaultMain tests + let + wallet1PubKeyHash = "9b697975d20d891cc1713a3c4d3f881490880a780019337037ef079c" + wallet2PubKeyHash = "a6e1973e53af80c473cafb288235864f66240d305d9ce9df992125ea" + + mintingSignatures = [wallet1PubKeyHash, wallet2PubKeyHash] + + signaturesThreshold = 2 + + lqQty = 9223372036854775807 + + rabbitPool = PoolInfo + { name = "rabbitPool" + , tokenX = adaTokenInfo + , tokenY = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "726162626974" + , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "7261626269745f6164615f6e6674" + , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "7261626269745f6164615f6c71" + , lqBound = 5000000 + , authKeys = [] + , threshold = signaturesThreshold + , initialXQty = 15000000 + , initialYQty = 15000000 + , allowStaking = True + } + goldfishPool = PoolInfo + { name = "goldfishPool" + , tokenX = adaTokenInfo + , tokenY = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "676F6C6466697368" + , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "676f6c64666973685f6164615f6e6674" + , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "676f6c64666973685f6164615f6c71" + , lqBound = 5000000 + , authKeys = [] + , threshold = signaturesThreshold + , initialXQty = 15000000 + , initialYQty = 15000000000 + , allowStaking = True + } + rabbitFoldfishPool = PoolInfo + { name = "rabbitGoldfishPool" + , tokenX = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "726162626974" + , tokenY = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "676F6C6466697368" + , tokenNft = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "7261626269745F676F6C64666973685F6E6674" + , tokenLP = TokenInfo "5ac3d4bdca238105a040a565e5d7e734b7c9e1630aec7650e809e34a" "7261626269745F676F6C64666973685F6C71" + , lqBound = 5000000 + , authKeys = [] + , threshold = signaturesThreshold + , initialXQty = 1000000 + , initialYQty = 1000000 + , allowStaking = False + } + pools = [rabbitPool, goldfishPool, rabbitFoldfishPool] + + -- Step 1. Converting uplc produced by cardano-contracts onchain repo to plutus + + -- convertUplcMintingPolicy `traverse` pools + + -- Step 1.5 (optional) + + -- convertUplcStakingScript wallet2PubKeyHash + + -- Step 2. Datums creation. Will produce output for cardano-cli. Also necessary to copy all datums from test to mainnet machine + + -- createDatumJson `traverse` pools + + -- Step 3. Require manual steps for creation staking certs + -- Also we cannot retrive original min utxo value for inline datums. So, set it manually + -- More Also, we cannot determine change. So, set it manually too + + -- let + -- poolAddressWithStaking = "addr1x9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evkqwx9ghwy6quk2fhu5g0ek8rth7z4zxr5ev975ph34q5fsq2amyd" + -- poolAddress = "addr1w9cgs59t2hr5sphrv4gfuzxl323akly5z57qv07hq266evsg37dfw" + -- -- on mainnet machine + -- origDatumWorkDir = "/root/plutus-scripts-for-mainnet/test-pools/datums/" + + -- bootstrapAddressString = "" + -- bootstrapAddressVKeyPath = "" + + -- minUtxoValueForPool = 3223960 + + -- res = (\pi -> poolCLICreationOutput pi poolAddressWithStaking poolAddress minUtxoValueForPool origDatumWorkDir) `fmap` pools + + -- folded = foldr (\acc nextPool -> acc ++ "\n" ++ nextPool) "" res + + -- putStr folded + + -- end + + --print $ readShellyAddress "addr1v8g2jvkr55vsqlteuu5x0052lgj3ak0ev5vs74dyu0fgahg92dth0" + + -- print $ readShellyAddress "addr1qxupdk69sdemdx80far0tsvrydz7zj67ydzxxujmv9srj3tcgmmtkpl4k2p93p0y2qn8ne5eknnq5rzxpxjxhs652nxsy8ugdz" + + print $ readShellyAddress "addr1qxy8aeh2e77hgtrevn4p459m7qsqswfnkxck26g2cuanh2ncgmmtkpl4k2p93p0y2qn8ne5eknnq5rzxpxjxhs652nxsqf8en8" + print $ readShellyAddress "addr1q9cehmjzf2tmtzeae2y0uhdxl6kxf992wgn0ja0n2pk9kftcgmmtkpl4k2p93p0y2qn8ne5eknnq5rzxpxjxhs652nxsqwq3mt" + + -- let testData = "hgCYrxoAAyNhGQMsAQEZA+gZAjsAARkD6BlecQQBGQPoGCAaAAHKdhko6wQZWdgYZBlZ2BhkGVnYGGQZWdgYZBlZ2BhkGVnYGGQYZBhkGVnYGGQZTFEYIBoAAqz6GCAZtVEEGgADYxUZAf8AARoAAVw1GCAaAAeXdRk29AQCGgAC/5QaAAbqeBjcAAEBGQPoGW/2BAIaAAO9CBoAA07FGD4BGgAQLg8ZMSoBGgADLoAZAaUBGgAC2ngZA+gZzwYBGgABOjQYIBmo8RggGQPoGCAaAAE6rAEZ4UMEGQPoChoAAwIZGJwBGgADAhkYnAEaAAMgfBkB2QEaAAMwABkB/wEZzPMYIBn9QBggGf/VGCAZWB4YIBlAsxggGgABKt8YIBoAAv+UGgAG6ngY3AABARoAAQ+SGS2nAAEZ6rsYIBoAAv+UGgAG6ngY3AABARoAAv+UGgAG6ngY3AABARoAEbIsGgAF/d4AAhoADFBOGXcSBBoAHWr2GgABQlsEGgAEDGYABAAaAAFPqxggGgADI2EZAywBARmg3hggGgADPXYYIBl59BggGX+4GCAZqV0YIBl99xggGZWqGCAaAiOszAoaA3T2kxlKHwoaAlFehBmAswqCGgCYloAbAAAAAhhxGgBZBHFZBG4BAAAyMjIyMjIyMjIyMjIyMjIyMjIyMjIyIiUzMBUyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMlMzAvM3DpABABCZGRkZGSmZgaGbh1MzA0M3Dm60wNTA2ARSAAFIAAUgAkgABUzAlM3DmYFQBhgagPJABCpmBKZuvMDUAYwNQChUzAlM3DmZgZkRKZmBiACIAQmYAZm4AAJIAIwOQAUgAAFUgBBUzAlUzMDQzcOAEACKURUzMDQzcQAEACJmZmYEYB5gagOAAgBABgCiZmZmBGAeYGoDoAQAIAgAombiVMzA0M3EgBAAiAEIAJmBUAeYGoDYmZEZkYGxEpmYGYAIpQFTMwOTN15gdAAgBilETACMDsAE3UgAgBG6wwNTIwNzA3MDcwNzA3ABMDYBY3XGBqAyZmZmBGAQYGgDYAQAhutMDQBk3WmBoYGoC5mZmYEQA5gZgNgBABm60wMwGDdaYGZgaALGYE4BJgZAMmYEwBBgYgMmbgUg/v//////////ATMCUAcwMAFhYwMgAjApABN1RgWmBcAubqzIwLTAuMC8AEwLDAtABMC0AEzAmN1pgVADgFG6syMCowKzAsABMCkwKgATAqABMwIzdaYE4AoA5mRGRkZKZmBUZGRkpmYFpm4dIAIAITIyMlMzAwM3DpAAABClATN15unAEN04AJgZgBGBUACbqgBxMjIyUzMDAzcOkAEAEKUBM3Xm6cAQ3TgAmBmAEYFQAJuqAHMDAAIwJwATdUACIAQsZGRkZGSmZgXGbh0gAAAhMjIyMlMzAyM3DpAAABCZGRkZKZmBsZuHSACACFhM3SpAAAAmByAEYGAAJuqABMDMAEWMDUAIwLAATdUACYF4AImbpUgAgKTAxACMCgAE3VAAmBWYFhgWgAmBUYFgApurMjIyUzMCszcOkAEAELCpmYFZm483XGBYACAMJgWGBaYFwA4sYFwARgSgAm6oAEyMCkwKwATAoMCoAM3XGBMAUYEwBJmBCbrTAlABAEMCUAEwJAATAkAON1hgQgBG6wwIAAjAgMCAAEwIDAeAIMB4AEwHQATAcABMBsAEwGgATAZABMBkAQwGAARSYWIiIiM3EmbgzNwRm4EAQAMAIAEzANAGAFIiIiMjNwZm4JTMwFzIyUzAKM3Hm64wGjAbACN1xgNGA2ACJm483XGA0AEbrjAaABMBsAswGgBhM3AmbgQAQAwAhABAEAFMwDABgBSIzMBEAIAEAMUoGbpUgADMAE3UgBGYAJupACAIV0CRAQAiMjMwBAAzdcYBwAJuuMA4wDwATAPABIiMzMAQAJIAAjMzAFACSAAdabqwAQAyMAI3UgAkREZgFESmZgDgAiAKKmZgGmbrzAJMA4AEAYTAEMBEwDgARMAIwDwAQAVVz6XrgVXOkSmZgCmbiAAkgABYTMAMAIAEwASIlMzAFM3DgBJAACYAwAImYAZm4EAJIAIwBwASMjACIzACACABIwAiMwAgAgAVc0roVdERgBG6oAFVc8Gf2Hmf2HmfWBxKJ0ZREqOUZObdXuRwxVLrs8tCkl1ewEAUlnkITFNORUtfQURBX05GVP/YeZ9AQP/YeZ9YHCeckJ80jlM9pYCImPh/mhS7LD37uszNYx2Sej9EU05FS//YeZ9YHHvd8sJ/JX7u7z6JJ1i0eeCciac2QkmXl/KpfzxLU05FS19BREFfTFH/GgAW42BYHHGb7kJKl7WLPcqI/l2m/qxklKpyJvl181BsWyXYeZ9YHHhG9rsH9bKCWIXkUCZ55pm05goMRgmka8NUVM3/AP/YeZ8AAAAB/9h5n9h5n5/YeZ/YeZ/YeZ9YIOJq2TLOwizh6CSdIPMY8ym12pvIsRHWLadv/bMz7PmX/wD/2Hmf2Hmf2HqfWBwHXgnrD6ieHcNGkbPFan9DfmCsXqZ7M48uF24g/9h6gP+iQKFAGgC2NddYHCeckJ80jlM9pYCImPh/mhS7LD37uszNYx2Sej+hRFNORUsZJxDYe5/YeZ/YeZ9YHEonRlESo5Rk5t1e5HDFUuuzy0KSXV7AQBSWeQhMU05FS19BREFfTkZU/9h5n0BA/9h5n1gcJ5yQnzSOUz2lgIiY+H+aFLssPfu6zM1jHZJ6P0RTTkVL/9h5n1gce93ywn8lfu7vPoknWLR54JyJpzZCSZeX8ql/PEtTTkVLX0FEQV9MUf8aABbjYFgccZvuQkqXtYs9yoj+Xab+rGSUqnIm+XXzUGxbJdh5n1gceEb2uwf1soJYheRQJnnmmbTmCgxGCaRrw1RUzf8A///YeoD///+f2Hmf2Hmf2HmfWCDiatkyzsIs4egknSDzGPMptdqbyLER1i2nb/2zM+z5l/8A/9h5n9h5n9h6n1gcB14J6w+onh3DRpGzxWp/Q35grF6mezOPLhduIP/YeoD/okChQBoAtjXXWBwnnJCfNI5TPaWAiJj4f5oUuyw9+7rMzWMdkno/oURTTkVLGScQ2Huf2Hmf2HmfWBxKJ0ZREqOUZObdXuRwxVLrs8tCkl1ewEAUlnkITFNORUtfQURBX05GVP/YeZ9AQP/YeZ9YHCeckJ80jlM9pYCImPh/mhS7LD37uszNYx2Sej9EU05FS//YeZ9YHHvd8sJ/JX7u7z6JJ1i0eeCciac2QkmXl/KpfzxLU05FS19BREFfTFH/GgAW42BYHHGb7kJKl7WLPcqI/l2m/qxklKpyJvl181BsWyXYeZ9YHHhG9rsH9bKCWIXkUCZ55pm05goMRgmka8NUVM3/AP//2HqA///YeZ/YeZ/YeZ9YIPyemf0SoToTdyXaYeV6QQ42dH1RO5ZZk9ksMsZ9+SWa/wD/2Hmf2Hmf2HmfWBym4Zc+U6+AxHPK+yiCNYZPZiQNMF2c6d+ZISXq/9h5n9h5n9h5n1gcP3DvBZXbx1DWV12BSvjaDNtT53ja5Ilehe8jnv////+hQKFAGgC7K2TYeYDYeZ9YHAdeCesPqJ4dw0aRs8Vqf0N+YKxepnszjy4XbiD/////n9h5n9h5n9h5n1gcIbzaqADWQqqU1iq0NSTeNIGneQtpFy5+PviC7P/YeZ/YeZ/YeZ9YHHhG9rsH9bKCWIXkUCZ55pm05goMRgmka8NUVM3/////okChQBoAn5uEWBwnnJCfNI5TPaWAiJj4f5oUuyw9+7rMzWMdkno/oURTTkVLGScQ2HmA2HqA//+hQKFAGgAWmlOhQKFAAICg2Hmf2Hmf2HmA2HqA/9h5n9h7gNh6gP//n1gcIbzaqADWQqqU1iq0NSTeNIGneQtpFy5+PviC7FgccZvuQkqXtYs9yoj+Xab+rGSUqnIm+XXzUGxbJf+h2Hqf2Hmf2HmfWCDiatkyzsIs4egknSDzGPMptdqbyLER1i2nb/2zM+z5l/8A///YeZ8AAAAB/6DYeZ9YIDMW4vM4hWi8LBR8kV4+xSzqkd2A8PJeMjwpxJhhd4zB///Yep/YeZ/YeZ9YIOJq2TLOwizh6CSdIPMY8ym12pvIsRHWLadv/bMz7PmX/wD/////gggA" + -- plutusData = Data.from testData + + -- pool <- poolValidator + -- print (PV2.mkValidatorAddress pool) + -- swap <- swapValidator + -- print (PV2.mkValidatorAddress swap) + -- deposit <- depositValidator + -- print (PV2.mkValidatorAddress deposit) + -- redeem <- redeemValidator + -- print (PV2.mkValidatorAddress redeem) + + pure () + +-- poolDatum = PoolConfig spectrumTokenNFTClass spectrumTokenAClass spectrumTokenBClass spectrumTokenLPClass 995 + +-- poolDatumData = toData poolDatum + +-- datumStr = (T.decodeUtf8 . Hex.encode $ (LBS.toStrict $ serialise $ poolDatumData)) + +--- Pool creation stuff --- + +-- return cardano-cli string for pool and lp charge for user +poolCLICreationOutput :: PoolInfo -> String -> String -> Integer -> String -> String +poolCLICreationOutput pi@PoolInfo{..} poolAddressWithStaking poolAddress minUtxoValue origDatumWorkDir = + let + adaValue = if isAda tokenX then show initialXQty else show minUtxoValue + tokenXValue = if isAda tokenX then "" else "+" ++ dq ++ show initialXQty ++ " " ++ show tokenX ++ dq + tokenYValue = "+" ++ dq ++ show initialYQty ++ " " ++ show tokenY ++ dq + tokenNftValue = "+" ++ dq ++ "1 " ++ show tokenNft ++ dq + + charge = floor . sqrt . fromIntegral $ (initialXQty * initialYQty) + + tokenLpValue = "+" ++ dq ++ show (lqInitQty - charge) ++ " " ++ show tokenLP ++ dq + + address = if allowStaking then poolAddressWithStaking else poolAddress + + toCardanoCliPoolValue = "--tx-out " ++ address ++ "+" ++ adaValue ++ tokenXValue ++ tokenYValue ++ tokenNftValue ++ tokenLpValue ++ " \\" + + toCardanoCliDatum = "--tx-out-inline-datum-file " ++ poolMainnetServerDatumPath origDatumWorkDir pi ++ " \\" + + in toCardanoCliPoolValue ++ ['\n'] ++ toCardanoCliDatum + +--- Datum creation stuff --- + +createDatumJson :: PoolInfo -> IO () +createDatumJson pi@PoolInfo{..} = do + let + convertedNft = tokenInfo2CS tokenNft + convertedX = tokenInfo2CS tokenX + convertedY = tokenInfo2CS tokenY + convertedLP = tokenInfo2CS tokenLP + + policies <- + if allowStaking + then do + mpPolicy <- getPoolMintingPolicy pi + let + (PlutusV2.MintingPolicyHash mpPolicyHash) = mintingPolicyHash mpPolicy + mpCS = CurrencySymbol mpPolicyHash + pure [mpCS] + else pure [] + + let poolConfig = PoolConfig convertedNft convertedX convertedY convertedLP 995 policies lqBound + + writeDatumToJson pi poolConfig + pure () + +writeDatumToJson :: PoolInfo -> PoolConfig -> IO () +writeDatumToJson pi poolDatum = + LBS.writeFile (poolDatumPath pi) (Json.encode + . scriptDataToJson ScriptDataJsonDetailedSchema + . fromPlutusData + . toData + $ poolDatum ) + +--- Minting policies stuff --- + +convertUplcMintingPolicy :: PoolInfo -> IO () +convertUplcMintingPolicy pi@PoolInfo{..} = + if allowStaking + then do + bytes <- BS.readFile (uplcPolicyPath pi) + let + shortBS = SBS.toShort bytes + scr :: PlutusScript PlutusScriptV2 + scr = PlutusScriptSerialised shortBS + writeFileTextEnvelope (plutusPolicyPath pi) Nothing scr + pure () + else pure () + +getPoolMintingPolicy :: PoolInfo -> IO PV2.MintingPolicy +getPoolMintingPolicy pi = do + bytes <- BS.readFile (uplcPolicyPath pi) + let + script = deserialise (LBS.fromStrict bytes) + pure (PlutusV2.MintingPolicy script) + +--- Staking scripts stuff --- + +convertUplcStakingScript :: String -> IO () +convertUplcStakingScript pkh = do + bytes <- BS.readFile (uplcStakingScriptPath pkh) + let + shortBS = SBS.toShort bytes + scr :: PlutusScript PlutusScriptV2 + scr = PlutusScriptSerialised shortBS + writeFileTextEnvelope (plutusStakingScriptPath pkh) Nothing scr + pure () + +tokenInfo2CS :: TokenInfo -> AssetClass +tokenInfo2CS TokenInfo{..} = + let + convertedCS = CurrencySymbol $ BuiltinByteString $ mkByteString $ T.pack curSymbol + convertedTN = TokenName $ BuiltinByteString $ mkByteString $ T.pack tokenName + in AssetClass (convertedCS, convertedTN) + +textToPubKeyHash :: String -> PubKeyHash +textToPubKeyHash = PubKeyHash . BuiltinByteString . mkByteString . T.pack + +mkByteString :: T.Text -> BS.ByteString +mkByteString input = unsafeFromEither (Hex.decode . E.encodeUtf8 $ input) + +unsafeFromEither :: (Show b) => Either b a -> a +unsafeFromEither (Left err) = Prelude.error ("Err:" ++ show err) +unsafeFromEither (Right value) = value + +-- writeDataDatum2 :: FilePath -> IO () +-- writeDataDatum2 file = do +-- LBS.writeFile file (Json.encode +-- . scriptDataToJson ScriptDataJsonDetailedSchema +-- . fromPlutusData +-- . toData +-- $ (poolDatum) ) -tests = testGroup "SubmitApi" - [ buildTxBodyTests - , buildTxBodyContentTests - , buildBalancedTxTests - ] \ No newline at end of file +-- tests = testGroup "SubmitApi" +-- [ buildTxBodyTests +-- , buildTxBodyContentTests +-- , buildBalancedTxTests +-- ] \ No newline at end of file From 7d926a436f868914872614ec9aee28dfe052d5a2 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sat, 29 Jul 2023 16:11:15 +0200 Subject: [PATCH 09/21] add unsafe finalizeTx --- submit-api/src/SubmitAPI/Service.hs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/submit-api/src/SubmitAPI/Service.hs b/submit-api/src/SubmitAPI/Service.hs index 513febad..d0abbba4 100644 --- a/submit-api/src/SubmitAPI/Service.hs +++ b/submit-api/src/SubmitAPI/Service.hs @@ -79,6 +79,31 @@ finalizeTx' CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAsse signers <- mapM (\pkh -> getSigningKey pkh >>= maybe (throwM $ SignerNotFound pkh) pure) signatories pure $ Internal.signTx txb signers +finalizeTxUnsafe' + :: MonadThrow f + => CardanoNetwork f C.BabbageEra + -> C.NetworkId + -> Map P.Script C.TxIn + -> WalletOutputs f + -> Vault f + -> TxAssemblyConfig + -> Sdk.TxCandidate + -> Integer + -> f (C.Tx C.BabbageEra) +finalizeTxUnsafe' CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAssemblyConfig{..} txc@Sdk.TxCandidate{..} changeValue = do + sysenv <- getSystemEnv + collaterals <- selectCollaterals utxos sysenv refScriptsMap network conf txc + + (C.BalancedTxBody txb _ _) <- Internal.buildBalancedTxUnsafe sysenv refScriptsMap network (getChangeAddr deafultChangeAddr) collaterals txc changeValue + let + allInputs = (Set.elems txCandidateInputs <&> Sdk.fullTxInTxOut) ++ (Set.elems collaterals <&> Sdk.fullCollateralTxInTxOut) + signatories = allInputs >>= getPkh + where + getPkh Sdk.FullTxOut{fullTxOutAddress=P.Address (P.PubKeyCredential pkh) _} = [pkh] + getPkh _ = [] + signers <- mapM (\pkh -> getSigningKey pkh >>= maybe (throwM $ SignerNotFound pkh) pure) signatories + pure $ Internal.signTx txb signers + submitTx' :: Monad f => CardanoNetwork f C.BabbageEra -> C.Tx C.BabbageEra -> f C.TxId submitTx' CardanoNetwork{submitTx} tx = do submitTx tx From 07cecc47354a45363a3329b151c099c87a8b0cb4 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sat, 29 Jul 2023 16:16:26 +0200 Subject: [PATCH 10/21] fix Transactions --- submit-api/src/SubmitAPI/Service.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/submit-api/src/SubmitAPI/Service.hs b/submit-api/src/SubmitAPI/Service.hs index d0abbba4..9f7ef588 100644 --- a/submit-api/src/SubmitAPI/Service.hs +++ b/submit-api/src/SubmitAPI/Service.hs @@ -24,6 +24,7 @@ import Cardano.Crypto.DSIGN.SchnorrSecp256k1 data Transactions f era = Transactions { estimateTxFee :: Set.Set Sdk.FullCollateralTxIn -> Sdk.TxCandidate -> f C.Lovelace , finalizeTx :: Sdk.TxCandidate -> f (C.Tx era) + , finalizeTxUnsafe :: Sdk.TxCandidate -> Integer -> f (C.Tx era) , submitTx :: C.Tx era -> f C.TxId } @@ -39,6 +40,7 @@ mkTransactions mkTransactions network networkId refScriptsMap utxos wallet conf = Transactions { estimateTxFee = estimateTxFee' network networkId refScriptsMap , finalizeTx = finalizeTx' network networkId refScriptsMap utxos wallet conf + , finalizeTxUnsafe = finalizeTxUnsafe' network networkId refScriptsMap utxos wallet conf , submitTx = submitTx' network } From 326adeae195b75bd13778c3b98d09d93b1370ec5 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 13:44:45 +0200 Subject: [PATCH 11/21] update unsafe collateral estimation logic --- .../src/SubmitAPI/Internal/Balancing.hs | 8 ++--- .../src/SubmitAPI/Internal/Transaction.hs | 5 +-- submit-api/src/SubmitAPI/Service.hs | 35 ++++++++++++++++--- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 120d5e2f..114034cf 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -24,18 +24,18 @@ makeTransactionBodyBalanceUnsafe => TxBodyContent BuildTx era -> AddressInEra era -- ^ Change address -> Integer + -> Integer -> Either TxBodyErrorAutoBalance (BalancedTxBody era) -makeTransactionBodyBalanceUnsafe txbodycontent changeaddr changeValue = do +makeTransactionBodyBalanceUnsafe txbodycontent changeaddr changeValue colAmount = do let era' = cardanoEra retColSup <- maybeToEitherOr (totalAndReturnCollateralSupportedInEra era') TxBodyErrorMissingParamMinUTxO -- incorrect error let fee = 300000 - reqAmt = 1300000 - totalCollateral = TxTotalCollateral retColSup (Lovelace reqAmt) + totalCollateral = TxTotalCollateral retColSup (Lovelace colAmount) (retColl, reqCol) = ( TxReturnCollateral retColSup - (TxOut changeaddr (lovelaceToTxOutValue (Lovelace reqAmt)) TxOutDatumNone ReferenceScriptNone) + (TxOut changeaddr (lovelaceToTxOutValue (Lovelace colAmount)) TxOutDatumNone ReferenceScriptNone) , totalCollateral ) explicitTxFees <- first (const TxBodyErrorByronEraNotSupported) $ diff --git a/submit-api/src/SubmitAPI/Internal/Transaction.hs b/submit-api/src/SubmitAPI/Internal/Transaction.hs index d6172299..68c624e8 100644 --- a/submit-api/src/SubmitAPI/Internal/Transaction.hs +++ b/submit-api/src/SubmitAPI/Internal/Transaction.hs @@ -69,14 +69,15 @@ buildBalancedTxUnsafe -> Set.Set Sdk.FullCollateralTxIn -> Sdk.TxCandidate -> Integer + -> Integer -> f (BalancedTxBody BabbageEra) -buildBalancedTxUnsafe SystemEnv{..} refScriptsMap network defaultChangeAddr collateral txc@Sdk.TxCandidate{..} changeValue = do +buildBalancedTxUnsafe SystemEnv{..} refScriptsMap network defaultChangeAddr collateral txc@Sdk.TxCandidate{..} changeValue colAmount = do txBody <- buildTxBodyContent pparams network refScriptsMap collateral txc changeAddr <- absorbError $ case txCandidateChangePolicy of Just (Sdk.ReturnTo addr) -> Interop.toCardanoAddressInEra network addr _ -> Interop.toCardanoAddressInEra network $ Sdk.getAddress defaultChangeAddr absorbBalancingError $ - Balancing.makeTransactionBodyBalanceUnsafe txBody changeAddr changeValue + Balancing.makeTransactionBodyBalanceUnsafe txBody changeAddr changeValue colAmount where absorbBalancingError (Left e) = throwM $ BalancingError $ T.pack $ displayError e absorbBalancingError (Right a) = pure a diff --git a/submit-api/src/SubmitAPI/Service.hs b/submit-api/src/SubmitAPI/Service.hs index 9f7ef588..84024461 100644 --- a/submit-api/src/SubmitAPI/Service.hs +++ b/submit-api/src/SubmitAPI/Service.hs @@ -20,6 +20,11 @@ import NetworkAPI.Types import WalletAPI.Utxos import WalletAPI.Vault import Cardano.Crypto.DSIGN.SchnorrSecp256k1 +import Cardano.Api (Lovelace(Lovelace)) +import Plutus.V1.Ledger.Value (assetClass) +import Plutus.V1.Ledger.Api (adaSymbol) +import Plutus.V1.Ledger.Api (adaToken) +import Ledger.Value (assetClassValueOf) data Transactions f era = Transactions { estimateTxFee :: Set.Set Sdk.FullCollateralTxIn -> Sdk.TxCandidate -> f C.Lovelace @@ -55,7 +60,7 @@ estimateTxFee' -> f C.Lovelace estimateTxFee' CardanoNetwork{..} network refScriptsMap collateral txc = do SystemEnv{pparams} <- getSystemEnv - Internal.estimateTxFee pparams network refScriptsMap collateral txc + Internal.estimateTxFee pparams network refScriptsMap collateral txc finalizeTx' :: MonadThrow f @@ -93,10 +98,10 @@ finalizeTxUnsafe' -> Integer -> f (C.Tx C.BabbageEra) finalizeTxUnsafe' CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAssemblyConfig{..} txc@Sdk.TxCandidate{..} changeValue = do - sysenv <- getSystemEnv - collaterals <- selectCollaterals utxos sysenv refScriptsMap network conf txc + sysenv <- getSystemEnv + (collaterals, colAmount) <- selectCollateralsUnsafe utxos sysenv conf txc - (C.BalancedTxBody txb _ _) <- Internal.buildBalancedTxUnsafe sysenv refScriptsMap network (getChangeAddr deafultChangeAddr) collaterals txc changeValue + (C.BalancedTxBody txb _ _) <- Internal.buildBalancedTxUnsafe sysenv refScriptsMap network (getChangeAddr deafultChangeAddr) collaterals txc changeValue colAmount let allInputs = (Set.elems txCandidateInputs <&> Sdk.fullTxInTxOut) ++ (Set.elems collaterals <&> Sdk.fullCollateralTxInTxOut) signatories = allInputs >>= getPkh @@ -149,3 +154,25 @@ selectCollaterals WalletOutputs{selectUtxosStrict} SystemEnv{..} refScriptsMap n ([], _) -> pure mempty (_, Cover) -> collectCollaterals mempty _ -> throwM CollateralNotAllowed + +selectCollateralsUnsafe + :: MonadThrow f + => WalletOutputs f + -> SystemEnv + -> TxAssemblyConfig + -> Sdk.TxCandidate + -> f (Set.Set Sdk.FullCollateralTxIn, Integer) +selectCollateralsUnsafe WalletOutputs{selectUtxosStrict} SystemEnv{..} TxAssemblyConfig{..} Sdk.TxCandidate{..} = do + let + collectCollaterals = do + utxos <- selectUtxosStrict (P.toValue (P.Lovelace 1300000)) >>= maybe (throwM FailedToSatisfyCollateral) pure + let + collaterals = Set.fromList $ Set.elems utxos <&> Sdk.FullCollateralTxIn + adaAC = assetClass adaSymbol adaToken + origValue = foldl (\acc Sdk.FullTxOut{..} -> acc + assetClassValueOf fullTxOutValue adaAC) 0 utxos + + pure (collaterals, origValue) + + case collateralPolicy of + Cover -> collectCollaterals + _ -> pure (mempty, 0) From a849d6c6a871c679d9ee7c0d3e7fac4517bc25df Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 14:10:47 +0200 Subject: [PATCH 12/21] add debug --- submit-api/src/SubmitAPI/Service.hs | 16 ++++++++++------ submit-api/submit-api.cabal | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/submit-api/src/SubmitAPI/Service.hs b/submit-api/src/SubmitAPI/Service.hs index 84024461..1bae1673 100644 --- a/submit-api/src/SubmitAPI/Service.hs +++ b/submit-api/src/SubmitAPI/Service.hs @@ -25,6 +25,7 @@ import Plutus.V1.Ledger.Value (assetClass) import Plutus.V1.Ledger.Api (adaSymbol) import Plutus.V1.Ledger.Api (adaToken) import Ledger.Value (assetClassValueOf) +import System.Logging.Hlog data Transactions f era = Transactions { estimateTxFee :: Set.Set Sdk.FullCollateralTxIn -> Sdk.TxCandidate -> f C.Lovelace @@ -35,17 +36,18 @@ data Transactions f era = Transactions mkTransactions :: (MonadThrow f, MonadIO f) - => CardanoNetwork f C.BabbageEra + => Logging f + -> CardanoNetwork f C.BabbageEra -> C.NetworkId -> Map P.Script C.TxIn -> WalletOutputs f -> Vault f -> TxAssemblyConfig -> Transactions f C.BabbageEra -mkTransactions network networkId refScriptsMap utxos wallet conf = Transactions +mkTransactions logging network networkId refScriptsMap utxos wallet conf = Transactions { estimateTxFee = estimateTxFee' network networkId refScriptsMap , finalizeTx = finalizeTx' network networkId refScriptsMap utxos wallet conf - , finalizeTxUnsafe = finalizeTxUnsafe' network networkId refScriptsMap utxos wallet conf + , finalizeTxUnsafe = finalizeTxUnsafe' logging network networkId refScriptsMap utxos wallet conf , submitTx = submitTx' network } @@ -88,7 +90,8 @@ finalizeTx' CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAsse finalizeTxUnsafe' :: MonadThrow f - => CardanoNetwork f C.BabbageEra + => Logging f + -> CardanoNetwork f C.BabbageEra -> C.NetworkId -> Map P.Script C.TxIn -> WalletOutputs f @@ -97,10 +100,11 @@ finalizeTxUnsafe' -> Sdk.TxCandidate -> Integer -> f (C.Tx C.BabbageEra) -finalizeTxUnsafe' CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAssemblyConfig{..} txc@Sdk.TxCandidate{..} changeValue = do +finalizeTxUnsafe' Logging{..} CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAssemblyConfig{..} txc@Sdk.TxCandidate{..} changeValue = do sysenv <- getSystemEnv (collaterals, colAmount) <- selectCollateralsUnsafe utxos sysenv conf txc - + infoM $ "Collaterals: " ++ show collaterals + infoM $ "Collaterals amount: " ++ show colAmount (C.BalancedTxBody txb _ _) <- Internal.buildBalancedTxUnsafe sysenv refScriptsMap network (getChangeAddr deafultChangeAddr) collaterals txc changeValue colAmount let allInputs = (Set.elems txCandidateInputs <&> Sdk.fullTxInTxOut) ++ (Set.elems collaterals <&> Sdk.fullCollateralTxInTxOut) diff --git a/submit-api/submit-api.cabal b/submit-api/submit-api.cabal index f959a94c..5c1d878e 100644 --- a/submit-api/submit-api.cabal +++ b/submit-api/submit-api.cabal @@ -96,6 +96,7 @@ library aeson, servant, singletons, + hlog, either, aeson-gadt-th, plutus-script-utils, From aca710203c1bfb0ee6dd63a45bf8f9c73082c1a3 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 14:43:13 +0200 Subject: [PATCH 13/21] change return collateral --- submit-api/src/SubmitAPI/Internal/Balancing.hs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 114034cf..2c0e3aed 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -33,9 +33,7 @@ makeTransactionBodyBalanceUnsafe txbodycontent changeaddr changeValue colAmount fee = 300000 totalCollateral = TxTotalCollateral retColSup (Lovelace colAmount) (retColl, reqCol) = - ( TxReturnCollateral - retColSup - (TxOut changeaddr (lovelaceToTxOutValue (Lovelace colAmount)) TxOutDatumNone ReferenceScriptNone) + ( TxReturnCollateralNone , totalCollateral ) explicitTxFees <- first (const TxBodyErrorByronEraNotSupported) $ From 936a286df32dbefa099c5002064984a5afc21467 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 14:56:12 +0200 Subject: [PATCH 14/21] remove debug --- submit-api/src/SubmitAPI/Service.hs | 2 -- 1 file changed, 2 deletions(-) diff --git a/submit-api/src/SubmitAPI/Service.hs b/submit-api/src/SubmitAPI/Service.hs index 1bae1673..e2807e40 100644 --- a/submit-api/src/SubmitAPI/Service.hs +++ b/submit-api/src/SubmitAPI/Service.hs @@ -103,8 +103,6 @@ finalizeTxUnsafe' finalizeTxUnsafe' Logging{..} CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAssemblyConfig{..} txc@Sdk.TxCandidate{..} changeValue = do sysenv <- getSystemEnv (collaterals, colAmount) <- selectCollateralsUnsafe utxos sysenv conf txc - infoM $ "Collaterals: " ++ show collaterals - infoM $ "Collaterals amount: " ++ show colAmount (C.BalancedTxBody txb _ _) <- Internal.buildBalancedTxUnsafe sysenv refScriptsMap network (getChangeAddr deafultChangeAddr) collaterals txc changeValue colAmount let allInputs = (Set.elems txCandidateInputs <&> Sdk.fullTxInTxOut) ++ (Set.elems collaterals <&> Sdk.fullCollateralTxInTxOut) From e91e1b25010109e9a42b50f8b74370f89a6bb0a1 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 15:10:35 +0200 Subject: [PATCH 15/21] increase fee --- dex-core/src/ErgoDex/Amm/PoolActions.hs | 6 +++--- submit-api/src/SubmitAPI/Internal/Balancing.hs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dex-core/src/ErgoDex/Amm/PoolActions.hs b/dex-core/src/ErgoDex/Amm/PoolActions.hs index 3ffa72d1..1567ffc3 100644 --- a/dex-core/src/ErgoDex/Amm/PoolActions.hs +++ b/dex-core/src/ErgoDex/Amm/PoolActions.hs @@ -138,7 +138,7 @@ runSwapUnsafe' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFee when (poolReservesX pool * 2 <= lqBound pool) (Left $ InsufficientPoolLqForSwap (poolId pool)) let - fee = 300000 + fee = 320000 exFee = assetAmountRawValue quoteOutput * exFeePerTokenNum `div` exFeePerTokenDen rewardAddr = pubKeyHashAddress (PaymentPubKeyHash swapRewardPkh) swapRewardSPkh rewardOut = @@ -189,7 +189,7 @@ runDepositUnsafe' runDepositUnsafe' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOut, pool@Pool{..}) = do when (depositPoolId /= poolId) (Left $ PoolMismatch depositPoolId poolId) let - fee = 300000 + fee = 320000 inputs = mkOrderInputs P.Deposit pv dv (PoolIn poolOut) (OrderIn depositOut) (inX, inY) = @@ -265,7 +265,7 @@ runRedeemUnsafe' runRedeemUnsafe' executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, pool@Pool{..}) = do when (redeemPoolId /= poolId) (Left $ PoolMismatch redeemPoolId poolId) let - fee = 300000 + fee = 320000 inputs = mkOrderInputs P.Redeem pv rv (PoolIn poolOut) (OrderIn redeemOut) diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 2c0e3aed..a8ef588a 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -30,7 +30,7 @@ makeTransactionBodyBalanceUnsafe txbodycontent changeaddr changeValue colAmount let era' = cardanoEra retColSup <- maybeToEitherOr (totalAndReturnCollateralSupportedInEra era') TxBodyErrorMissingParamMinUTxO -- incorrect error let - fee = 300000 + fee = 320000 totalCollateral = TxTotalCollateral retColSup (Lovelace colAmount) (retColl, reqCol) = ( TxReturnCollateralNone From d7a8acc2a4d34e6e4fb8706fa3583d73e738ebf1 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 15:46:12 +0200 Subject: [PATCH 16/21] debug for exUnits --- submit-api/src/SubmitAPI/Internal/Balancing.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index a8ef588a..4740452f 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -16,7 +16,7 @@ import Cardano.Api import Cardano.Api.Shelley (ProtocolParameters(..), PoolId, ReferenceScript (..), fromShelleyLovelace) import qualified Cardano.Ledger.Coin as Ledger import Debug.Trace -import Control.FromSum +import Control.FromSum ( fromMaybe, maybeToEitherOr ) makeTransactionBodyBalanceUnsafe :: forall era. @@ -93,6 +93,8 @@ makeTransactionBodyAutoBalance eraInMode systemstart history pparams failures exUnitsMap' + traceM $ "exUnitsMap:" ++ show exUnitsMap + txbodycontent1 <- substituteExecutionUnits exUnitsMap' txbodycontent explicitTxFees <- first (const TxBodyErrorByronEraNotSupported) $ From 2c5a6ed9c70efb81d9ce0377f37a1f5752905553 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 16:05:48 +0200 Subject: [PATCH 17/21] add substituteExecutionUnitsUnsafe --- .../src/SubmitAPI/Internal/Balancing.hs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 4740452f..102ba95a 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -18,6 +18,9 @@ import qualified Cardano.Ledger.Coin as Ledger import Debug.Trace import Control.FromSum ( fromMaybe, maybeToEitherOr ) +-- exUnitsMap:fromList [(ScriptWitnessIndexTxIn 0,Right (ExecutionUnits {executionSteps = 130605779, executionMemory = 298198})), +-- (ScriptWitnessIndexTxIn 1,Right (ExecutionUnits {executionSteps = 133934187, executionMemory = 302164}))] + makeTransactionBodyBalanceUnsafe :: forall era. IsShelleyBasedEra era @@ -38,14 +41,27 @@ makeTransactionBodyBalanceUnsafe txbodycontent changeaddr changeValue colAmount ) explicitTxFees <- first (const TxBodyErrorByronEraNotSupported) $ txFeesExplicitInEra era' - txBody0 <- first TxBodyError $ makeTransactionBody txbodycontent + txBody0 <- substituteExecutionUnitsUnsafe txbodycontent + txBodyFinal <- first TxBodyError $ makeTransactionBody txBody0 { txOuts = txOuts txbodycontent , txFee = TxFeeExplicit explicitTxFees $ Lovelace fee , txReturnCollateral = retColl , txTotalCollateral = reqCol } - return (BalancedTxBody txBody0 (TxOut changeaddr (lovelaceToTxOutValue (Lovelace changeValue)) TxOutDatumNone ReferenceScriptNone) (Lovelace fee)) + return (BalancedTxBody txBodyFinal (TxOut changeaddr (lovelaceToTxOutValue (Lovelace changeValue)) TxOutDatumNone ReferenceScriptNone) (Lovelace fee)) +substituteExecutionUnitsUnsafe :: TxBodyContent BuildTx era -> Either TxBodyErrorAutoBalance (TxBodyContent BuildTx era) +substituteExecutionUnitsUnsafe = + mapTxScriptWitnesses f + where + f :: ScriptWitnessIndex + -> ScriptWitness witctx era + -> Either TxBodyErrorAutoBalance (ScriptWitness witctx era) + f _ wit@SimpleScriptWitness{} = Right wit + f _ (PlutusScriptWitness langInEra version script datum redeemer _) = + Right $ PlutusScriptWitness langInEra version script + datum redeemer (ExecutionUnits 134500000 304000) + makeTransactionBodyAutoBalance :: forall era mode. IsShelleyBasedEra era From fef1fda26bccf831397ba47dce791e098da1cb52 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 16:24:22 +0200 Subject: [PATCH 18/21] update exunits --- submit-api/src/SubmitAPI/Internal/Balancing.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 102ba95a..9cf2d550 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -60,8 +60,8 @@ substituteExecutionUnitsUnsafe = f _ wit@SimpleScriptWitness{} = Right wit f _ (PlutusScriptWitness langInEra version script datum redeemer _) = Right $ PlutusScriptWitness langInEra version script - datum redeemer (ExecutionUnits 134500000 304000) - + datum redeemer (ExecutionUnits 140000000 320000) + makeTransactionBodyAutoBalance :: forall era mode. IsShelleyBasedEra era From 512633642386e1f6c1cfed6a592a85890e335dff Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 21:25:46 +0200 Subject: [PATCH 19/21] add UnsafeEvalConfig --- dex-core/dex-core.cabal | 1 + dex-core/src/ErgoDex/Amm/PoolActions.hs | 32 +++++++++++-------- submit-api/src/SubmitAPI/Config.hs | 9 ++++++ .../src/SubmitAPI/Internal/Balancing.hs | 8 +++-- .../src/SubmitAPI/Internal/Transaction.hs | 8 +++-- submit-api/src/SubmitAPI/Service.hs | 14 ++++---- 6 files changed, 46 insertions(+), 26 deletions(-) diff --git a/dex-core/dex-core.cabal b/dex-core/dex-core.cabal index 945a5d5d..26948ca6 100644 --- a/dex-core/dex-core.cabal +++ b/dex-core/dex-core.cabal @@ -111,6 +111,7 @@ library either, extra, transformers, + submit-api, cardano-api, text, serialise, diff --git a/dex-core/src/ErgoDex/Amm/PoolActions.hs b/dex-core/src/ErgoDex/Amm/PoolActions.hs index 1567ffc3..70d6c81a 100644 --- a/dex-core/src/ErgoDex/Amm/PoolActions.hs +++ b/dex-core/src/ErgoDex/Amm/PoolActions.hs @@ -30,6 +30,7 @@ import ErgoDex.Contracts.Types import CardanoTx.Models import System.Logging.Hlog (Logging (Logging)) import Plutus.V1.Ledger.Value (Value) +import SubmitAPI.Config data OrderExecErr = PriceTooHigh @@ -89,14 +90,14 @@ data PoolActions = PoolActions , runRedeem :: [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) } -mkPoolActions :: PaymentPubKeyHash -> AmmValidators V1 -> PoolActions -mkPoolActions executorPkh AmmValidators{..} = PoolActions +mkPoolActions :: UnsafeEvalConfig -> PaymentPubKeyHash -> AmmValidators V1 -> PoolActions +mkPoolActions evalCfg executorPkh AmmValidators{..} = PoolActions { runSwapWithDebug = runSwapWithDebug' executorPkh poolV swapV , runDepositWithDebug = runDepositWithDebug' executorPkh poolV depositV , runRedeemWithDebug = runRedeemWithDebug' executorPkh poolV redeemV - , runSwap = runSwapUnsafe' executorPkh poolV swapV - , runDeposit = runDepositUnsafe' executorPkh poolV depositV - , runRedeem = runRedeemUnsafe' executorPkh poolV redeemV + , runSwap = runSwapUnsafe' evalCfg executorPkh poolV swapV + , runDeposit = runDepositUnsafe' evalCfg executorPkh poolV depositV + , runRedeem = runRedeemUnsafe' evalCfg executorPkh poolV redeemV } newtype PoolIn = PoolIn FullTxOut @@ -120,14 +121,15 @@ mkOrderInputs action (PoolValidator pv) ov' (PoolIn poolOut) (OrderIn orderOut) in Set.fromList [poolIn, orderIn] runSwapUnsafe' - :: PaymentPubKeyHash + :: UnsafeEvalConfig + -> PaymentPubKeyHash -> PoolValidator V1 -> SwapValidator V1 -> [FullTxOut] -> OnChain Swap -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) -runSwapUnsafe' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do +runSwapUnsafe' UnsafeEvalConfig{..} executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFeePerToken{..}, ..}) (poolOut, pool) = do let inputs = mkOrderInputs P.Swap pv sv (PoolIn poolOut) (OrderIn swapOut) pp@(Predicted nextPoolOut _) = applySwap pv pool (AssetAmount swapBase swapBaseIn) @@ -138,7 +140,7 @@ runSwapUnsafe' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFee when (poolReservesX pool * 2 <= lqBound pool) (Left $ InsufficientPoolLqForSwap (poolId pool)) let - fee = 320000 + fee = unsafeTxFee exFee = assetAmountRawValue quoteOutput * exFeePerTokenNum `div` exFeePerTokenDen rewardAddr = pubKeyHashAddress (PaymentPubKeyHash swapRewardPkh) swapRewardSPkh rewardOut = @@ -179,17 +181,18 @@ runSwapUnsafe' executorPkh pv sv refInputs (OnChain swapOut Swap{swapExFee=ExFee Right (txCandidate, pp, exFee - fee) runDepositUnsafe' - :: PaymentPubKeyHash + :: UnsafeEvalConfig + -> PaymentPubKeyHash -> PoolValidator V1 -> DepositValidator V1 -> [FullTxOut] -> OnChain Deposit -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) -runDepositUnsafe' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOut, pool@Pool{..}) = do +runDepositUnsafe' UnsafeEvalConfig{..} executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) (poolOut, pool@Pool{..}) = do when (depositPoolId /= poolId) (Left $ PoolMismatch depositPoolId poolId) let - fee = 320000 + fee = unsafeTxFee inputs = mkOrderInputs P.Deposit pv dv (PoolIn poolOut) (OrderIn depositOut) (inX, inY) = @@ -255,17 +258,18 @@ runDepositUnsafe' executorPkh pv dv refInputs (OnChain depositOut Deposit{..}) ( Right (txCandidate, pp, unAmount exFee - fee) runRedeemUnsafe' - :: PaymentPubKeyHash + :: UnsafeEvalConfig + -> PaymentPubKeyHash -> PoolValidator V1 -> RedeemValidator V1 -> [FullTxOut] -> OnChain Redeem -> (FullTxOut, Pool) -> Either OrderExecErr (TxCandidate, Predicted Pool, Integer) -runRedeemUnsafe' executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, pool@Pool{..}) = do +runRedeemUnsafe' UnsafeEvalConfig{..} executorPkh pv rv refInputs (OnChain redeemOut Redeem{..}) (poolOut, pool@Pool{..}) = do when (redeemPoolId /= poolId) (Left $ PoolMismatch redeemPoolId poolId) let - fee = 320000 + fee = unsafeTxFee inputs = mkOrderInputs P.Redeem pv rv (PoolIn poolOut) (OrderIn redeemOut) diff --git a/submit-api/src/SubmitAPI/Config.hs b/submit-api/src/SubmitAPI/Config.hs index f4af1f11..9b69a70b 100644 --- a/submit-api/src/SubmitAPI/Config.hs +++ b/submit-api/src/SubmitAPI/Config.hs @@ -3,6 +3,7 @@ module SubmitAPI.Config , CollateralPolicy(..) , TxAssemblyConfig(..) , DefaultChangeAddress(..) + , UnsafeEvalConfig(..) , unwrapChangeAddress ) where @@ -37,6 +38,14 @@ data TxAssemblyConfig = TxAssemblyConfig instance D.FromDhall TxAssemblyConfig +data UnsafeEvalConfig = UnsafeEvalConfig + { unsafeTxFee :: Integer + , exUnits :: Integer + , exMem :: Integer + } deriving Generic + +instance D.FromDhall UnsafeEvalConfig + newtype DefaultChangeAddress = DefaultChangeAddress { getChangeAddr :: ChangeAddress } unwrapChangeAddress :: DefaultChangeAddress -> Address diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 9cf2d550..57aa6383 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -17,6 +17,7 @@ import Cardano.Api.Shelley (ProtocolParameters(..), PoolId, ReferenceScript (. import qualified Cardano.Ledger.Coin as Ledger import Debug.Trace import Control.FromSum ( fromMaybe, maybeToEitherOr ) +import SubmitAPI.Config (UnsafeEvalConfig (..)) -- exUnitsMap:fromList [(ScriptWitnessIndexTxIn 0,Right (ExecutionUnits {executionSteps = 130605779, executionMemory = 298198})), -- (ScriptWitnessIndexTxIn 1,Right (ExecutionUnits {executionSteps = 133934187, executionMemory = 302164}))] @@ -24,16 +25,17 @@ import Control.FromSum ( fromMaybe, maybeToEitherOr ) makeTransactionBodyBalanceUnsafe :: forall era. IsShelleyBasedEra era - => TxBodyContent BuildTx era + => UnsafeEvalConfig + -> TxBodyContent BuildTx era -> AddressInEra era -- ^ Change address -> Integer -> Integer -> Either TxBodyErrorAutoBalance (BalancedTxBody era) -makeTransactionBodyBalanceUnsafe txbodycontent changeaddr changeValue colAmount = do +makeTransactionBodyBalanceUnsafe cfg@UnsafeEvalConfig{..} txbodycontent changeaddr changeValue colAmount = do let era' = cardanoEra retColSup <- maybeToEitherOr (totalAndReturnCollateralSupportedInEra era') TxBodyErrorMissingParamMinUTxO -- incorrect error let - fee = 320000 + fee = unsafeTxFee totalCollateral = TxTotalCollateral retColSup (Lovelace colAmount) (retColl, reqCol) = ( TxReturnCollateralNone diff --git a/submit-api/src/SubmitAPI/Internal/Transaction.hs b/submit-api/src/SubmitAPI/Internal/Transaction.hs index 68c624e8..7b9d1430 100644 --- a/submit-api/src/SubmitAPI/Internal/Transaction.hs +++ b/submit-api/src/SubmitAPI/Internal/Transaction.hs @@ -28,6 +28,7 @@ import qualified CardanoTx.Models as Sdk import qualified SubmitAPI.Internal.Balancing as Balancing import CardanoTx.ToPlutus import NetworkAPI.Types +import SubmitAPI.Config signTx :: TxBody BabbageEra @@ -62,7 +63,8 @@ buildBalancedTx SystemEnv{..} refScriptsMap network defaultChangeAddr collateral buildBalancedTxUnsafe :: (MonadThrow f) - => SystemEnv + => UnsafeEvalConfig + -> SystemEnv -> Map P.Script C.TxIn -> NetworkId -> Sdk.ChangeAddress @@ -71,13 +73,13 @@ buildBalancedTxUnsafe -> Integer -> Integer -> f (BalancedTxBody BabbageEra) -buildBalancedTxUnsafe SystemEnv{..} refScriptsMap network defaultChangeAddr collateral txc@Sdk.TxCandidate{..} changeValue colAmount = do +buildBalancedTxUnsafe cfg SystemEnv{..} refScriptsMap network defaultChangeAddr collateral txc@Sdk.TxCandidate{..} changeValue colAmount = do txBody <- buildTxBodyContent pparams network refScriptsMap collateral txc changeAddr <- absorbError $ case txCandidateChangePolicy of Just (Sdk.ReturnTo addr) -> Interop.toCardanoAddressInEra network addr _ -> Interop.toCardanoAddressInEra network $ Sdk.getAddress defaultChangeAddr absorbBalancingError $ - Balancing.makeTransactionBodyBalanceUnsafe txBody changeAddr changeValue colAmount + Balancing.makeTransactionBodyBalanceUnsafe cfg txBody changeAddr changeValue colAmount where absorbBalancingError (Left e) = throwM $ BalancingError $ T.pack $ displayError e absorbBalancingError (Right a) = pure a diff --git a/submit-api/src/SubmitAPI/Service.hs b/submit-api/src/SubmitAPI/Service.hs index e2807e40..d2dee5a7 100644 --- a/submit-api/src/SubmitAPI/Service.hs +++ b/submit-api/src/SubmitAPI/Service.hs @@ -36,7 +36,8 @@ data Transactions f era = Transactions mkTransactions :: (MonadThrow f, MonadIO f) - => Logging f + => UnsafeEvalConfig + -> Logging f -> CardanoNetwork f C.BabbageEra -> C.NetworkId -> Map P.Script C.TxIn @@ -44,10 +45,10 @@ mkTransactions -> Vault f -> TxAssemblyConfig -> Transactions f C.BabbageEra -mkTransactions logging network networkId refScriptsMap utxos wallet conf = Transactions +mkTransactions cfg logging network networkId refScriptsMap utxos wallet conf = Transactions { estimateTxFee = estimateTxFee' network networkId refScriptsMap , finalizeTx = finalizeTx' network networkId refScriptsMap utxos wallet conf - , finalizeTxUnsafe = finalizeTxUnsafe' logging network networkId refScriptsMap utxos wallet conf + , finalizeTxUnsafe = finalizeTxUnsafe' cfg logging network networkId refScriptsMap utxos wallet conf , submitTx = submitTx' network } @@ -90,7 +91,8 @@ finalizeTx' CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAsse finalizeTxUnsafe' :: MonadThrow f - => Logging f + => UnsafeEvalConfig + -> Logging f -> CardanoNetwork f C.BabbageEra -> C.NetworkId -> Map P.Script C.TxIn @@ -100,10 +102,10 @@ finalizeTxUnsafe' -> Sdk.TxCandidate -> Integer -> f (C.Tx C.BabbageEra) -finalizeTxUnsafe' Logging{..} CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAssemblyConfig{..} txc@Sdk.TxCandidate{..} changeValue = do +finalizeTxUnsafe' cfg Logging{..} CardanoNetwork{..} network refScriptsMap utxos Vault{..} conf@TxAssemblyConfig{..} txc@Sdk.TxCandidate{..} changeValue = do sysenv <- getSystemEnv (collaterals, colAmount) <- selectCollateralsUnsafe utxos sysenv conf txc - (C.BalancedTxBody txb _ _) <- Internal.buildBalancedTxUnsafe sysenv refScriptsMap network (getChangeAddr deafultChangeAddr) collaterals txc changeValue colAmount + (C.BalancedTxBody txb _ _) <- Internal.buildBalancedTxUnsafe cfg sysenv refScriptsMap network (getChangeAddr deafultChangeAddr) collaterals txc changeValue colAmount let allInputs = (Set.elems txCandidateInputs <&> Sdk.fullTxInTxOut) ++ (Set.elems collaterals <&> Sdk.fullCollateralTxInTxOut) signatories = allInputs >>= getPkh From d67876ee27b62a95cba1b018539d09555fe2b55c Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Sun, 30 Jul 2023 23:13:49 +0200 Subject: [PATCH 20/21] add cfg to substituteExecutionUnitsUnsafe --- submit-api/src/SubmitAPI/Config.hs | 5 +++-- submit-api/src/SubmitAPI/Internal/Balancing.hs | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/submit-api/src/SubmitAPI/Config.hs b/submit-api/src/SubmitAPI/Config.hs index 9b69a70b..2b62cd1c 100644 --- a/submit-api/src/SubmitAPI/Config.hs +++ b/submit-api/src/SubmitAPI/Config.hs @@ -15,6 +15,7 @@ import Ledger (Address) import qualified Cardano.Api as C import qualified Ledger.Tx.CardanoAPI as Interop import CardanoTx.Models (ChangeAddress(..)) +import Dhall (Natural) data FeePolicy = Strict -- Require existing TX inputs to cover fee entirely @@ -40,8 +41,8 @@ instance D.FromDhall TxAssemblyConfig data UnsafeEvalConfig = UnsafeEvalConfig { unsafeTxFee :: Integer - , exUnits :: Integer - , exMem :: Integer + , exUnits :: Natural + , exMem :: Natural } deriving Generic instance D.FromDhall UnsafeEvalConfig diff --git a/submit-api/src/SubmitAPI/Internal/Balancing.hs b/submit-api/src/SubmitAPI/Internal/Balancing.hs index 57aa6383..672e46d0 100644 --- a/submit-api/src/SubmitAPI/Internal/Balancing.hs +++ b/submit-api/src/SubmitAPI/Internal/Balancing.hs @@ -43,7 +43,7 @@ makeTransactionBodyBalanceUnsafe cfg@UnsafeEvalConfig{..} txbodycontent changead ) explicitTxFees <- first (const TxBodyErrorByronEraNotSupported) $ txFeesExplicitInEra era' - txBody0 <- substituteExecutionUnitsUnsafe txbodycontent + txBody0 <- substituteExecutionUnitsUnsafe cfg txbodycontent txBodyFinal <- first TxBodyError $ makeTransactionBody txBody0 { txOuts = txOuts txbodycontent , txFee = TxFeeExplicit explicitTxFees $ Lovelace fee @@ -52,8 +52,8 @@ makeTransactionBodyBalanceUnsafe cfg@UnsafeEvalConfig{..} txbodycontent changead } return (BalancedTxBody txBodyFinal (TxOut changeaddr (lovelaceToTxOutValue (Lovelace changeValue)) TxOutDatumNone ReferenceScriptNone) (Lovelace fee)) -substituteExecutionUnitsUnsafe :: TxBodyContent BuildTx era -> Either TxBodyErrorAutoBalance (TxBodyContent BuildTx era) -substituteExecutionUnitsUnsafe = +substituteExecutionUnitsUnsafe :: UnsafeEvalConfig -> TxBodyContent BuildTx era -> Either TxBodyErrorAutoBalance (TxBodyContent BuildTx era) +substituteExecutionUnitsUnsafe UnsafeEvalConfig{..} = mapTxScriptWitnesses f where f :: ScriptWitnessIndex @@ -62,7 +62,7 @@ substituteExecutionUnitsUnsafe = f _ wit@SimpleScriptWitness{} = Right wit f _ (PlutusScriptWitness langInEra version script datum redeemer _) = Right $ PlutusScriptWitness langInEra version script - datum redeemer (ExecutionUnits 140000000 320000) + datum redeemer (ExecutionUnits exUnits exMem) makeTransactionBodyAutoBalance :: forall era mode. From fcadfb499f2a479e71245e837b6d4132db8f1e03 Mon Sep 17 00:00:00 2001 From: Bromel777 Date: Mon, 31 Jul 2023 00:14:36 +0200 Subject: [PATCH 21/21] fix reward addr --- dex-core/src/ErgoDex/Amm/PoolActions.hs | 6 +++--- submit-api/test/Main.hs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dex-core/src/ErgoDex/Amm/PoolActions.hs b/dex-core/src/ErgoDex/Amm/PoolActions.hs index 70d6c81a..d7a3739d 100644 --- a/dex-core/src/ErgoDex/Amm/PoolActions.hs +++ b/dex-core/src/ErgoDex/Amm/PoolActions.hs @@ -161,7 +161,7 @@ runSwapUnsafe' UnsafeEvalConfig{..} executorPkh pv sv refInputs (OnChain swapOut executorRewardOut = TxOutCandidate - { txOutCandidateAddress = rewardAddr + { txOutCandidateAddress = pubKeyHashAddress executorPkh Nothing , txOutCandidateValue = Ada.lovelaceValueOf (exFee - fee) , txOutCandidateDatum = EmptyDatum , txOutCandidateRefScript = Nothing @@ -238,7 +238,7 @@ runDepositUnsafe' UnsafeEvalConfig{..} executorPkh pv dv refInputs (OnChain depo executorRewardOut = TxOutCandidate - { txOutCandidateAddress = rewardAddr + { txOutCandidateAddress = pubKeyHashAddress executorPkh Nothing , txOutCandidateValue = Ada.lovelaceValueOf (unAmount exFee - fee) , txOutCandidateDatum = EmptyDatum , txOutCandidateRefScript = Nothing @@ -300,7 +300,7 @@ runRedeemUnsafe' UnsafeEvalConfig{..} executorPkh pv rv refInputs (OnChain redee executorRewardOut = TxOutCandidate - { txOutCandidateAddress = rewardAddr + { txOutCandidateAddress = pubKeyHashAddress executorPkh Nothing , txOutCandidateValue = Ada.lovelaceValueOf (exFee - fee) , txOutCandidateDatum = EmptyDatum , txOutCandidateRefScript = Nothing diff --git a/submit-api/test/Main.hs b/submit-api/test/Main.hs index 86002f3a..1d775423 100644 --- a/submit-api/test/Main.hs +++ b/submit-api/test/Main.hs @@ -129,7 +129,7 @@ dq = "\"" main :: IO () main = do - txFile + test123 txFile :: IO () txFile = do