Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement certifying and withdrawing Plutus script tests #3318

Merged
merged 6 commits into from Dec 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 2 additions & 13 deletions bench/tx-generator/src/Cardano/Benchmarking/Script/Aeson.hs
Expand Up @@ -10,18 +10,16 @@ import Prelude
import System.Exit
import Data.Functor.Identity
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Dependent.Sum
import qualified Data.ByteString.Lazy as BSL
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS (lines)
import Data.Aeson
import Data.Aeson.Types
import Data.Aeson.Encode.Pretty
import qualified Data.Attoparsec.ByteString as Atto

import qualified Ouroboros.Network.Magic as Ouroboros (NetworkMagic(..))
import Cardano.Api (AnyCardanoEra(..), CardanoEra(..), ScriptData, ScriptDataJsonSchema(..), NetworkId(..)
import Cardano.Api (ScriptData, ScriptDataJsonSchema(..), NetworkId(..)
, scriptDataFromJson, scriptDataToJson)
import Cardano.Api.Shelley (ProtocolParameters)
import Cardano.CLI.Types (SigningKeyFile(..))
Expand All @@ -46,15 +44,6 @@ prettyPrint = encodePretty' conf
, "runBenchmark", "asyncBenchmark", "waitBenchmark", "cancelBenchmark"
, "reserved" ]

instance FromJSON AnyCardanoEra where
parseJSON = withText "AnyCardanoEra" $ \case
"Byron" -> return $ AnyCardanoEra ByronEra
"Shelley" -> return $ AnyCardanoEra ShelleyEra
"Allegra" -> return $ AnyCardanoEra AllegraEra
"Mary" -> return $ AnyCardanoEra MaryEra
"Alonzo" -> return $ AnyCardanoEra AlonzoEra
era -> parseFail ("Error: Cannot parse JSON value '" <> Text.unpack era <> "' to AnyCardanoEra.")

jsonOptionsUnTaggedSum :: Options
jsonOptionsUnTaggedSum = defaultOptions { sumEncoding = ObjectWithSingleField }

Expand Down Expand Up @@ -169,7 +158,7 @@ instance FromJSON SigningKeyFile where parseJSON a = SigningKeyFile <$> parseJS
instance ToJSON NetworkId where
toJSON Mainnet = "Mainnet"
toJSON (Testnet (Ouroboros.NetworkMagic t)) = object ["Testnet" .= t]

instance FromJSON NetworkId where
parseJSON j = case j of
(String "Mainnet") -> return Mainnet
Expand Down
1 change: 1 addition & 0 deletions cardano-api/gen/Gen/Cardano/Api/Typed.hs
Expand Up @@ -39,6 +39,7 @@ module Gen.Cardano.Api.Typed
, genStakeAddress
, genTx
, genTxBody
, genLovelace
, genValue
, genValueDefault
, genVerificationKey
Expand Down
9 changes: 9 additions & 0 deletions cardano-api/src/Cardano/Api/Address.hs
Expand Up @@ -515,6 +515,15 @@ instance SerialiseAddress StakeAddress where
either (const Nothing) Just $
deserialiseFromBech32 AsStakeAddress t

instance ToJSON StakeAddress where
toJSON s = Aeson.String $ serialiseAddress s

instance FromJSON StakeAddress where
parseJSON = withText "StakeAddress" $ \str ->
case deserialiseAddress AsStakeAddress str of
Nothing ->
fail $ "Error while deserialising StakeAddress: " <> Text.unpack str
Just sAddr -> pure sAddr

