Skip to content

Commit

Permalink
Merge pull request #639 from input-output-hk/exec_spec/shelley/small-…
Browse files Browse the repository at this point in the history
…chain-sts-test

simple Shelley CHAIN STS test
  • Loading branch information
Jared Corduan authored Jul 15, 2019
2 parents 54e29a8 + 1ca5597 commit 8ffdbad
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 12 deletions.
2 changes: 2 additions & 0 deletions nix/.stack.nix/delegation.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion shelley/chain-and-ledger/executable-spec/delegation.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ test-suite delegation-test
Mutator
Generator
PropertyTests
STSTests
hs-source-dirs: test
ghc-options:
-threaded
Expand All @@ -100,6 +101,7 @@ test-suite delegation-test
-Werror
build-depends:
base,
cryptonite,
tasty,
tasty-hunit,
tasty-hedgehog,
Expand All @@ -110,4 +112,5 @@ test-suite delegation-test
text,
microlens,
cs-ledger,
cardano-crypto-class
cardano-crypto-class,
small-steps
7 changes: 6 additions & 1 deletion shelley/chain-and-ledger/executable-spec/src/BlockChain.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module BlockChain
, BHBody(..)
, BHeader(..)
, Block(..)
, Proof(..)
, bhHash
, bhbHash
, bHeaderSize
Expand Down Expand Up @@ -101,7 +102,11 @@ instance

