Skip to content

Commit

Permalink
Initial contract in aiken + plutus V3 (#1734)
Browse files Browse the repository at this point in the history
### Why

When working on incremental commits feature our head script grew so
hydra scripts publishing became an issue (we pre-publish initial, commit
and head scripts). In order to work around this constraint we decided to
rewrite the initial validator using aiken since it typically produces
smaller script sizes. While doing this work we realized that we can't
construct a valid redeemer from haskell land unless we bump to plutus V3
(which is what aiken expects). Therefore we came up with this PR which
should enable us to continue work on incremental commits (very possibly
we still need to reduce script sizes further or just publish the scripts
in separate transactions).

---

<!-- Consider each and tick it off one way or the other -->
* [x] CHANGELOG updated or not needed
* [x] Documentation updated or not needed
* [x] Haddocks updated or not needed
* [x] No new TODOs introduced or explained herafter
  • Loading branch information
v0d1ch authored Nov 11, 2024
2 parents ed8e0b7 + ea6d674 commit 3be7b22
Show file tree
Hide file tree
Showing 78 changed files with 717 additions and 391 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ changes.
in a new maximum number of head participants being `8`.
- Changes script hashes in `hydra-plutus`

- **BREAKING** Rewrite of the initial script in aiken and update to Plutus V3:
- This makes the initial script smaller by 1337 bytes
- Changes script hashes in `hydra-plutus`

- Fix the bug where commit endpoint drops withdraw redeemers [#1643](https://github.com/cardano-scaling/hydra/issues/1643)

- **BREAKING** Change to `SnapshotConfirmed` and `TxValid` server outputs, as
Expand All @@ -44,6 +48,8 @@ changes.

- Update mithril to `2442.0`



## [0.19.0] - 2024-09-13

- Tested with `cardano-node 9.1.1` and `cardano-cli 9.2.1.0`
Expand Down
16 changes: 8 additions & 8 deletions hydra-cardano-api/src/Hydra/Cardano/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
-- also get rid of era witnesses.
--
-- NOTE: This module also uses the **latest plutus version** available
-- (currently 'PlutusScriptV2'). So make sure that you give it a plutus script
-- (currently 'PlutusScriptV3'). So make sure that you give it a plutus script
-- of the right version (e.g. when compiling and serializing plutus-tx).
module Hydra.Cardano.Api (
-- * Common type-alias
Expand Down Expand Up @@ -232,7 +232,7 @@ pattern ShelleyKeyWitness{shelleyKeyWitness} <-

-- ** PlutusScript

type PlutusScript = Cardano.Api.PlutusScript PlutusScriptV2
type PlutusScript = Cardano.Api.PlutusScript PlutusScriptV3
{-# COMPLETE PlutusScriptSerialised #-}

pattern PlutusScriptSerialised :: ShortByteString -> PlutusScript
Expand All @@ -244,31 +244,31 @@ pattern PlutusScriptSerialised{plutusScriptSerialised} <-

-- ** Script

type Script = Cardano.Api.Script PlutusScriptV2
type Script = Cardano.Api.Script PlutusScriptV3
{-# COMPLETE PlutusScript #-}

pattern PlutusScript :: PlutusScript -> Script
pattern PlutusScript{plutusScript} <-
Cardano.Api.Shelley.PlutusScript _ plutusScript
where
PlutusScript =
Cardano.Api.Shelley.PlutusScript PlutusScriptV2
Cardano.Api.Shelley.PlutusScript PlutusScriptV3

-- ** ScriptInEra

type ScriptInEra = Cardano.Api.ScriptInEra Era

-- ** ScriptLanguage

type ScriptLanguage = Cardano.Api.ScriptLanguage PlutusScriptV2
type ScriptLanguage = Cardano.Api.ScriptLanguage PlutusScriptV3
{-# COMPLETE PlutusScriptLanguage #-}

pattern PlutusScriptLanguage :: ScriptLanguage
pattern PlutusScriptLanguage <-
Cardano.Api.Shelley.PlutusScriptLanguage _
where
PlutusScriptLanguage =
Cardano.Api.Shelley.PlutusScriptLanguage PlutusScriptV2
Cardano.Api.Shelley.PlutusScriptLanguage PlutusScriptV3

-- ** ScriptWitness

Expand All @@ -289,7 +289,7 @@ pattern PlutusScriptWitness
} <-
Cardano.Api.PlutusScriptWitness
_
PlutusScriptV2
PlutusScriptV3
(PScript plutusScriptWitnessScript)
plutusScriptWitnessDatum
plutusScriptWitnessRedeemer
Expand All @@ -298,7 +298,7 @@ pattern PlutusScriptWitness
PlutusScriptWitness =
Cardano.Api.PlutusScriptWitness
scriptLanguageInEra
PlutusScriptV2
PlutusScriptV3
. PScript

-- ** Tx
Expand Down
4 changes: 2 additions & 2 deletions hydra-cardano-api/src/Hydra/Cardano/Api/AddressInEra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import Cardano.Ledger.Credential qualified as Ledger
import Cardano.Ledger.Hashes qualified as Ledger
import Cardano.Ledger.Keys qualified as Ledger
import Hydra.Cardano.Api.Network (Network)
import PlutusLedgerApi.V2 (
import PlutusLedgerApi.V3 (
Address (..),
Credential (..),
StakingCredential (StakingHash, StakingPtr),
fromBuiltin,
)
import PlutusLedgerApi.V2 qualified as Plutus
import PlutusLedgerApi.V3 qualified as Plutus

-- * Extras

Expand Down
2 changes: 1 addition & 1 deletion hydra-cardano-api/src/Hydra/Cardano/Api/Hash.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Cardano.Ledger.Plutus.TxInfo (transKeyHash)
import Cardano.Ledger.SafeHash (unsafeMakeSafeHash)
import Cardano.Ledger.Shelley.Scripts qualified as Ledger
import Data.ByteString qualified as BS
import PlutusLedgerApi.V2 qualified as Plutus
import PlutusLedgerApi.V3 qualified as Plutus

-- * Type conversions

Expand Down
2 changes: 1 addition & 1 deletion hydra-cardano-api/src/Hydra/Cardano/Api/PolicyId.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Cardano.Ledger.Alonzo.Plutus.TxInfo qualified as Ledger
import Cardano.Ledger.Hashes qualified as Ledger
import Cardano.Ledger.Mary.Value qualified as Ledger
import Hydra.Cardano.Api.ScriptHash ()
import PlutusLedgerApi.V2 (CurrencySymbol, fromBuiltin, unCurrencySymbol)
import PlutusLedgerApi.V3 (CurrencySymbol, fromBuiltin, unCurrencySymbol)

-- * Orphans

Expand Down
6 changes: 3 additions & 3 deletions hydra-cardano-api/src/Hydra/Cardano/Api/ReferenceScript.hs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ module Hydra.Cardano.Api.ReferenceScript where
import Hydra.Cardano.Api.Prelude

import Hydra.Cardano.Api.PlutusScript (fromPlutusScript)
import PlutusLedgerApi.V2 qualified as Plutus
import PlutusLedgerApi.V3 qualified as Plutus

-- | Construct a 'ReferenceScript' from any given Plutus script.
--
-- NOTE: The script is treated as a 'PlutusScriptV2'
-- NOTE: The script is treated as a 'PlutusScriptV3'
mkScriptRef :: Plutus.SerialisedScript -> ReferenceScript Era
mkScriptRef =
ReferenceScript babbageBasedEra
. toScriptInAnyLang
. PlutusScript PlutusScriptV2
. PlutusScript PlutusScriptV3
. fromPlutusScript

-- | Construct a PlutusV3 'ReferenceScript' from any given Plutus script.
Expand Down
2 changes: 1 addition & 1 deletion hydra-cardano-api/src/Hydra/Cardano/Api/ScriptData.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Data.Aeson (Value (String), withText)
import Data.ByteString qualified as BS
import Data.ByteString.Base16 qualified as Base16
import Data.Map qualified as Map
import PlutusLedgerApi.V2 qualified as Plutus
import PlutusLedgerApi.V3 qualified as Plutus
import Test.QuickCheck (arbitrarySizedNatural, choose, oneof, scale, sized, vector)

-- * Extras
Expand Down
2 changes: 1 addition & 1 deletion hydra-cardano-api/src/Hydra/Cardano/Api/ScriptHash.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ hashScriptInAnyLang (ScriptInAnyLang _ script) =

instance Arbitrary ScriptHash where
arbitrary = do
hashScript . PlutusScript PlutusScriptV2 <$> arbitrary
hashScript . PlutusScript PlutusScriptV3 <$> arbitrary
2 changes: 1 addition & 1 deletion hydra-cardano-api/src/Hydra/Cardano/Api/TxBody.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Data.Map qualified as Map
import Hydra.Cardano.Api.PlutusScript (fromLedgerScript)
import Hydra.Cardano.Api.PolicyId (toLedgerPolicyID, toLedgerScriptHash)
import Hydra.Cardano.Api.TxIn (toLedgerTxIn)
import PlutusLedgerApi.V2 qualified as Plutus
import PlutusLedgerApi.V3 qualified as Plutus

-- | Find and deserialise from 'ScriptData', a redeemer from the transaction
-- associated to the given input.
Expand Down
10 changes: 7 additions & 3 deletions hydra-cardano-api/src/Hydra/Cardano/Api/TxIn.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import Hydra.Cardano.Api.Prelude

import Cardano.Ledger.BaseTypes qualified as Ledger
import Cardano.Ledger.Binary qualified as Ledger
import Cardano.Ledger.Plutus (transTxIn)
import Cardano.Ledger.Plutus (transSafeHash)
import Cardano.Ledger.TxIn qualified as Ledger
import Data.ByteString qualified as BS
import Data.Set qualified as Set
import PlutusLedgerApi.V2 qualified as Plutus
import PlutusLedgerApi.V3 qualified as Plutus
import Test.QuickCheck (choose, vectorOf)

-- * Extras
Expand Down Expand Up @@ -54,7 +54,11 @@ fromPlutusTxOutRef (Plutus.TxOutRef (Plutus.TxId bytes) ix) =

-- | Convert a cardano-api 'TxIn' into a plutus 'TxOutRef'.
toPlutusTxOutRef :: TxIn -> Plutus.TxOutRef
toPlutusTxOutRef = transTxIn . toLedgerTxIn
toPlutusTxOutRef txIn =
-- XXX: The upstream 'transTxIn' works only with the the PlutusV1 type, so we
-- needed to vendor its definition here.
let (Ledger.TxIn (Ledger.TxId safe) txIx) = toLedgerTxIn txIn
in Plutus.TxOutRef (Plutus.TxId $ transSafeHash safe) (toInteger $ Ledger.txIxToInt txIx)

-- * Arbitrary values

Expand Down
4 changes: 2 additions & 2 deletions hydra-cardano-api/src/Hydra/Cardano/Api/TxOut.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import Hydra.Cardano.Api.Hash (unsafeScriptDataHashFromBytes)
import Hydra.Cardano.Api.Network (Network)
import Hydra.Cardano.Api.ScriptData (toScriptData)
import Hydra.Cardano.Api.Value (fromPlutusValue, minUTxOValue)
import PlutusLedgerApi.V2 (OutputDatum (..), fromBuiltin)
import PlutusLedgerApi.V2 qualified as Plutus
import PlutusLedgerApi.V3 (OutputDatum (..), fromBuiltin)
import PlutusLedgerApi.V3 qualified as Plutus

-- * Extras

Expand Down
4 changes: 2 additions & 2 deletions hydra-cardano-api/src/Hydra/Cardano/Api/Value.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import GHC.IsList (IsList (..))
import Hydra.Cardano.Api.CtxUTxO (ToUTxOContext (..))
import Hydra.Cardano.Api.PolicyId (fromPlutusCurrencySymbol)
import PlutusLedgerApi.V1.Value (flattenValue)
import PlutusLedgerApi.V2 (adaSymbol, adaToken, fromBuiltin, unTokenName)
import PlutusLedgerApi.V2 qualified as Plutus
import PlutusLedgerApi.V3 (adaSymbol, adaToken, fromBuiltin, unTokenName)
import PlutusLedgerApi.V3 qualified as Plutus

-- * Extras

Expand Down
3 changes: 1 addition & 2 deletions hydra-cluster/hydra-cluster.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ library
build-depends:
, aeson
, async
, base >=4.7 && <5
, base >=4.7 && <5
, bytestring
, cardano-slotting
, containers
Expand All @@ -106,7 +106,6 @@ library
, lens
, lens-aeson
, optparse-applicative
, plutus-ledger-api:plutus-ledger-api-testlib
, process
, QuickCheck
, req
Expand Down
5 changes: 2 additions & 3 deletions hydra-cluster/src/Hydra/Cluster/Scenarios.hs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ 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 (verificationKeyToOnChainId)
import Hydra.Tx.Utils (dummyValidatorScript, verificationKeyToOnChainId)
import HydraNode (
HydraClient (..),
HydraNodeLog,
Expand Down Expand Up @@ -110,7 +110,6 @@ import Network.HTTP.Req (
)
import Network.HTTP.Simple (getResponseBody, httpJSON, setRequestBodyJSON)
import Network.HTTP.Types (urlEncode)
import PlutusLedgerApi.Test.Examples (alwaysSucceedingNAryFunction)
import System.Directory (removeDirectoryRecursive)
import System.FilePath ((</>))
import Test.Hydra.Tx.Fixture (testNetworkId)
Expand Down Expand Up @@ -445,7 +444,7 @@ singlePartyCommitsScriptBlueprint tracer workDir node hydraScriptsTxId =
output "GetUTxOResponse" ["headId" .= headId, "utxo" .= (scriptUTxO <> scriptUTxO')]
where
prepareScriptPayload = do
let script = alwaysSucceedingNAryFunction 3
let script = dummyValidatorScript
let serializedScript = PlutusScriptSerialised script
let scriptAddress = mkScriptAddress networkId serializedScript
let datumHash = mkTxOutDatumHash ()
Expand Down
2 changes: 1 addition & 1 deletion hydra-node/bench/tx-cost/TxCost.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import Hydra.Ledger.Cardano.Evaluate (
import Hydra.Ledger.Cardano.Time (slotNoFromUTCTime)
import Hydra.Plutus.Orphans ()
import Hydra.Tx.Snapshot (genConfirmedSnapshot)
import PlutusLedgerApi.V2 (toBuiltinData)
import PlutusLedgerApi.V3 (toBuiltinData)
import PlutusTx.Builtins (lengthOfByteString, serialiseData)
import Test.Hydra.Tx.Gen (genOutput, genUTxOAdaOnlyOfSize)

Expand Down
7 changes: 3 additions & 4 deletions hydra-node/hydra-node.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,10 @@ test-suite tests
, lens
, lens-aeson
, network-simple-wss
, plutus-ledger-api >=1.1.1.0
, plutus-ledger-api:plutus-ledger-api-testlib
, plutus-ledger-api >=1.1.1.0
, plutus-tx
, QuickCheck
, quickcheck-dynamic >=3.4 && <3.5
, quickcheck-dynamic >=3.4 && <3.5
, quickcheck-instances
, random
, regex-tdfa
Expand All @@ -373,7 +372,7 @@ test-suite tests
, text
, time
, tls
, typed-protocols-examples >=0.1.0.0
, typed-protocols-examples >=0.1.0.0
, vector
, websockets

Expand Down
2 changes: 1 addition & 1 deletion hydra-node/src/Hydra/Chain.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ maxMainnetLovelace = Coin 100_000_000
-- validators (see 'computeCollectComCost' 'computeAbortCost'). A too high
-- enough number would be detected by property and acceptance tests.
maximumNumberOfParties :: Int
maximumNumberOfParties = 8
maximumNumberOfParties = 7

-- | Data type used to post transactions on chain. It holds everything to
-- construct corresponding Head protocol transactions.
Expand Down
24 changes: 11 additions & 13 deletions hydra-node/src/Hydra/Chain/Direct/State.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import Hydra.Cardano.Api (
NetworkId (Mainnet, Testnet),
NetworkMagic (NetworkMagic),
PaymentKey,
PlutusScriptV2,
PlutusScriptV3,
PolicyId,
Quantity (..),
Expand Down Expand Up @@ -85,10 +84,9 @@ import Hydra.Contract.Deposit qualified as Deposit
import Hydra.Contract.Head qualified as Head
import Hydra.Contract.HeadState qualified as Head
import Hydra.Contract.HeadTokens (headPolicyId, mkHeadTokenScript)
import Hydra.Contract.Initial qualified as Initial
import Hydra.Ledger.Cardano.Evaluate (genPointInTimeBefore, genValidityBoundsFromContestationPeriod, slotLength, systemStart)
import Hydra.Ledger.Cardano.Time (slotNoFromUTCTime)
import Hydra.Plutus (commitValidatorScript)
import Hydra.Plutus (commitValidatorScript, initialValidatorScript)
import Hydra.Plutus.Extras (posixToUTCTime)
import Hydra.Tx (
CommitBlueprintTx (..),
Expand Down Expand Up @@ -439,9 +437,9 @@ abort ctx seedTxIn spendableUTxO committedUTxO = do

commitScript = fromPlutusScript @PlutusScriptV3 commitValidatorScript

headScript = fromPlutusScript @PlutusScriptV2 Head.validatorScript
headScript = fromPlutusScript @PlutusScriptV3 Head.validatorScript

initialScript = fromPlutusScript @PlutusScriptV2 Initial.validatorScript
initialScript = fromPlutusScript @PlutusScriptV3 initialValidatorScript

headTokenScript = mkHeadTokenScript seedTxIn

Expand Down Expand Up @@ -473,7 +471,7 @@ collect ctx headId headParameters utxoToCollect spendableUTxO = do
pure $
collectComTx networkId scriptRegistry ownVerificationKey headId headParameters headUTxO commits utxoToCollect
where
headScript = fromPlutusScript @PlutusScriptV2 Head.validatorScript
headScript = fromPlutusScript @PlutusScriptV3 Head.validatorScript

commitScript = fromPlutusScript @PlutusScriptV3 commitValidatorScript

Expand Down Expand Up @@ -520,8 +518,8 @@ increment ctx spendableUTxO headId headParameters incrementingSnapshot depositTx
Left SnapshotIncrementUTxOIsNull
| otherwise -> Right $ incrementTx scriptRegistry ownVerificationKey headId headParameters headUTxO sn (UTxO.singleton (depositedIn, depositedOut)) upperValiditySlot
where
headScript = fromPlutusScript @PlutusScriptV2 Head.validatorScript
depositScript = fromPlutusScript @PlutusScriptV2 Deposit.validatorScript
headScript = fromPlutusScript @PlutusScriptV3 Head.validatorScript
depositScript = fromPlutusScript @PlutusScriptV3 Deposit.validatorScript

Snapshot{utxoToCommit} = sn

Expand Down Expand Up @@ -560,7 +558,7 @@ decrement ctx spendableUTxO headId headParameters decrementingSnapshot = do
Left DecrementValueNegative
Right $ decrementTx scriptRegistry ownVerificationKey headId headParameters headUTxO sn sigs
where
headScript = fromPlutusScript @PlutusScriptV2 Head.validatorScript
headScript = fromPlutusScript @PlutusScriptV3 Head.validatorScript

decommitValue = foldMap txOutValue $ fromMaybe mempty $ utxoToDecommit sn

Expand Down Expand Up @@ -613,7 +611,7 @@ recover ctx headId depositedTxId spendableUTxO lowerValiditySlot = do
then Left InvalidHeadIdInRecover{headId}
else Right $ recoverTx depositedTxId deposited lowerValiditySlot
where
depositScript = fromPlutusScript @PlutusScriptV2 Deposit.validatorScript
depositScript = fromPlutusScript @PlutusScriptV3 Deposit.validatorScript
ChainContext{networkId} = ctx

-- | Construct a close transaction spending the head output in given 'UTxO',
Expand Down Expand Up @@ -652,7 +650,7 @@ close ctx spendableUTxO headId HeadParameters{parties, contestationPeriod} openV
}
pure $ closeTx scriptRegistry ownVerificationKey headId openVersion confirmedSnapshot startSlotNo pointInTime openThreadOutput
where
headScript = fromPlutusScript @PlutusScriptV2 Head.validatorScript
headScript = fromPlutusScript @PlutusScriptV3 Head.validatorScript

ChainContext{ownVerificationKey, scriptRegistry} = ctx

Expand Down Expand Up @@ -721,7 +719,7 @@ contest ctx spendableUTxO headId contestationPeriod openVersion contestingSnapsh

ChainContext{ownVerificationKey, scriptRegistry} = ctx

headScript = fromPlutusScript @PlutusScriptV2 Head.validatorScript
headScript = fromPlutusScript @PlutusScriptV3 Head.validatorScript

data FanoutTxError
= CannotFindHeadOutputToFanout
Expand Down Expand Up @@ -758,7 +756,7 @@ fanout ctx spendableUTxO seedTxIn utxo utxoToDecommit deadlineSlotNo = do

ChainContext{scriptRegistry} = ctx

headScript = fromPlutusScript @PlutusScriptV2 Head.validatorScript
headScript = fromPlutusScript @PlutusScriptV3 Head.validatorScript

checkHeadDatum headUTxO@(_, headOutput) = do
headDatum <-
Expand Down
Loading

0 comments on commit 3be7b22

Please sign in to comment.