content: module Test.Cardano.Chain.Update.Gen
    ( genCanonicalProtocolParameters
    , genApplicationName
    , genError
    , genProtocolVersion
    , genProtocolParameters
    , genProtocolParametersUpdate
    , genSoftforkRule
    , genSoftwareVersion
    , genSystemTag
    , genInstallerHash
    , genPayload
    , genProof
    , genProposal
    , genProposalBody
    , genUpId
    , genUpsData
    , genVote
    )
  where
  
  import Cardano.Prelude
  import Test.Cardano.Prelude
  
  import Hedgehog
  import qualified Hedgehog.Gen as Gen
  import qualified Hedgehog.Range as Range
  
  import Cardano.Chain.Update
    ( ApplicationName(..)
    , ApplicationNameError(..)
    , InstallerHash(..)
    , Payload
    , Proof
    , Proposal
    , ProposalBody(..)
    , ProtocolParameters(..)
    , ProtocolParametersUpdate(..)
    , ProtocolVersion(..)
    , SoftforkRule(..)
    , SoftwareVersion(..)
    , SoftwareVersionError(..)
    , SystemTag(..)
    , SystemTagError(..)
    , UpId
    , Vote
    , applicationNameMaxLength
    , mkVote
    , payload
    , systemTagMaxLength
    , unsafeProposal
    )
  import Cardano.Chain.Update.Validation.Interface (Error(..))
  import qualified Cardano.Chain.Update.Validation.Registration as Registration
  import qualified Cardano.Chain.Update.Validation.Voting as Voting
  import qualified Cardano.Chain.Update.Validation.Endorsement as Endorsement
  import Cardano.Chain.Slotting (SlotNumber(..))
  
  
  import Cardano.Crypto (ProtocolMagicId)
  
  import Test.Cardano.Chain.Common.Gen
    ( genCanonicalTxFeePolicy
    , genLovelacePortion
    , genScriptVersion
    , genTxFeePolicy
    , genKeyHash
    )
  import Test.Cardano.Chain.Slotting.Gen
    (genEpochNumber, genSlotNumber)
  import Test.Cardano.Crypto.Gen
    ( genAbstractHash
    , genHashRaw
    , genVerificationKey
    , genSigningKey
    , genSignature
    )
  
  
  
  
  genApplicationName :: Gen ApplicationName
  genApplicationName =
    ApplicationName
      <$> Gen.text (Range.constant 0 applicationNameMaxLength) Gen.alphaNum
  
  genCanonicalProtocolParameters :: Gen ProtocolParameters
  genCanonicalProtocolParameters =
    ProtocolParameters
      <$> genScriptVersion
      <*> genNatural
      <*> genNatural
      <*> genNatural
      <*> genNatural
      <*> genNatural
      <*> genLovelacePortion
      <*> genLovelacePortion
      <*> genLovelacePortion
      <*> genLovelacePortion
      <*> genSlotNumber
      <*> genSoftforkRule
      <*> genCanonicalTxFeePolicy
      <*> genEpochNumber
  
  genProtocolVersion :: Gen ProtocolVersion
  genProtocolVersion =
    ProtocolVersion
      <$> Gen.word16 Range.constantBounded
      <*> Gen.word16 Range.constantBounded
      <*> Gen.word8 Range.constantBounded
  
  genProtocolParameters :: Gen ProtocolParameters
  genProtocolParameters =
    ProtocolParameters
      <$> genScriptVersion
      <*> genNatural
      <*> genNatural
      <*> genNatural
      <*> genNatural
      <*> genNatural
      <*> genLovelacePortion
      <*> genLovelacePortion
      <*> genLovelacePortion
      <*> genLovelacePortion
      <*> genSlotNumber
      <*> genSoftforkRule
      <*> genTxFeePolicy
      <*> genEpochNumber
  
  genProtocolParametersUpdate :: Gen ProtocolParametersUpdate
  genProtocolParametersUpdate =
    ProtocolParametersUpdate
      <$> Gen.maybe genScriptVersion
      <*> Gen.maybe genNatural
      <*> Gen.maybe genNatural
      <*> Gen.maybe genNatural
      <*> Gen.maybe genNatural
      <*> Gen.maybe genNatural
      <*> Gen.maybe genLovelacePortion
      <*> Gen.maybe genLovelacePortion
      <*> Gen.maybe genLovelacePortion
      <*> Gen.maybe genLovelacePortion
      <*> Gen.maybe genSlotNumber
      <*> Gen.maybe genSoftforkRule
      <*> Gen.maybe genTxFeePolicy
      <*> Gen.maybe genEpochNumber
  
  genSoftforkRule :: Gen SoftforkRule
  genSoftforkRule =
    SoftforkRule
      <$> genLovelacePortion
      <*> genLovelacePortion
      <*> genLovelacePortion
  
  genSoftwareVersion :: Gen SoftwareVersion
  genSoftwareVersion =
    SoftwareVersion <$> genApplicationName <*> Gen.word32 Range.constantBounded
  
  genSystemTag :: Gen SystemTag
  genSystemTag =
    SystemTag <$> Gen.text (Range.constant 0 systemTagMaxLength) Gen.alphaNum
  
  genInstallerHash :: Gen InstallerHash
  genInstallerHash = InstallerHash <$> genHashRaw
  
  genPayload :: ProtocolMagicId -> Gen Payload
  genPayload pm = payload <$> Gen.maybe (genProposal pm) <*> Gen.list
    (Range.linear 0 10)
    (genVote pm)
  
  genProof :: ProtocolMagicId -> Gen Proof
  genProof pm = genAbstractHash (genPayload pm)
  
  genProposal :: ProtocolMagicId -> Gen Proposal
  genProposal pm =
    unsafeProposal
      <$> genProposalBody
      <*> genVerificationKey
      <*> genSignature pm genProposalBody
  
  genProposalBody :: Gen ProposalBody
  genProposalBody =
    ProposalBody
      <$> genProtocolVersion
      <*> genProtocolParametersUpdate
      <*> genSoftwareVersion
      <*> genUpsData
  
  genUpId :: ProtocolMagicId -> Gen UpId
  genUpId pm = genAbstractHash (genProposal pm)
  
  genUpsData :: Gen (Map SystemTag InstallerHash)
  genUpsData =
    Gen.map (Range.linear 0 20) ((,) <$> genSystemTag <*> genInstallerHash)
  
  genVote :: ProtocolMagicId -> Gen Vote
  genVote pm = mkVote pm <$> genSigningKey <*> genUpId pm <*> Gen.bool
  
  genError :: ProtocolMagicId -> Gen Error
  genError pm = Gen.choice
    [ Registration <$> genRegistrationError
    , Voting <$> genVotingError pm
    , Endorsement <$> genEndorsementError
    , NumberOfGenesisKeysTooLarge <$> genRegistrationTooLarge
    ]
  
  genRegistrationError :: Gen Registration.Error
  genRegistrationError = Gen.choice
    [ Registration.DuplicateProtocolVersion <$> genProtocolVersion
    , Registration.DuplicateSoftwareVersion <$> genSoftwareVersion
    , Registration.InvalidProposer <$> genKeyHash
    , Registration.InvalidProtocolVersion
        <$> genProtocolVersion
        <*> (Registration.Adopted <$> genProtocolVersion)
    , Registration.InvalidScriptVersion <$> genWord16 <*> genWord16
    , pure Registration.InvalidSignature
    , Registration.InvalidSoftwareVersion <$>
      ( Gen.map (Range.linear 1 20) $ do
          name <- genApplicationName
          version <- genWord32
          slotNo <- SlotNumber <$> Gen.word64 Range.constantBounded
          meta <- Gen.map (Range.linear 1 10) $
            (,) <$> genSystemTag <*> genInstallerHash
          pure (name, (version, slotNo, meta))
      ) <*> genSoftwareVersion
    , Registration.MaxBlockSizeTooLarge <$> (Registration.TooLarge <$> genNatural <*> genNatural)
    , Registration.MaxTxSizeTooLarge <$> (Registration.TooLarge <$> genNatural <*> genNatural)
    , pure Registration.ProposalAttributesUnknown
    , Registration.ProposalTooLarge <$> (Registration.TooLarge <$> genNatural <*> genNatural)
    , (Registration.SoftwareVersionError . SoftwareVersionApplicationNameError)
        <$> Gen.choice
        [ ApplicationNameTooLong <$> Gen.text (Range.linear 0 20) Gen.alphaNum
        , ApplicationNameNotAscii <$> Gen.text (Range.linear 0 20) Gen.alphaNum
        ]
    , Registration.SystemTagError <$> Gen.choice
        [ SystemTagNotAscii <$> Gen.text (Range.linear 0 20) Gen.alphaNum
        , SystemTagTooLong <$> Gen.text (Range.linear 0 20) Gen.alphaNum
        ]
    ]
  
  genVotingError :: ProtocolMagicId -> Gen Voting.Error
  genVotingError pm = Gen.choice
    [ pure Voting.VotingInvalidSignature
    , Voting.VotingProposalNotRegistered <$> genUpId pm
    , Voting.VotingVoterNotDelegate <$> genKeyHash
    ]
  
  genEndorsementError :: Gen Endorsement.Error
  genEndorsementError = Endorsement.MultipleProposalsForProtocolVersion <$>
    genProtocolVersion
  
  genRegistrationTooLarge :: Gen (Registration.TooLarge Int)
  genRegistrationTooLarge = Registration.TooLarge 
    <$> Gen.int Range.constantBounded
    <*> Gen.int Range.constantBounded
  