Plutip is a tool to run private Cardano testnets. CTL provides integration with Plutip via a plutip-server
binary that exposes an HTTP interface to control local Cardano clusters.
Table of Contents
CTL depends on a number of binaries in the $PATH
to execute Plutip tests:
plutip-server
to launch a localcardano-node
clusterogmios
ogmios-datum-cache
- PostgreSQL:
initdb
,createdb
andpsql
forogmios-datum-cache
storage
If you plan on using CTL's applyArgs
effect, you must also ensure the following is on your $PATH
:
ctl-server
: a server-side part of CTL itself
All of these are provided by CTL's overlays.runtime
(and are provided in CTL's own devShell
). You must use the runtime
overlay or otherwise make the services available in your package set (e.g. by defining them within your own overlays
when instantiating nixpkgs
) as purescriptProject.runPlutipTest
expects all of them.
The services are NOT run by docker-compose
as is the case with launchCtlRuntime
: they are started and stopped on each CTL Contract
execution by CTL.
The main entry point to the testing interface is Contract.Test.Plutip.runPlutipContract
function:
runPlutipContract
:: forall (distr :: Type) (wallets :: Type) (a :: Type)
. UtxoDistribution distr wallets
=> PlutipConfig
-> distr
-> (wallets -> Contract () a)
-> Aff a
distr
is a specification of how many wallets and with how much funds should be created. It should either be a unit
(for no wallets) or nested tuples containing Array BigInt
- each element of the array specifies an UTxO amount in Lovelaces (0.000001 Ada).
The wallets
argument is either a Unit
or a tuple of KeyWallet
s (with the same nesting level as in distr
, which is guaranteed by UtxoDistribution
).
wallets
should be pattern-matched on, and its components should be passed to withKeyWallet
:
An example Contract
with two actors:
let
distribution :: Array BigInt /\ Array BigInt
distribution =
[ BigInt.fromInt 1_000_000_000
, BigInt.fromInt 2_000_000_000
] /\
[ BigInt.fromInt 2_000_000_000 ]
runPlutipContract config distribution \(alice /\ bob) -> do
withKeyWallet alice do
pure unit -- sign, balance, submit, etc.
withKeyWallet bob do
pure unit -- sign, balance, submit, etc.
In most cases at least two UTxOs per wallet are needed (one of which will be used as collateral, so it should exceed 5_000_000
Lovelace).
Note that during execution WebSocket connection errors may occur. However, payloads are re-sent after these errors, so you can ignore them. These errors will be suppressed in the future..
You can run Plutip tests via CTL's purescriptProject
as well. After creating your project, you can use the runPlutipTest
attribute to create a Plutip testing environment that is suitable for use with your flake's checks
. An example:
{
some-plutip-test = project.runPlutipTest {
name = "some-plutip-test";
testMain = "MyProject.Test.Plutip";
# If you don't need `ctl-server`, you can set the following
# to `false`. Make sure to leave it as `true` (the default)
# if you are calling `applyArgs` in your contracts. This
# must match your `PlutipConfig` -- if `ctlServerConfig` is
# `Nothing`, `ctl-server` will not be spawned
withCtlServer = false;
# The rest of the arguments are passed through to `runPursTest`:
env = { SOME_ENV_VAR = "${some-value}"; };
};
}
- Plutip does not currently provide staking keys. However, arbitrary staking keys can be used if the application does not depend on staking (because payment keys and stake keys don't have to be connected in any way). It's also possible to omit staking keys in many cases by using
mustPayToPubKey
instead ofmustPayToPubKeyAddress
.