Skip to content

Commit

Permalink
Import schnorkell plutus
Browse files Browse the repository at this point in the history
add singlePartyUsesSchnorrkelScriptOnL2 scenario test

Finalize schnorkel test case

There is some refactoring in order but the test itself is fine.

Update plutus source-repository-package

treefmt

fixup

Have some ada for the min UTxO

Almost there; insufficient collateral now

Trying to be more clear about the UTxOs to pay for things

WIP on schnorrkel; just missing script as input
  • Loading branch information
locallycompact authored and noonio committed Jan 13, 2025
1 parent e7252f8 commit 434a0df
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 16 deletions.
22 changes: 22 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,25 @@ program-options
constraints:
quickcheck-instances==0.3.31,
data-default==0.7.1.3

source-repository-package
type: git
location: https://github.com/locallycompact/cardano-base
tag: 1a800a0c1392935256aebabf6c1fdefe5e8b34ae
--sha256: sha256-LXYzVyWHWBS361NR4pL/Jbilnv48z6ZozltaL2/ym2s=
subdir:
cardano-crypto-class

source-repository-package
type: git
location: https://github.com/locallycompact/plutus
tag: b117b4460b5b5da2a599db8693b18dacd811bb91
--sha256: sha256-GUPwIwbTOy/eTBhjOwrR+XwJsML/jmBlAf1qU6zWvd8=
subdir:
prettyprinter-configurable
plutus-core
plutus-ledger-api
plutus-tx-plugin
plutus-tx

