Merge pull request #1090 from input-output-hk/ch1bo/kupo-integration-test
Make hydra-cluster --devnet open a head
Make hydra-cluster --devnet open a head
import Hydra.Cluster.Faucet (publishHydraScriptsAs)
import Hydra.Cluster.Fixture (Actor (Faucet))
import Hydra.Cluster.Options (Options (..), PublishOrReuse (Publish, Reuse), parseOptions)
import Hydra.Cluster.Scenarios (singlePartyHeadFullLifeCycle)
import Hydra.Cluster.Scenarios (singlePartyHeadFullLifeCycle, singlePartyOpenAHead)
import Hydra.Logging (Verbosity (Verbose), traceWith, withTracer)
import HydraNode (EndToEndLog (..))
import HydraNode (EndToEndLog (..), HydraClient (..))
import Options.Applicative (ParserInfo, execParser, fullDesc, header, helper, info, progDesc)
import Test.Hydra.Prelude (withTempDir)
>>= singlePartyHeadFullLifeCycle tracer workDir node
Nothing ->
withCardanoNodeDevnet fromCardanoNode workDir $ \node -> do
publishOrReuseHydraScripts tracer node
>> forever (threadDelay 60) -- do nothing
txId <- publishOrReuseHydraScripts tracer node
singlePartyOpenAHead tracer workDir node txId $ \HydraClient{} -> do
forever (threadDelay 60) -- do nothing
where
Options{knownNetwork, stateDirectory, publishHydraScripts} = options
<> help
( toString $
unlines
[ "Run cardano-node over a devnet and stand-by. This is useful when one"
, "wants to have a local devnet possibly primed with Hydra contracts and"
, "use it for testing"
[ "Create a local cardano devnet by running a cardano-node, "
, "start a hydra-node and open a single-party head in it. "
, "Generates a wallet key pair and commits some into the head using it. "
, "The keys are available on the state-directory. This is useful as a "
, "sandbox for development and testing."
]
)
)
)
import Hydra.Cardano.Api (
BabbageEra,
File (File),
Lovelace (..),
PlutusScriptV2,
Tx,
selectLovelace,
signTx,
toScriptData,
writeFileTextEnvelope,
)
import Hydra.Cardano.Api.Prelude (ReferenceScript (..), TxOut (..), TxOutDatum (..))
import Hydra.Chain (HeadId)
import Hydra.Cluster.Util (chainConfigFor, keysFor)
import Hydra.ContestationPeriod (ContestationPeriod (UnsafeContestationPeriod))
import Hydra.Ledger (IsTx (balance))
import Hydra.Ledger.Cardano (genKeyPair)
import Hydra.Logging (Tracer, traceWith)
import Hydra.Options (ChainConfig, networkId, startChainFrom)
import Hydra.Party (Party)
import HydraNode (EndToEndLog (..), input, output, requestCommitTx, send, waitFor, waitForAllMatch, waitMatch, withHydraNode)
import HydraNode (EndToEndLog (..), HydraClient, input, output, requestCommitTx, send, waitFor, waitForAllMatch, waitMatch, withHydraNode)
import qualified Network.HTTP.Client as L
import Network.HTTP.Req (
HttpException (VanillaHttpException),
)
import qualified PlutusLedgerApi.Test.Examples as Plutus
import Test.Hspec.Expectations (shouldBe, shouldReturn, shouldThrow)
import Test.QuickCheck (generate)
restartedNodeCanObserveCommitTx :: Tracer IO EndToEndLog -> FilePath -> RunningNode -> TxId -> IO ()
restartedNodeCanObserveCommitTx tracer workDir cardanoNode hydraScriptsTxId = do
utxo <- queryUTxOFor networkId nodeSocket QueryTip actorVk
traceWith tracer RemainingFunds{actor = actorName actor, utxo}
-- | Open a Hydra Head with only a single participant but some arbitrary UTxO
-- committed.
singlePartyOpenAHead ::
Tracer IO EndToEndLog ->
FilePath ->
RunningNode ->
TxId ->
-- | Continuation called when the head is open
(HydraClient -> IO ()) ->
IO ()
singlePartyOpenAHead tracer workDir node hydraScriptsTxId callback =
(`finally` returnFundsToFaucet tracer node Alice) $ do
refuelIfNeeded tracer node Alice 25_000_000
-- Start hydra-node on chain tip
tip <- queryTip networkId nodeSocket
let contestationPeriod = UnsafeContestationPeriod 100
aliceChainConfig <-
chainConfigFor Alice workDir nodeSocket [] contestationPeriod
<&> \config -> config{networkId, startChainFrom = Just tip}
(walletVk, walletSk) <- generate genKeyPair
let keyPath = workDir <> "/wallet.sk"
_ <- writeFileTextEnvelope (File keyPath) Nothing walletSk
traceWith tracer CreatedKey{keyPath}
utxoToCommit <- seedFromFaucet node walletVk 100_000_000 (contramap FromFaucet tracer)
withHydraNode tracer aliceChainConfig workDir 1 aliceSk [] [1] hydraScriptsTxId $ \n1 -> do
-- Initialize & open head
send n1 $ input "Init" []
headId <- waitMatch 600 n1 $ headIsInitializingWith (Set.fromList [alice])
-- Commit nothing for now
requestCommitTx n1 utxoToCommit <&> signTx walletSk >>= submitTx node
waitFor tracer 600 [n1] $
output "HeadIsOpen" ["utxo" .= toJSON utxoToCommit, "headId" .= headId]
callback n1
where
RunningNode{networkId, nodeSocket} = node
-- | Exercise committing a script utxo that uses inline datums.
singlePartyCommitsExternalScriptWithInlineDatum ::
Tracer IO EndToEndLog ->
| RemainingFunds {actor :: String, utxo :: UTxO}
| PublishedHydraScriptsAt {hydraScriptsTxId :: TxId}
| UsingHydraScriptsAt {hydraScriptsTxId :: TxId}
| CreatedKey { keyPath :: FilePath }
deriving (Eq, Show, Generic, ToJSON, FromJSON, ToObject)
-- XXX: The two lists need to be of same length. Also the verification keys can
Alonzo builds