makeStakeAddress :: NetworkId
-> StakeCredential
Expand Down
9 changes: 7 additions & 2 deletions cardano-api/src/Cardano/Api/Block.hs
@@ -1,3 +1,4 @@
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
Expand Down Expand Up @@ -46,7 +47,7 @@ module Cardano.Api.Block (

import Prelude

import Data.Aeson (ToJSON (..), object, (.=))
import Data.Aeson (FromJSON (..), ToJSON (..), object, (.=))
import qualified Data.Aeson as Aeson
import qualified Data.ByteString as BS
import qualified Data.ByteString.Short as SBS
Expand All @@ -69,15 +70,16 @@ import qualified Ouroboros.Network.Block as Consensus

import qualified Cardano.Chain.Block as Byron
import qualified Cardano.Chain.UTxO as Byron
import qualified Cardano.Ledger.Block as Ledger
import qualified Cardano.Ledger.Era as Ledger
import qualified Cardano.Protocol.TPraos.BHeader as TPraos
import qualified Cardano.Ledger.Block as Ledger

import Cardano.Api.Eras
import Cardano.Api.HasTypeProxy
import Cardano.Api.Hash
import Cardano.Api.Modes
import Cardano.Api.SerialiseRaw
import Cardano.Api.SerialiseUsing
import Cardano.Api.Tx

{- HLINT ignore "Use lambda" -}
Expand Down Expand Up @@ -237,6 +239,9 @@ data BlockHeader = BlockHeader !SlotNo
-- representation.
newtype instance Hash BlockHeader = HeaderHash SBS.ShortByteString
deriving (Eq, Ord, Show)
deriving (ToJSON, FromJSON) via UsingRawBytesHex (Hash BlockHeader)



instance SerialiseAsRawBytes (Hash BlockHeader) where
serialiseToRawBytes (HeaderHash bs) = SBS.fromShort bs
Expand Down
14 changes: 13 additions & 1 deletion cardano-api/src/Cardano/Api/Eras.hs
Expand Up @@ -46,7 +46,8 @@ module Cardano.Api.Eras

import Prelude

import Data.Aeson (ToJSON, toJSON)
import Data.Aeson (FromJSON (..), ToJSON, toJSON, withText)
import qualified Data.Text as Text
import Data.Type.Equality (TestEquality (..), (:~:) (Refl))

import Ouroboros.Consensus.Shelley.Eras as Ledger (StandardAllegra, StandardAlonzo,
Expand Down Expand Up @@ -229,6 +230,17 @@ instance Enum AnyCardanoEra where
instance ToJSON AnyCardanoEra where
toJSON (AnyCardanoEra era) = toJSON era

instance FromJSON AnyCardanoEra where
parseJSON = withText "AnyCardanoEra"
$ \case
"Byron" -> pure $ AnyCardanoEra ByronEra
"Shelley" -> pure $ AnyCardanoEra ShelleyEra
"Allegra" -> pure $ AnyCardanoEra AllegraEra
"Mary" -> pure $ AnyCardanoEra MaryEra
"Alonzo" -> pure $ AnyCardanoEra AlonzoEra
wrong -> fail $ "Failed to parse unknown era: " <> Text.unpack wrong


-- | Like the 'AnyCardanoEra' constructor but does not demand a 'IsCardanoEra'
-- class constraint.
--
Expand Down
15 changes: 12 additions & 3 deletions cardano-api/src/Cardano/Api/KeysShelley.hs
Expand Up @@ -37,11 +37,12 @@ module Cardano.Api.KeysShelley (

import Prelude

import Data.Aeson.Types (ToJSONKey (..), toJSONKeyText)
import Data.Aeson.Types (ToJSONKey (..), toJSONKeyText, withText)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.Maybe
import Data.String (IsString (..))
import qualified Data.Text as Text

import qualified Cardano.Crypto.DSIGN.Class as Crypto
import qualified Cardano.Crypto.Hash.Class as Crypto
Expand All @@ -52,8 +53,9 @@ import qualified Cardano.Ledger.Keys as Shelley

import Cardano.Ledger.Crypto (StandardCrypto)

import Cardano.Api.HasTypeProxy
import Cardano.Api.Error
import Cardano.Api.Hash
import Cardano.Api.HasTypeProxy
import Cardano.Api.Key
import Cardano.Api.SerialiseBech32
import Cardano.Api.SerialiseCBOR
Expand All @@ -62,7 +64,6 @@ import Cardano.Api.SerialiseRaw
import Cardano.Api.SerialiseTextEnvelope
import Cardano.Api.SerialiseUsing


--
-- Shelley payment keys
--
Expand Down Expand Up @@ -1205,6 +1206,14 @@ instance ToJSON (Hash StakePoolKey) where
instance ToJSONKey (Hash StakePoolKey) where
toJSONKey = toJSONKeyText serialiseToBech32

instance FromJSON (Hash StakePoolKey) where
parseJSON = withText "PoolId" $ \str ->
case deserialiseFromBech32 (AsHash AsStakePoolKey) str of
Left err ->
fail $ "Error deserialising Hash StakePoolKey: " <> Text.unpack str <>
" Error: " <> displayError err
Right h -> pure h

instance HasTextEnvelope (VerificationKey StakePoolKey) where
textEnvelopeType _ = "StakePoolVerificationKey_"
<> fromString (Crypto.algorithmNameDSIGN proxy)
Expand Down
2 changes: 2 additions & 0 deletions cardano-cli/cardano-cli.cabal
Expand Up @@ -176,6 +176,7 @@ test-suite cardano-cli-test
, cardano-node
, cardano-prelude
, cardano-slotting
, containers
, directory
, exceptions
, filepath
Expand All @@ -189,6 +190,7 @@ test-suite cardano-cli-test
other-modules: Test.Config.Mainnet
Test.Cli.FilePermissions
Test.Cli.ITN
Test.Cli.JSON
Test.Cli.MultiAssetParsing
Test.Cli.Pioneers.Exercise1
Test.Cli.Pioneers.Exercise2
Expand Down
7 changes: 1 addition & 6 deletions cardano-cli/src/Cardano/CLI/Shelley/Commands.hs
Expand Up @@ -39,7 +39,6 @@ module Cardano.CLI.Shelley.Commands
, VerificationKeyBase64 (..)
, GenesisKeyFile (..)
, MetadataFile (..)
, PoolId (..)
, PoolMetadataFile (..)
, PrivKeyFile (..)
, BlockId (..)
Expand All @@ -50,7 +49,7 @@ module Cardano.CLI.Shelley.Commands
import Data.Text (Text)
import Prelude

import Cardano.Api.Shelley hiding (PoolId)
import Cardano.Api.Shelley

import Ouroboros.Consensus.BlockchainTime (SystemStart (..))

Expand Down Expand Up @@ -467,10 +466,6 @@ newtype OutputFile
= OutputFile FilePath
deriving Show

newtype PoolId
= PoolId String -- Probably not a String
deriving Show

newtype PoolMetadataFile = PoolMetadataFile
{ unPoolMetadataFile :: FilePath }
deriving Show
Expand Down
4 changes: 2 additions & 2 deletions cardano-cli/src/Cardano/CLI/Shelley/Orphans.hs
Expand Up @@ -38,9 +38,9 @@ import qualified Cardano.Ledger.Credential as Ledger
import qualified Cardano.Ledger.Shelley.API.Protocol as Ledger
import qualified Cardano.Ledger.Shelley.EpochBoundary as Ledger
import qualified Cardano.Ledger.Shelley.Rewards as Ledger
import Cardano.Ledger.TxIn (TxId (..))
import qualified Cardano.Protocol.TPraos.Rules.Prtcl as Ledger
import qualified Cardano.Protocol.TPraos.Rules.Tickn as Ledger
import Cardano.Ledger.TxIn (TxId (..))

import qualified Cardano.Ledger.Mary.Value as Ledger.Mary

Expand All @@ -66,8 +66,8 @@ instance ToJSON (HeaderHash blk) => ToJSON (Tip blk) where
, "blockNo" .= blockNo
]

-- This instance is temporarily duplicated in cardano-config
deriving newtype instance ToJSON BlockNo
deriving newtype instance FromJSON BlockNo

--
-- Simple newtype wrappers JSON conversion
Expand Down
52 changes: 39 additions & 13 deletions cardano-cli/src/Cardano/CLI/Shelley/Output.hs
Expand Up @@ -7,17 +7,15 @@ module Cardano.CLI.Shelley.Output
) where

import Cardano.Api
import Prelude

import Data.Aeson (FromJSON (..), KeyValue, ToJSON (..), object, pairs, withObject, (.:?),
(.=))
import Data.Text (Text)

import Cardano.CLI.Shelley.Orphans ()
import Cardano.Prelude (Text)
import Cardano.Slotting.Time (SystemStart (..))
import Data.Aeson (KeyValue, ToJSON (..), (.=))
import Data.Function (id, ($), (.))
import Data.Maybe ( Maybe(..) )
import Data.Monoid (mconcat)
import Cardano.Ledger.Shelley.Scripts ()

import qualified Data.Aeson as J
import Cardano.Slotting.Time (SystemStart (..))

data QueryTipLocalState mode = QueryTipLocalState
{ era :: AnyCardanoEra
Expand All @@ -31,7 +29,7 @@ data QueryTipLocalStateOutput = QueryTipLocalStateOutput
, mEra :: Maybe AnyCardanoEra
, mEpoch :: Maybe EpochNo
, mSyncProgress :: Maybe Text
}
} deriving Show