allow-newer: cardano-crypto-class
100 changes: 98 additions & 2 deletions hydra-cluster/src/Hydra/Cluster/Scenarios.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import CardanoClient (
QueryPoint (QueryTip),
RunningNode (..),
buildTransaction,
buildTransactionWithBody,
queryProtocolParameters,
queryTip,
queryUTxOFor,
submitTx,
waitForUTxO,
)
import Hydra.Cardano.Api.Pretty (renderTxWithUTxO)
import CardanoNode (NodeLog)
import Control.Concurrent.Async (mapConcurrently_)
import Control.Lens ((^..), (^?))
Expand All @@ -35,13 +38,17 @@ import Hydra.API.HTTPServer (
)
import Hydra.Cardano.Api (
Coin (..),
mkTxIn,
File (File),
Key (SigningKey),
KeyWitnessInCtx (KeyWitnessForSpending),
PaymentKey,
Tx,
TxId,
UTxO,
addTxIns,
addTxInsCollateral,
addTxOuts,
defaultTxBodyContent,
getTxBody,
getTxId,
Expand All @@ -51,18 +58,23 @@ import Hydra.Cardano.Api (
mkScriptAddress,
mkScriptDatum,
mkScriptWitness,
mkTxOutAutoBalance,
mkTxOutDatumHash,
mkVkAddress,
scriptWitnessInCtx,
selectLovelace,
setTxFee,
signTx,
toScriptData,
txOutValue,
utxoFromTx,
writeFileTextEnvelope,
pattern BuildTxWith,
pattern KeyWitness,
pattern PlutusScriptSerialised,
pattern ReferenceScriptNone,
pattern ScriptWitness,
pattern TxFeeExplicit,
pattern TxOut,
pattern TxOutDatumNone,
)
Expand All @@ -72,12 +84,12 @@ import Hydra.Cluster.Fixture (Actor (..), actorName, alice, aliceSk, aliceVk, bo
import Hydra.Cluster.Mithril (MithrilLog)
import Hydra.Cluster.Options (Options)
import Hydra.Cluster.Util (chainConfigFor, keysFor, modifyConfig, setNetworkId)
import Hydra.Ledger.Cardano (mkSimpleTx, mkTransferTx, unsafeBuildTransaction)
import Hydra.Ledger.Cardano (changePParams, mkSimpleTx, mkTransferTx, unsafeBuildTransaction)
import Hydra.Logging (Tracer, traceWith)
import Hydra.Options (DirectChainConfig (..), networkId, startChainFrom)
import Hydra.Tx (HeadId, IsTx (balance), Party, txId)
import Hydra.Tx.ContestationPeriod (ContestationPeriod (UnsafeContestationPeriod), fromNominalDiffTime)
import Hydra.Tx.Utils (dummyValidatorScript, verificationKeyToOnChainId)
import Hydra.Tx.Utils (dummyValidatorScript, schnorrkelValidatorScript, verificationKeyToOnChainId)
import HydraNode (
HydraClient (..),
HydraNodeLog,
Expand Down Expand Up @@ -381,6 +393,90 @@ singlePartyCommitsFromExternal tracer workDir node hydraScriptsTxId =
where
RunningNode{nodeSocket, blockTime} = node

singlePartyUsesSchnorrkelScriptOnL2 ::
Tracer IO EndToEndLog ->
FilePath ->
RunningNode ->
[TxId] ->
IO ()
singlePartyUsesSchnorrkelScriptOnL2 tracer workDir node hydraScriptsTxId =
( `finally`
do
returnFundsToFaucet tracer node Alice
returnFundsToFaucet tracer node AliceFunds
)
$ do
refuelIfNeeded tracer node Alice 250_000_000
aliceChainConfig <- chainConfigFor Alice workDir nodeSocket hydraScriptsTxId [] $ UnsafeContestationPeriod 100
let hydraNodeId = 1
let hydraTracer = contramap FromHydraNode tracer
withHydraNode hydraTracer aliceChainConfig workDir hydraNodeId aliceSk [] [1] $ \n1 -> do
send n1 $ input "Init" []
headId <- waitMatch (10 * blockTime) n1 $ headIsInitializingWith (Set.fromList [alice])

(walletVk, walletSk) <- keysFor AliceFunds

-- Create money on L1
utxoToCommit <- seedFromFaucet node walletVk 100_000_000 (contramap FromFaucet tracer)

-- Push it into L2
requestCommitTx n1 utxoToCommit <&> signTx walletSk >>= \tx -> do
putStrLn $ renderTxWithUTxO utxoToCommit tx
submitTx node tx

-- Check UTxO is present in L2
waitFor hydraTracer (10 * blockTime) [n1] $
output "HeadIsOpen" ["utxo" .= toJSON utxoToCommit, "headId" .= headId]

pparams <- queryProtocolParameters networkId nodeSocket QueryTip

-- Send the UTxO to a script; in preparation for running the script
let serializedScript = PlutusScriptSerialised dummyValidatorScript
-- let serializedScript = PlutusScriptSerialised schnorrkelValidatorScript
let scriptAddress = mkScriptAddress networkId serializedScript
let scriptOutput =
mkTxOutAutoBalance
pparams
scriptAddress
(lovelaceToValue 0) -- Autobalanced
(mkTxOutDatumHash ())
ReferenceScriptNone

Right tx <- buildTransaction networkId nodeSocket (mkVkAddress networkId walletVk) utxoToCommit [] [scriptOutput]

let signedL2tx = signTx walletSk tx
send n1 $ input "NewTx" ["transaction" .= signedL2tx]

putStrLn $ renderTxWithUTxO utxoToCommit signedL2tx

waitMatch 10 n1 $ \v -> do
guard $ v ^? key "tag" == Just "SnapshotConfirmed"
guard $
toJSON signedL2tx
`elem` (v ^.. key "snapshot" . key "confirmed" . values)

-- Finally, take money from the script
let scriptWitness =
BuildTxWith $
ScriptWitness scriptWitnessInCtx $
mkScriptWitness serializedScript (mkScriptDatum ()) (toScriptData ())

-- TODO: Include the script as an input!
let body =
defaultTxBodyContent
& addTxIns [(mkTxIn signedL2tx 0, scriptWitness)]

tx <- either (failure . show) pure =<< buildTransactionWithBody networkId nodeSocket (mkVkAddress networkId walletVk) body utxoToCommit
let signedL2tx = signTx walletSk tx

waitMatch 10 n1 $ \v -> do
guard $ v ^? key "tag" == Just "SnapshotConfirmed"
guard $
toJSON signedL2tx
`elem` (v ^.. key "snapshot" . key "confirmed" . values)
where
RunningNode{networkId, nodeSocket, blockTime} = node

singlePartyCommitsScriptBlueprint ::
Tracer IO EndToEndLog ->
FilePath ->
Expand Down
6 changes: 6 additions & 0 deletions hydra-cluster/test/Test/EndToEndSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import Hydra.Cluster.Scenarios (
singlePartyCommitsFromExternalTxBlueprint,
singlePartyCommitsScriptBlueprint,
singlePartyHeadFullLifeCycle,
singlePartyUsesSchnorrkelScriptOnL2,
testPreventResumeReconfiguredPeer,
threeNodesNoErrorsOnOpen,
)
Expand Down Expand Up @@ -178,6 +179,11 @@ spec = around (showLogsOnFailure "EndToEndSpec") $ do
withCardanoNodeDevnet (contramap FromCardanoNode tracer) tmpDir $ \node ->
publishHydraScriptsAs node Faucet
>>= singlePartyCommitsFromExternal tracer tmpDir node
it "can use a schnorrkel script on L2" $ \tracer -> do
withClusterTempDir $ \tmpDir -> do
withCardanoNodeDevnet (contramap FromCardanoNode tracer) tmpDir $ \node ->
publishHydraScriptsAs node Faucet
>>= singlePartyUsesSchnorrkelScriptOnL2 tracer tmpDir node
it "can submit a signed user transaction" $ \tracer -> do
withClusterTempDir $ \tmpDir -> do
withCardanoNodeDevnet (contramap FromCardanoNode tracer) tmpDir $ \node ->
Expand Down
40 changes: 28 additions & 12 deletions hydra-node/src/Hydra/Chain/CardanoClient.hs
Original file line number Diff line number Diff line change
Expand Up @@ -63,26 +63,19 @@ mkCardanoClient networkId nodeSocket =

-- * Tx Construction / Submission

-- | Construct a simple payment consuming some inputs and producing some
-- outputs (no certificates or withdrawals involved).
--
-- On success, the returned transaction is fully balanced. On error, return
-- `TxBodyErrorAutoBalance`.
buildTransaction ::
buildTransactionWithBody ::
-- | Current network identifier
NetworkId ->
-- | Filepath to the cardano-node's domain socket
SocketPath ->
-- | Change address to send
AddressInEra ->
-- | Body
TxBodyContent BuildTx ->
-- | Unspent transaction outputs to spend.
UTxO ->
-- | Collateral inputs.
[TxIn] ->
-- | Outputs to create.
[TxOut CtxTx] ->
IO (Either (TxBodyErrorAutoBalance Era) Tx)
buildTransaction networkId socket changeAddress utxoToSpend collateral outs = do
buildTransactionWithBody networkId socket changeAddress body utxoToSpend = do
pparams <- queryProtocolParameters networkId socket QueryTip
systemStart <- querySystemStart networkId socket QueryTip
eraHistory <- queryEraHistory networkId socket QueryTip
Expand All @@ -98,9 +91,32 @@ buildTransaction networkId socket changeAddress utxoToSpend collateral outs = do
mempty
mempty
(UTxO.toApi utxoToSpend)
(bodyContent pparams)
body
changeAddress
Nothing

-- | Construct a simple payment consuming some inputs and producing some
-- outputs (no certificates or withdrawals involved).
--
-- On success, the returned transaction is fully balanced. On error, return
-- `TxBodyErrorAutoBalance`.
buildTransaction ::
-- | Current network identifier
NetworkId ->
-- | Filepath to the cardano-node's domain socket
SocketPath ->
-- | Change address to send
AddressInEra ->
-- | Unspent transaction outputs to spend.
UTxO ->
-- | Collateral inputs.
[TxIn] ->
-- | Outputs to create.
[TxOut CtxTx] ->
IO (Either (TxBodyErrorAutoBalance Era) Tx)
buildTransaction networkId socket changeAddress utxoToSpend collateral outs = do
pparams <- queryProtocolParameters networkId socket QueryTip
buildTransactionWithBody networkId socket changeAddress (bodyContent pparams) utxoToSpend
where
-- NOTE: 'makeTransactionBodyAutoBalance' overwrites this.
dummyFeeForBalancing = TxFeeExplicit 0
Expand Down
18 changes: 17 additions & 1 deletion hydra-plutus/src/Hydra/Contract/Dummy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,28 @@

module Hydra.Contract.Dummy where

import Hydra.Prelude
import Hydra.Cardano.Api (PlutusScriptVersion (PlutusScriptV3))
import Hydra.Plutus.Extras (ValidatorType, scriptValidatorHash, wrapValidator)
import Hydra.Prelude hiding ((==))

import Hydra.Cardano.Api (PlutusScript, pattern PlutusScriptSerialised)
import Hydra.Plutus.Extras (ValidatorType, wrapValidator)
import PlutusLedgerApi.V3 (BuiltinData, ScriptContext, serialiseCompiledCode, toOpaque)
import PlutusTx (CompiledCode, compile)
import PlutusTx.Builtins (schnorrkel)
import PlutusTx.Prelude (Eq (..))

schnorrkelValidator :: BuiltinData -> BuiltinData -> ScriptContext -> Bool
schnorrkelValidator _ _ _ = "" == schnorrkel ""

schnorrkelValidatorScript :: SerialisedScript
schnorrkelValidatorScript = serialiseCompiledCode compiledDummyValidator

compiledSchnorrkelValidator :: CompiledCode ValidatorType
compiledSchnorrkelValidator =
$$(PlutusTx.compile [||fakeWrap schnorrkelValidator||])
where
wrap = wrapValidator @BuiltinData @BuiltinData

dummyValidator :: BuiltinData -> BuiltinData -> ScriptContext -> Bool
dummyValidator _ _ _ = True
Expand Down
4 changes: 4 additions & 0 deletions hydra-tx/src/Hydra/Ledger/Cardano/Builder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ addTxInsSpending :: [TxIn] -> TxBodyContent BuildTx -> TxBodyContent BuildTx
addTxInsSpending ins =
addTxIns ((,BuildTxWith $ KeyWitness KeyWitnessForSpending) <$> ins)

changePParams :: PParams (ShelleyLedgerEra Era) -> TxBodyContent BuildTx -> TxBodyContent BuildTx
changePParams pparams tx =
tx{txProtocolParams = BuildTxWith $ Just $ LedgerProtocolParameters pparams}

-- | Mint tokens with given plutus minting script and redeemer.
mintTokens :: ToScriptData redeemer => PlutusScript -> redeemer -> [(AssetName, Quantity)] -> TxBodyContent BuildTx -> TxBodyContent BuildTx
mintTokens script redeemer assets = addTxMintValue newTokens
Expand Down
3 changes: 2 additions & 1 deletion hydra-tx/src/Hydra/Tx/Utils.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module Hydra.Tx.Utils (
module Hydra.Tx.Utils,
dummyValidatorScript,
schnorrkelValidatorScript,
) where

import Hydra.Cardano.Api
Expand All @@ -13,7 +14,7 @@ import Control.Lens ((.~), (^.))
import Data.Map.Strict qualified as Map
import Data.Maybe.Strict (StrictMaybe (..))
import GHC.IsList (IsList (..))
import Hydra.Contract.Dummy (dummyValidatorScript)
import Hydra.Contract.Dummy (dummyValidatorScript, schnorrkelValidatorScript)
import Hydra.Contract.Util (hydraHeadV1)
import Hydra.Tx.OnChainId (OnChainId (..))
import Ouroboros.Consensus.Shelley.Eras qualified as Ledger
Expand Down

0 comments on commit 434a0df

Please sign in to comment.