data BHBody hashAlgo dsignAlgo kesAlgo = BHBody
{ -- | Hash of the previous block header
bheaderPrev :: HashHeader hashAlgo dsignAlgo kesAlgo
-- The first block in a chain will set this field to Nothing.
-- TODO Since the Shelley chain will begins with blocks from
-- the Byron era, we should probably use a sum type here,
-- so that the first shelley block can point to the last Byron block.
bheaderPrev :: Maybe (HashHeader hashAlgo dsignAlgo kesAlgo)
-- | verification key of block issuer
, bheaderVk :: VKey dsignAlgo
-- | block slot
Expand Down
4 changes: 2 additions & 2 deletions shelley/chain-and-ledger/executable-spec/src/Keys.hs
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,11 @@ hashKeyES (VKeyES vKeyES) =
-- |Produce a key evolving signature
signKES
:: (KESAlgorithm kesAlgo, KES.Signable kesAlgo a, ToCBOR a)
=> SignKeyKES kesAlgo
=> SKeyES kesAlgo
-> a
-> Natural
-> KESig kesAlgo a
signKES k d n =
signKES (SKeyES k) d n =
KESig
. fst
. fromJust
Expand Down
2 changes: 1 addition & 1 deletion shelley/chain-and-ledger/executable-spec/src/STS/Chain.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ instance
= ( NewEpochState hashAlgo dsignAlgo
, Seed
, Seed
, HashHeader hashAlgo dsignAlgo kesAlgo
, Maybe (HashHeader hashAlgo dsignAlgo kesAlgo)
, Slot
)

Expand Down
4 changes: 2 additions & 2 deletions shelley/chain-and-ledger/executable-spec/src/STS/Prtcl.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ instance
where
type State (PRTCL hashAlgo dsignAlgo kesAlgo)
= ( Map.Map (KeyHash hashAlgo dsignAlgo) Natural
, HashHeader hashAlgo dsignAlgo kesAlgo
, Maybe (HashHeader hashAlgo dsignAlgo kesAlgo)
, Slot
, Seed
, Seed
Expand Down Expand Up @@ -89,7 +89,7 @@ prtclTransition = do
cs' <- trans @(OVERLAY hashAlgo dsignAlgo kesAlgo) $ TRC (oe, cs, bh)
(etaV', etaC') <- trans @UPDN $ TRC (eta, (etaV, etaC), slot)

pure (cs', bhHash bh, slot, etaV', etaC')
pure (cs', Just $ bhHash bh, slot, etaV', etaC')

instance
( HashAlgorithm hashAlgo
Expand Down
2 changes: 1 addition & 1 deletion shelley/chain-and-ledger/executable-spec/src/Slot.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ slotFromEpoch :: Epoch -> Slot
slotFromEpoch (Epoch n) = Slot $ slotsPerEpoch * n

epochFromSlot :: Slot -> Epoch
epochFromSlot (Slot n) = Epoch $ n `rem` slotsPerEpoch
epochFromSlot (Slot n) = Epoch $ n `div` slotsPerEpoch

firstSlot :: Epoch -> Slot
firstSlot = slotFromEpoch
Expand Down
28 changes: 28 additions & 0 deletions shelley/chain-and-ledger/executable-spec/test/MockTypes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ module MockTypes where

import Cardano.Crypto.DSIGN (MockDSIGN)
import Cardano.Crypto.Hash (ShortHash)
import Cardano.Crypto.KES (MockKES)

import qualified BlockChain
import qualified Delegation.Certificates
import qualified Delegation.PoolParams
import qualified Keys
import qualified LedgerState
import qualified OCert
import qualified STS.Chain
import qualified UTxO

type DCert = Delegation.Certificates.DCert ShortHash MockDSIGN
Expand Down Expand Up @@ -44,3 +48,27 @@ type TxIn = UTxO.TxIn ShortHash MockDSIGN
type TxOut = UTxO.TxOut ShortHash MockDSIGN

type UTxO = UTxO.UTxO ShortHash MockDSIGN

type Block = BlockChain.Block ShortHash MockDSIGN MockKES

type BHBody = BlockChain.BHBody ShortHash MockDSIGN MockKES

type SKeyES = Keys.SKeyES MockKES

type VKeyES = Keys.VKeyES MockKES

type KESig = Keys.KESig MockKES BHBody

type Sig a = Keys.Sig MockDSIGN a

type Proof a = BlockChain.Proof MockDSIGN

type BHeader = BlockChain.BHeader ShortHash MockDSIGN MockKES

type OCert = OCert.OCert MockDSIGN MockKES

type HashHeader = BlockChain.HashHeader ShortHash MockDSIGN MockKES

type NewEpochState = LedgerState.NewEpochState ShortHash MockDSIGN

type CHAIN = STS.Chain.CHAIN ShortHash MockDSIGN MockKES
107 changes: 107 additions & 0 deletions shelley/chain-and-ledger/executable-spec/test/STSTests.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeApplications #-}

module STSTests (stsTests) where

import Data.Either (isLeft)
import qualified Data.Map.Strict as Map (empty)
import Data.Maybe (fromMaybe)
import Data.Word (Word64)
import Test.Tasty (TestTree, testGroup)
import Test.Tasty.HUnit (Assertion, testCase, (@?=))

import Cardano.Crypto.KES (deriveVerKeyKES, genKeyKES)
import Crypto.Random (drgNewTest, withDRG)
import MockTypes (CHAIN, SKeyES, VKeyES)

import BaseTypes (Seed (..), mkUnitInterval)
import BlockChain (pattern BHBody, pattern BHeader, pattern Block, pattern Proof, bhbHash)
import Control.State.Transition (TRC (..), applySTS)
import Delegation.Certificates (PoolDistr (..))
import EpochBoundary (BlocksMade (..))
import Keys (pattern KeyPair, pattern SKeyES, pattern VKeyES, sKey, sign, signKES, vKey)
import LedgerState (pattern NewEpochState, emptyEpochState)
import OCert (KESPeriod (..), pattern OCert)
import Slot (Epoch (..), Slot (..))
import STS.Updn (UPDN)


-- | The UPDN transition should update both the evolving nonce and
-- the candidate nonce during the first two-thirds of the epoch.
-- Note that the number of slots per epoch is hard-coded in the Slot module.
testUPNEarly :: Assertion
testUPNEarly =
let
st = applySTS @UPDN (TRC (Nonce 1, (Nonce 2, Nonce 3), Slot.Slot 5))
in
st @?= Right (SeedOp (Nonce 2) (Nonce 1), SeedOp (Nonce 3) (Nonce 1))

-- | The UPDN transition should update only the evolving nonce
-- in the last thirds of the epoch.
-- Note that the number of slots per epoch is hard-coded in the Slot module.
testUPNLate :: Assertion
testUPNLate =
let
st = applySTS @UPDN (TRC (Nonce 1, (Nonce 2, Nonce 3), Slot.Slot 85))
in
st @?= Right (SeedOp (Nonce 2) (Nonce 1), Nonce 3)

-- | For testing purposes, generate a deterministic KES key pair given a seed.
mkKESKeyPair :: (Word64, Word64, Word64, Word64, Word64) -> (SKeyES, VKeyES)
mkKESKeyPair seed = fst . withDRG (drgNewTest seed) $ do
sk <- genKeyKES 90
return (SKeyES sk, VKeyES $ deriveVerKeyKES sk)

-- | This is a very simple test demonstrating that we have everything in place
-- in order to run the CHAIN STS transition.
-- TODO replace this test with one that does more than just apply the rule.
testApplyChain :: Assertion
testApplyChain =
let
initChainSt =
( NewEpochState
(Epoch 0)
(Nonce 0)
(BlocksMade Map.empty)
(BlocksMade Map.empty)
emptyEpochState
Nothing
(PoolDistr Map.empty)
Map.empty
, Nonce 0
, Nonce 0
, Nothing
, Slot 0
)
kp = KeyPair 1 1
half = fromMaybe (error "could not construct unit interval") $ mkUnitInterval 0.5
(sKeyES, vKeyES) = mkKESKeyPair (0, 0, 0, 0, 0)
bhb = BHBody
Nothing
(vKey kp)
(Slot 0)
(Nonce 0)
(Proof (vKey kp) (Nonce 0))
half
(Proof (vKey kp) half)
(sign (sKey kp) [])
100
(bhbHash [])
(OCert
vKeyES
(vKey kp)
0
(KESPeriod 0)
(sign (sKey kp) (vKeyES, 0, KESPeriod 0))
)
block = Block (BHeader bhb (Keys.signKES sKeyES bhb 0)) []
newSt = applySTS @CHAIN (TRC (Slot 0, initChainSt, block))
in
isLeft newSt @?= True

stsTests :: TestTree
stsTests = testGroup "STS Tests"
[ testCase "update nonce early in the epoch" testUPNEarly
, testCase "update nonce late in the epoch" testUPNLate
, testCase "apply CHAIN transition" testApplyChain
]
9 changes: 5 additions & 4 deletions shelley/chain-and-ledger/executable-spec/test/Tests.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import Test.Tasty
import Test.Tasty

import UnitTests (unitTests)
import PropertyTests (propertyTests)
import PropertyTests (propertyTests)
import STSTests (stsTests)
import UnitTests (unitTests)

tests :: TestTree
tests = testGroup "Ledger with Delegation" [unitTests, propertyTests]
tests = testGroup "Ledger with Delegation" [unitTests, propertyTests, stsTests]

-- main entry point
main :: IO ()
Expand Down

0 comments on commit 8ffdbad

Please sign in to comment.