Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cardano-testnet/cardano-testnet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ test-suite cardano-testnet-test
Cardano.Testnet.Test.Cli.QuerySlotNumber
Cardano.Testnet.Test.Cli.Plutus.Scripts
Cardano.Testnet.Test.Cli.Plutus.CostCalculation
Cardano.Testnet.Test.Cli.Plutus.BuildRaw
Cardano.Testnet.Test.Cli.Plutus.MultiAssetReturnCollateral
Cardano.Testnet.Test.Cli.Scripts.Simple.CostCalculation
Cardano.Testnet.Test.Cli.Scripts.Simple.Mint
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

### Tests

- Added integration test for spending a reference script using `transaction build-raw`

Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Cardano.Testnet.Test.Cli.Plutus.BuildRaw
( hprop_build_raw_ref_script_spend
-- | Execute tests in this module with:
-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test -- -p "/Build Raw Ref Script/"@
Comment on lines +8 to +9
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong haddock, -- | is used before symbol

)
where

import Cardano.Api hiding (Value)
import Cardano.Api.Experimental (Some (Some))
import Cardano.Api.Ledger (EpochInterval (..))

import Cardano.Testnet

import Prelude

import Control.Monad (void)
import Data.Default.Class (Default (def))
import qualified Data.Text as Text
import System.FilePath ((</>))
import qualified System.Info as SYS