-- | A key-value pair difference list for encoding a JSON object.
(..=) :: (KeyValue kv, ToJSON v) => Text -> v -> [kv] -> [kv]
Expand All @@ -46,13 +44,13 @@ data QueryTipLocalStateOutput = QueryTipLocalStateOutput
instance ToJSON QueryTipLocalStateOutput where
toJSON a = case localStateChainTip a of
ChainTipAtGenesis ->
J.object $
object $
( ("era" ..=? mEra a)
. ("epoch" ..=? mEpoch a)
. ("syncProgress" ..=? mSyncProgress a)
) []
ChainTip slotNo blockHeader blockNo ->
J.object $
object $
( ("slot" ..= slotNo)
. ("hash" ..= serialiseToRawBytesHexText blockHeader)
. ("block" ..= blockNo)
Expand All @@ -62,17 +60,45 @@ instance ToJSON QueryTipLocalStateOutput where
) []
toEncoding a = case localStateChainTip a of
ChainTipAtGenesis ->
J.pairs $ mconcat $
pairs $ mconcat $
( ("era" ..=? mEra a)
. ("epoch" ..=? mEpoch a)
. ("syncProgress" ..=? mSyncProgress a)
) []
ChainTip slotNo blockHeader blockNo ->
J.pairs $ mconcat $
pairs $ mconcat $
( ("slot" ..= slotNo)
. ("hash" ..= serialiseToRawBytesHexText blockHeader)
. ("block" ..= blockNo)
. ("era" ..=? mEra a)
. ("epoch" ..=? mEpoch a)
. ("syncProgress" ..=? mSyncProgress a)
) []

instance FromJSON QueryTipLocalStateOutput where
parseJSON = withObject "QueryTipLocalStateOutput" $ \o -> do
mEra' <- o .:? "era"
mEpoch' <- o .:? "epoch"
mSyncProgress' <- o .:? "syncProgress"

mSlot <- o .:? "slot"
mHash <- o .:? "hash"
mBlock <- o .:? "block"
case (mSlot, mHash, mBlock) of
(Nothing, Nothing, Nothing) ->
pure $ QueryTipLocalStateOutput
ChainTipAtGenesis
mEra'
mEpoch'
mSyncProgress'
(Just slot, Just hash, Just block) ->
pure $ QueryTipLocalStateOutput
(ChainTip slot hash block)
mEra'
mEpoch'
mSyncProgress'
(_,_,_) -> fail "QueryTipLocalStateOutput was incorrectly JSON encoded.\
\ Expected slot, header hash and block number (ChainTip)\
\ or none (ChainTipAtGenesis)"