cardano-addresses-4.0.0: lib/Command/Script/Validation.hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Copyright: 2020 Input Output (Hong Kong) Ltd., 2021-2022 Input Output Global Inc. (IOG), 2023-2025 Intersect
-- License: Apache-2.0
module Command.Script.Validation
( Cmd
, mod
, run
) where
import Prelude hiding
( mod )
import Cardano.Address.KeyHash
( KeyHash )
import Cardano.Address.Script
( Script (..)
, ValidationLevel (..)
, prettyErrValidateScript
, validateScript
)
import Data.Maybe
( fromMaybe )
import Data.Text
( Text )
import Options.Applicative
( CommandFields
, Mod
, command
, footerDoc
, header
, helper
, info
, optional
, progDesc
)
import Options.Applicative.Help.Pretty
( Doc, annotate, bold, indent, pretty, vsep )
import Options.Applicative.Script
( levelOpt, scriptArg )
import System.IO
( stderr, stdout )
import System.IO.Extra
( hPutString, progName )
data Cmd = Cmd
{ script :: Script KeyHash
, validationLevel :: Maybe ValidationLevel
} deriving (Show)
mod :: (Cmd -> parent) -> Mod CommandFields parent
mod liftCmd = command "validate" $
info (helper <*> fmap liftCmd parser) $ mempty
<> progDesc "Validate a script"
<> header "Choose a required (default) or recommended validation of a script."
<> footerDoc (Just $ vsep
[ prettyText "The script is taken as argument. To have required validation pass '--required' or nothing."
, prettyText "To have recommended validation pass '--recommended'. Recommended validation adds more validations"
, prettyText "on top of the required one, in particular:"
, prettyText " - check if 'all' is non-empty"
, prettyText " - check if there are redundant timelocks in a given level"
, prettyText " - check if there are no duplicated verification keys in a given level"
, prettyText " - check if 'at_least' coeffcient is positive"
, prettyText " - check if 'all', 'any' are non-empty and `'at_least' has no less elements in the list than the coeffcient after timelocks are filtered out. "
, prettyText "The validation of the script does not take into account transaction validity. We assume that the user will take care of this."
, prettyText ""
, prettyText "Example:"
, indent 2 $ annotate bold $ pretty $ progName<>" script validate 'all"
, indent 4 $ annotate bold $ prettyText "[ addr_shared_vk1wgj79fxw2vmxkp85g88nhwlflkxevd77t6wy0nsktn2f663wdcmqcd4fp3"
, indent 4 $ annotate bold $ prettyText ", addr_shared_vk1jthguyss2vffmszq63xsmxlpc9elxnvdyaqk7susl4sppp2s9xqsuszh44"
, indent 4 $ annotate bold $ prettyText "]'"
, indent 2 $ prettyText "Validated."
, prettyText ""
, indent 2 $ annotate bold $ pretty $ progName<>" script validate --required 'all"
, indent 4 $ annotate bold $ prettyText "[ addr_shared_vk1wgj79fxw2vmxkp85g88nhwlflkxevd77t6wy0nsktn2f663wdcmqcd4fp3"
, indent 4 $ annotate bold $ prettyText ", addr_shared_vk1jthguyss2vffmszq63xsmxlpc9elxnvdyaqk7susl4sppp2s9xqsuszh44"
, indent 4 $ annotate bold $ prettyText "]'"
, indent 2 $ prettyText "Validated."
, prettyText ""
, indent 2 $ annotate bold $ pretty $ progName<>" script validate --recommended 'all []'"
, indent 2 $ prettyText "Not validated: The list inside a script is empty or only contains timelocks (which is not recommended)."
, prettyText ""
, indent 2 $ annotate bold $ pretty $ progName<>" script validate 'at_least 1 [active_from 11, active_until 16]'"
, indent 2 $ prettyText "Validated."
, prettyText ""
, indent 2 $ annotate bold $ pretty $ progName<>" script validate 'all"
, indent 4 $ annotate bold $ prettyText "[ addr_shared_vk1wgj79fxw2vmxkp85g88nhwlflkxevd77t6wy0nsktn2f663wdcmqcd4fp3"
, indent 4 $ annotate bold $ prettyText ", addr_shared_vk1wgj79fxw2vmxkp85g88nhwlflkxevd77t6wy0nsktn2f663wdcmqcd4fp3"
, indent 4 $ annotate bold $ prettyText "]'"
, indent 2 $ prettyText "Validated."
, prettyText ""
, indent 2 $ annotate bold $ pretty $ progName<>" script validate --recommended 'all"
, indent 4 $ annotate bold $ prettyText "[ addr_shared_vk1wgj79fxw2vmxkp85g88nhwlflkxevd77t6wy0nsktn2f663wdcmqcd4fp3"
, indent 4 $ annotate bold $ prettyText ", addr_shared_vk1wgj79fxw2vmxkp85g88nhwlflkxevd77t6wy0nsktn2f663wdcmqcd4fp3"
, indent 4 $ annotate bold $ prettyText "]'"
, indent 2 $ prettyText "Not validated: The list inside a script has duplicate keys (which is not recommended)."
])
where
parser = Cmd
<$> scriptArg
<*> optional levelOpt
prettyText :: Text -> Doc
prettyText = pretty
run :: Cmd -> IO ()
run Cmd{script,validationLevel} =
case validateScript (fromMaybe RequiredValidation validationLevel) script of
Left err -> hPutString stderr $ "Not validated: " <> prettyErrValidateScript err
Right _ -> hPutString stdout "Validated."