import Testnet.Components.Query (findLargestUtxoForPaymentKey, getEpochStateView, getTxIx,
watchEpochStateUpdate)
import qualified Testnet.Defaults as Defaults
import Testnet.Process.Cli.Transaction (TxOutAddress (..), mkSpendOutputsOnlyTx,
retrieveTransactionId, signTx, submitTx)
import Testnet.Process.Run (execCli', mkExecConfig)
import Testnet.Property.Util (integrationRetryWorkspace)
import Testnet.Start.Types (eraToString)
import Testnet.Types

import Hedgehog (Property)
import qualified Hedgehog as H
import qualified Hedgehog.Extras.Test.Base as H
import qualified Hedgehog.Extras.Test.File as H
import qualified Hedgehog.Extras.Test.TestWatchdog as H

-- | Test spending a reference script UTxO using @transaction build-raw@.
-- @DISABLE_RETRIES=1 cabal test cardano-testnet-test --test-options '-p "/Build Raw Ref Script/"'@
Comment on lines +43 to +44
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is duplicated, - the same as in the exports list

hprop_build_raw_ref_script_spend :: Property
hprop_build_raw_ref_script_spend = integrationRetryWorkspace 2 "build-raw-ref-script" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
H.note_ SYS.os
conf@Conf{tempAbsPath} <- mkConf tempAbsBasePath'
let tempAbsPath' = unTmpAbsPath tempAbsPath
work <- H.createDirectoryIfMissing $ tempAbsPath' </> "work"

let
sbe = ShelleyBasedEraConway
era = toCardanoEra sbe
cEra = AnyCardanoEra era
eraName = eraToString era
tempBaseAbsPath = makeTmpBaseAbsPath $ TmpAbsolutePath tempAbsPath'
options = def{cardanoNodeEra = AnyShelleyBasedEra sbe}

TestnetRuntime
{ configurationFile
, testnetMagic
, testnetNodes
, wallets = wallet0 : wallet1 : _
} <-
createAndRunTestnet options def conf

poolNode1 <- H.headM testnetNodes
poolSprocket1 <- H.noteShow $ nodeSprocket poolNode1
execConfig <- mkExecConfig tempBaseAbsPath poolSprocket1 testnetMagic
epochStateView <- getEpochStateView configurationFile (nodeSocketPath poolNode1)

-- Write PlutusV3 always-succeeds script to file
let plutusScriptFp = work </> "always-succeeds-script.plutusV3"
H.writeFile plutusScriptFp $ Text.unpack Defaults.plutusV3Script
let plutusV3Script = File plutusScriptFp

-- Step 1: Publish reference script at wallet0's address (not the script address)
refScriptPublishWork <- H.createDirectoryIfMissing $ work </> "ref-script-publish"
let scriptPublishUTxOAmount = 10_000_000

txinPublish <- findLargestUtxoForPaymentKey epochStateView sbe wallet0
let txBodyPublishFp = File $ refScriptPublishWork </> "tx-body.txbody"
void $ execCli' execConfig
[ eraName
, "transaction", "build"
, "--change-address", Text.unpack $ paymentKeyInfoAddr wallet0
, "--tx-in", Text.unpack $ renderTxIn txinPublish
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
, "--tx-in", Text.unpack $ renderTxIn txinPublish
, "--tx-in", prettyShow txinPublish

, "--tx-out", Text.unpack (paymentKeyInfoAddr wallet0) <> "+" <> show (unCoin scriptPublishUTxOAmount)
, "--tx-out-reference-script-file", unFile plutusV3Script
, "--out-file", unFile txBodyPublishFp
]
signedTxPublishRefScript <-
signTx
execConfig
cEra
refScriptPublishWork
"signed-tx"
txBodyPublishFp
[Some $ paymentKeyInfoPair wallet0]
submitTx execConfig cEra signedTxPublishRefScript

txIdPublishRefScript <- retrieveTransactionId execConfig signedTxPublishRefScript
txIxPublishRefScript <-
H.evalMaybeM $
watchEpochStateUpdate
epochStateView
(EpochInterval 2)
(getTxIx sbe txIdPublishRefScript scriptPublishUTxOAmount)

-- Step 2: Lock funds at script address
refScriptLock <- H.createDirectoryIfMissing $ work </> "ref-script-lock"
let transferAmount = 20_000_000

txBodyLock <-
mkSpendOutputsOnlyTx
execConfig
epochStateView
sbe
refScriptLock
"tx-body"
wallet0
[(ScriptAddress plutusV3Script, transferAmount, Nothing)]
signedTxLock <-
signTx execConfig cEra refScriptLock "signed-tx" txBodyLock [Some $ paymentKeyInfoPair wallet0]
submitTx execConfig cEra signedTxLock

txIdLock <- retrieveTransactionId execConfig signedTxLock
txIxLock <-
H.evalMaybeM $
watchEpochStateUpdate epochStateView (EpochInterval 2) (getTxIx sbe txIdLock transferAmount)

-- Step 3: Query protocol parameters
void $ execCli' execConfig
[ eraName, "query", "protocol-parameters"
, "--cardano-mode"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
, "--cardano-mode"

this is redundant, no?

, "--out-file", work </> "pparams.json"
]

-- Step 4: Build raw transaction to unlock the script UTxO
refScriptUnlock <- H.createDirectoryIfMissing $ work </> "ref-script-unlock"
let unsignedUnlockTx = File $ refScriptUnlock </> "unsigned-tx.tx"
fee = 500_000 :: Coin

collateralUTxO <- findLargestUtxoForPaymentKey epochStateView sbe wallet1

void $
execCli'
execConfig
[ eraName
, "transaction", "build-raw"
, "--tx-in", prettyShow (TxIn txIdLock txIxLock)
, "--spending-reference-tx-in-inline-datum-present"
, "--spending-tx-in-reference", prettyShow (TxIn txIdPublishRefScript txIxPublishRefScript)
, "--spending-plutus-script-v3"
, "--spending-reference-tx-in-redeemer-value", "42"
, "--spending-reference-tx-in-execution-units", "(200000000, 200000)"
, "--tx-in-collateral", prettyShow collateralUTxO
, "--tx-out", Text.unpack (paymentKeyInfoAddr wallet1) <> "+" <> show (unCoin (transferAmount - fee))
, "--fee", show (unCoin fee)
, "--protocol-params-file", work </> "pparams.json"
, "--out-file", unFile unsignedUnlockTx
]

-- Step 5: Sign and submit
signedUnlockTx <-
signTx
execConfig
cEra
refScriptUnlock
"signed-tx"
unsignedUnlockTx
[Some $ paymentKeyInfoPair wallet1]

submitTx execConfig cEra signedUnlockTx

-- Verify the transaction landed on chain
txIdUnlock <- retrieveTransactionId execConfig signedUnlockTx
void $
H.evalMaybeM $
watchEpochStateUpdate
epochStateView
(EpochInterval 2)
(getTxIx sbe txIdUnlock (transferAmount - fee))
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module Main
import qualified Cardano.Crypto.Init as Crypto
import qualified Cardano.Testnet.Test.Api.TxReferenceInputDatum
import qualified Cardano.Testnet.Test.Cli.KesPeriodInfo
import qualified Cardano.Testnet.Test.Cli.Plutus.BuildRaw
import qualified Cardano.Testnet.Test.Cli.Plutus.CostCalculation
import qualified Cardano.Testnet.Test.Cli.Plutus.Scripts
import qualified Cardano.Testnet.Test.Cli.Query
Expand Down Expand Up @@ -94,6 +95,7 @@ tests = do
[ ignoreOnWindows "PlutusV3 purposes" Cardano.Testnet.Test.Cli.Plutus.Scripts.hprop_plutus_purposes_v3
, ignoreOnWindows "PlutusV2 transaction with two script certs" Cardano.Testnet.Test.Cli.Plutus.Scripts.hprop_tx_two_script_certs_v2
, ignoreOnWindows "Collateral With Multiassets" Cardano.Testnet.Test.Cli.Plutus.MultiAssetReturnCollateral.hprop_collateral_with_tokens
, ignoreOnWindows "Build Raw Ref Script" Cardano.Testnet.Test.Cli.Plutus.BuildRaw.hprop_build_raw_ref_script_spend
, T.testGroup "Cost Calc"
[ ignoreOnWindows "Ref Script" Cardano.Testnet.Test.Cli.Plutus.CostCalculation.hprop_ref_plutus_cost_calculation
, ignoreOnWindows "Normal Script" Cardano.Testnet.Test.Cli.Plutus.CostCalculation.hprop_included_plutus_cost_calculation
Expand Down
Loading