Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit 16fa234

Browse files
iohk-bors[bot]Michael Hueschenintricate
committed
Merge #4061
4061: [CBR-503] Test OBFT & Hard Fork Mechanism implementation via `script-runner` r=intricate a=mhuesch ## Description See title. ## Linked issue https://iohk.myjetbrains.com/youtrack/issue/CBR-503 Co-authored-by: Michael Hueschen <[email protected]> Co-authored-by: Luke Nadur <[email protected]>
2 parents 81f0ea0 + f57339f commit 16fa234

File tree

8 files changed

+183
-52
lines changed

8 files changed

+183
-52
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
### Features
1313

1414
- Support for (unused) addresses batch import ([CO-448](https://iohk.myjetbrains.com/youtrack/issue/CO-448) [#4040](https://github.com/input-output-hk/cardano-sl/pull/4040))
15-
- Add `script-runner` tool to automate cluster-level testing ([DEVOPS-1131](https://iohk.myjetbrains.com/youtrack/v2/issue/devops-1131): [#3916](https://github.com/input-output-hk/cardano-sl/pull/3916) [#4057](https://github.com/input-output-hk/cardano-sl/pull/4057))
15+
- Add `script-runner` tool to automate cluster-level testing ([DEVOPS-1131](https://iohk.myjetbrains.com/youtrack/v2/issue/devops-1131): [#3916](https://github.com/input-output-hk/cardano-sl/pull/3916) [#4057](https://github.com/input-output-hk/cardano-sl/pull/4057) [#4061](https://github.com/input-output-hk/cardano-sl/pull/4061))
1616

1717
- Node Monitoring API: nodes now serve their own settings and info via a web server via a `/api/v1/node-settings` and `/api/v1/node-info` (still proxied by the wallet backend) ([#110](https://github.com/input-output-hk/cardano-wallet/issues/110))
1818
- Set up scaffolding for node API [#3788](https://github.com/input-output-hk/cardano-sl/pull/3788)

chain/src/Pos/Chain/Update/BlockVersionData.hs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module Pos.Chain.Update.BlockVersionData
66
, ObftConsensusStrictness (..)
77
, ConsensusEra (..)
88
, consensusEraBVD
9+
, obftEraFlagValue
910
) where
1011

1112
import Universum

script-runner/README.md

+20
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,23 @@ This module contains scripts to perform tests at the cluster level - running clu
55
### Usage
66

77
See the `stack-gui` and `stack-test` scripts which contain usage commands.
8+
9+
### Testing OBFT
10+
11+
`script-runner` launches nodes using the `dev:` key of `lib/configuration.yaml`. We can start in OBFT era by applying a patch such as
12+
```
13+
diff --git a/lib/configuration.yaml b/lib/configuration.yaml
14+
index b55039730b..f67e581929 100644
15+
--- a/lib/configuration.yaml
16+
+++ b/lib/configuration.yaml
17+
@@ -48,7 +48,7 @@ dev: &dev
18+
txSizeLinear:
19+
a: 155381 # absolute minimal fees per transaction
20+
b: 43.946 # additional minimal fees per byte of transaction size
21+
- unlockStakeEpoch: 18446744073709551615 # last epoch (maxBound @Word64)
22+
+ unlockStakeEpoch: 9999999999999999999
23+
protocolConstants: &dev_core_genesis_spec_protocolConstants
24+
k: 2
25+
protocolMagic: 55550001
26+
```
27+
and then running a test e.g. `cd script-runner && ./stack-test test4.1` which ensures that we can issue update proposals and see them adopted in OBFT era.

script-runner/TestCases.hs

+104-20
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,21 @@ import System.Exit (ExitCode (..))
1515
import System.IO (hPutStrLn)
1616
import Universum hiding (on)
1717

18+
import Pos.Chain.Genesis (GenesisSpec (..), StaticConfig (..))
1819
import Pos.Chain.Update (ApplicationName (ApplicationName),
1920
BlockVersion (BlockVersion),
20-
BlockVersionData (bvdMaxBlockSize),
21-
BlockVersionModifier (bvmMaxBlockSize),
21+
BlockVersionData (bvdMaxBlockSize, bvdUnlockStakeEpoch),
22+
BlockVersionModifier (bvmMaxBlockSize, bvmUnlockStakeEpoch),
2223
SoftwareVersion (SoftwareVersion), UpdateConfiguration,
23-
ccApplicationVersion_L, ccLastKnownBlockVersion_L)
24+
ccApplicationVersion_L, ccLastKnownBlockVersion_L,
25+
obftEraFlagValue)
2426
import qualified Pos.Client.CLI as CLI
27+
import Pos.Core.Slotting (EpochIndex)
2528
import Pos.DB.Class (gsAdoptedBVData)
2629
import qualified Pos.GState as GS
2730
import Pos.Infra.Diffusion.Types (Diffusion)
28-
import Pos.Launcher (Configuration, HasConfigurations, ccUpdate_L,
29-
cfoFilePath_L, cfoKey_L)
31+
import Pos.Launcher (Configuration, HasConfigurations, ccGenesis_L,
32+
ccUpdate_L, cfoFilePath_L, cfoKey_L)
3033
import Pos.Util.Util (lensOf)
3134

3235
import AutomatedTestRunner
@@ -35,13 +38,20 @@ import NodeControl (NodeInfo (..), mutateConfigurationYaml, startNode,
3538
stopNodeByName)
3639
import OrphanedLenses ()
3740
import PocMode
38-
import Types (NodeType (..), ScriptRuntimeParams (..))
41+
import Types (NodeType (..))
3942

4043
import Serokell.Data.Memory.Units (Byte)
4144

4245
mutateConfiguration :: Configuration -> Configuration
4346
mutateConfiguration cfg = (cfg & ccUpdate_L . ccLastKnownBlockVersion_L .~ BlockVersion 0 1 0) & ccUpdate_L . ccApplicationVersion_L .~ 1
4447

48+
mutateConfigurationForObft :: Configuration -> Configuration
49+
mutateConfigurationForObft cfg = (cfg & ccUpdate_L . ccLastKnownBlockVersion_L .~ BlockVersion 1 0 0) & over ccGenesis_L (updateUnlockStakeEpoch obftEraFlagValue)
50+
51+
updateUnlockStakeEpoch :: EpochIndex -> StaticConfig -> StaticConfig
52+
updateUnlockStakeEpoch ei (GCSrc _ _) = error "updateUnlockStakeEpoch: got GCSrc"
53+
updateUnlockStakeEpoch ei (GCSpec gs) = GCSpec (gs { gsBlockVersionData = ((gsBlockVersionData gs) { bvdUnlockStakeEpoch = ei })})
54+
4555
data ExpectedResult = SuccessFullUpdate | FailedProposalUpdate deriving (Show, Eq)
4656

4757
-- most logging to console is disabled to reduce signal to noise ratio
@@ -50,6 +60,68 @@ data ExpectedResult = SuccessFullUpdate | FailedProposalUpdate deriving (Show, E
5060
logMsg :: String -> PocMode ()
5161
logMsg = liftIO . hPutStrLn stderr
5262

63+
{-# ANN testHardForkMechanism ("HLint: ignore Reduce duplication" :: Text) #-}
64+
testHardForkMechanism :: Script ()
65+
testHardForkMechanism = do
66+
genesisConfig <- getGenesisConfig
67+
let
68+
proposal :: Dict HasConfigurations -> Diffusion PocMode -> PocMode ()
69+
proposal Dict diffusion = do
70+
let
71+
keyIndex :: Int
72+
keyIndex = 0
73+
blockVersion = BlockVersion 0 1 0
74+
softwareVersion = SoftwareVersion (ApplicationName "cardano-sl") 1
75+
blockVersionModifier :: BlockVersionModifier
76+
blockVersionModifier = def { bvmUnlockStakeEpoch = Just obftEraFlagValue }
77+
doUpdate diffusion genesisConfig keyIndex blockVersion softwareVersion blockVersionModifier
78+
expectedResult = SuccessFullUpdate
79+
onStartup $ \Dict _diffusion -> do
80+
stateDir <- view acStatePath
81+
loadNKeys stateDir 4
82+
on (1,2) proposal
83+
on (2,6) $ \Dict _diffusion -> do
84+
uc <- view (lensOf @UpdateConfiguration)
85+
proposals <- GS.getConfirmedProposals uc Nothing
86+
case (proposals, expectedResult) of
87+
([], FailedProposalUpdate) -> do
88+
logMsg "expected failed proposal, passing test"
89+
endScript ExitSuccess
90+
(_, FailedProposalUpdate) -> do
91+
logMsg "expected failure, but proposal was accepted!"
92+
endScript $ ExitFailure 1
93+
([], _) -> do
94+
logMsg "expected proposal to pass, but it didnt"
95+
endScript $ ExitFailure 2
96+
([_one], SuccessFullUpdate) -> do
97+
stateDir <- view acStatePath
98+
opts <- view acScriptOptions
99+
let
100+
-- the config for the script-runner is mirrored to the nodes it starts
101+
cfg = opts ^. srCommonNodeArgs . CLI.commonArgs_L
102+
newConfiguration <- liftIO $ mutateConfigurationYaml (cfg ^. CLI.configurationOptions_L . cfoFilePath_L) (cfg ^. CLI.configurationOptions_L . cfoKey_L) mutateConfigurationForObft
103+
liftIO $ BS.writeFile (T.unpack $ stateDir <> "/configuration2.yaml") newConfiguration
104+
let
105+
cfg2 = cfg & CLI.configurationOptions_L . cfoFilePath_L .~ (T.unpack $ stateDir <> "/configuration2.yaml")
106+
forAllNodes_ $ \node -> do
107+
stopNodeByName (Core, node)
108+
startNode $ NodeInfo node Core stateDir (stateDir <> "/topology.yaml") cfg2
109+
(_toomany, SuccessFullUpdate) -> do
110+
logMsg "expected 1 proposal to pass, but >1 have passed"
111+
endScript $ ExitFailure 3
112+
on (3,10) $ \Dict _diffusion -> do
113+
bvd <- gsAdoptedBVData
114+
case (bvdUnlockStakeEpoch bvd == obftEraFlagValue) of
115+
True -> do
116+
liftIO $ hPutStrLn stderr "test passed"
117+
endScript ExitSuccess
118+
_ -> do
119+
liftIO $ hPutStrLn stderr "bvdUnlockStakeEpoch was not what was we expected"
120+
endScript $ ExitFailure 4
121+
forM_ (range (0,20)) $ \epoch -> do
122+
on(epoch, 0) $ printbvd epoch 0
123+
on(epoch, 1) $ printbvd epoch 1
124+
53125
test4 :: Byte -> ExpectedResult -> Script ()
54126
test4 targetblocksize expectedResult = do
55127
genesisConfig <- getGenesisConfig
@@ -99,11 +171,13 @@ test4 targetblocksize expectedResult = do
99171
endScript $ ExitFailure 3
100172
on (3,10) $ \Dict _diffusion -> do
101173
bvd <- gsAdoptedBVData
102-
case (bvdMaxBlockSize bvd == targetblocksize) of
103-
True -> endScript ExitSuccess
104-
_ -> do
105-
liftIO $ hPutStrLn stderr "max block size not what was expected"
106-
endScript $ ExitFailure 4
174+
if bvdMaxBlockSize bvd == targetblocksize
175+
then do
176+
liftIO $ hPutStrLn stderr "test passed"
177+
endScript ExitSuccess
178+
else do
179+
liftIO $ hPutStrLn stderr "max block size not what was expected"
180+
endScript $ ExitFailure 4
107181
forM_ (range (0,20)) $ \epoch -> do
108182
on(epoch, 0) $ printbvd epoch 0
109183
on(epoch, 1) $ printbvd epoch 1
@@ -114,19 +188,29 @@ emptyScript = do
114188

115189
main :: IO ()
116190
main = do
117-
script <- getEnv "SCRIPT"
191+
scriptArg <- getEnv "SCRIPT"
118192
let
119-
getScript :: String -> Script ()
120-
getScript "test4.1" = test4 1000000 SuccessFullUpdate
121-
getScript "test4.2" = test4 10000000 FailedProposalUpdate
122-
getScript "none" = emptyScript
123-
getScript invalid = error $ "invalid script: " <> show invalid
193+
scripts :: [(String, Script ())]
194+
scripts = [ ("test4.1", test4 1000000 SuccessFullUpdate)
195+
, ("test4.2", test4 10000000 FailedProposalUpdate)
196+
, ("testHFM", testHardForkMechanism)
197+
, ("none" , emptyScript)
198+
]
199+
124200
getAutoMode :: String -> Bool
125201
getAutoMode "none" = False
126202
getAutoMode _ = True
127203

204+
script <- case find ((scriptArg==) . fst) scripts of
205+
Nothing -> do
206+
putStrLn ("\ninvalid script: " <> show scriptArg
207+
<> "\navailable options are " <> show (map fst scripts)
208+
<> "\n" :: Text)
209+
exitFailure
210+
Just (_name,sc) -> pure sc
211+
128212
runScript $ ScriptParams
129-
{ spScript = getScript script
130-
, spRecentSystemStart = getAutoMode script
131-
, spStartCoreAndRelay = getAutoMode script
213+
{ spScript = script
214+
, spRecentSystemStart = getAutoMode scriptArg
215+
, spStartCoreAndRelay = getAutoMode scriptArg
132216
}

script-runner/common/AutomatedTestRunner.hs

+5-6
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import qualified Data.Map as Map
4242
import qualified Data.Text as T
4343
import Data.Time.Units (fromMicroseconds)
4444
import Data.Version (showVersion)
45-
import Formatting (Format, int, sformat, stext, (%))
45+
import Formatting (Format, build, int, sformat, stext, (%))
4646
import Options.Applicative (Parser, execParser, footerDoc, fullDesc,
4747
header, help, helper, info, infoOption, long, progDesc,
4848
switch)
@@ -57,8 +57,7 @@ import Paths_cardano_sl (version)
5757
import Pos.Chain.Block (LastKnownHeaderTag)
5858
import Pos.Chain.Genesis as Genesis
5959
import Pos.Chain.Txp (TxpConfiguration)
60-
import Pos.Chain.Update (BlockVersion,
61-
BlockVersionData (bvdMaxBlockSize, bvdMaxTxSize),
60+
import Pos.Chain.Update (BlockVersion, BlockVersionData (..),
6261
BlockVersionModifier, SoftwareVersion, SystemTag,
6362
UpdateConfiguration, UpdateData, mkUpdateProposalWSign,
6463
updateConfiguration)
@@ -432,10 +431,10 @@ loadNKeys stateDir n = do
432431
printbvd :: Word64 -> Word16 -> Dict HasConfigurations -> Diffusion PocMode -> PocMode ()
433432
printbvd epoch slot Dict _diffusion = do
434433
let
435-
bvdfmt :: Format r (Word64 -> Word16 -> Byte -> Byte -> r)
436-
bvdfmt = "epoch: "%int%" slot: "%int%" BVD: max-tx: " %int% ", max-block: " %int
434+
bvdfmt :: Format r (Word64 -> Word16 -> Byte -> Byte -> EpochIndex -> r)
435+
bvdfmt = "epoch: "%int%" slot: "%int%" BVD: max-tx: " %int% ", max-block: " %int% ", unlockStakeEpoch: "%build
437436
bar <- gsAdoptedBVData
438-
liftIO $ hPrint stderr $ sformat bvdfmt epoch slot (bvdMaxTxSize bar) (bvdMaxBlockSize bar)
437+
liftIO $ hPrint stderr $ sformat bvdfmt epoch slot (bvdMaxTxSize bar) (bvdMaxBlockSize bar) (bvdUnlockStakeEpoch bar)
439438

440439
setSystemStartMutator :: Timestamp -> ScriptRunnerOptions -> ScriptRunnerOptions
441440
setSystemStartMutator systemStartTs optsin =

script-runner/common/NodeControl.hs

+12-14
Original file line numberDiff line numberDiff line change
@@ -133,20 +133,18 @@ commonNodeStart prog args typ idx = do
133133
atomically $ modifyTVar tvar $ Map.insert (typ, idx) hnd
134134

135135
startNode :: NodeInfo -> PocMode ()
136-
startNode info@(NodeInfo idx Core stateRoot _topoPath _cfg) = do
137-
let
138-
params = (commonNodeParams info) <>
139-
[ "--keyfile", T.unpack (stateRoot <> "/genesis-keys/generated-keys/rich/key" <> (show idx) <> ".sk")
140-
, "--listen", "127.0.0.1:" <> show (startingPortOffset Core + idx + 3000)
141-
]
142-
commonNodeStart "cardano-node-simple" params Core idx
143-
startNode info@(NodeInfo idx Relay stateRoot _topoPath _cfg) = do
144-
let
145-
params = (commonNodeParams info) <>
146-
[ "--keyfile", T.unpack (stateRoot <> "/relay" <> (show idx) <> ".sk")
147-
, "--listen", "127.0.0.1:" <> show (startingPortOffset Relay + idx + 3000)
148-
]
149-
commonNodeStart "cardano-node-simple" params Relay idx
136+
startNode info@(NodeInfo idx typ stateRoot _topoPath _cfg) =
137+
commonNodeStart "cardano-node-simple" params typ idx
138+
where
139+
params = (commonNodeParams info) <> nonSharedParams <> sharedParams
140+
nonSharedParams = case typ of
141+
Core -> [ "--keyfile", T.unpack (stateRoot <> "/genesis-keys/generated-keys/rich/key" <> (show idx) <> ".sk")]
142+
Relay -> [ "--keyfile", T.unpack (stateRoot <> "/relay" <> (show idx) <> ".sk")]
143+
sharedParams = [ "--listen", "127.0.0.1:" <> show (startingPortOffset typ + idx + 3000)
144+
, "--tlskey", "scripts/tls-files/server.key"
145+
, "--tlsca", "scripts/tls-files/ca.crt"
146+
, "--tlscert", "scripts/tls-files/server.crt"
147+
]
150148

151149
stopNode :: NodeHandle -> IO ()
152150
stopNode (NodeHandle _async ph) = do

script-runner/stack-gui

+18-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,25 @@
1212
set -e
1313
set -x
1414

15+
16+
unameOut="$(uname -s)"
17+
case "${unameOut}" in
18+
Linux*) machine=Linux;;
19+
Darwin*) machine=Darwin;;
20+
CYGWIN*) machine=Cygwin;;
21+
MINGW*) machine=MinGw;;
22+
*) machine="UNKNOWN:${unameOut}"
23+
esac
24+
echo "We are on a ${machine} machine"
25+
26+
if [ "${machine}" == "Darwin" ]; then
27+
EXTRA_GHC_OPTIONS="--ghc-options=-optl-Wl,-dead_strip_dylibs"
28+
else
29+
EXTRA_GHC_OPTIONS=""
30+
fi
31+
1532
pushd ..
16-
stack build cardano-sl-script-runner cardano-sl-node cardano-sl-tools
33+
stack build $EXTRA_GHC_OPTIONS cardano-sl-script-runner cardano-sl-node cardano-sl-tools
1734
export PATH=$(realpath $(stack path --local-install-root)/bin):$PATH
1835
popd
1936

script-runner/stack-test

+22-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
1-
#!/bin/sh
1+
#!/bin/bash
22

33
# usage: ./stack-test test4.2
44

5-
# on Mac (and OS's with different `mktemp` versions)
6-
# usage: ALT_MKTEMP=1 ./stack-test test4.2
7-
85
set -e
96
set -x
107

8+
9+
unameOut="$(uname -s)"
10+
case "${unameOut}" in
11+
Linux*) machine=Linux;;
12+
Darwin*) machine=Darwin;;
13+
CYGWIN*) machine=Cygwin;;
14+
MINGW*) machine=MinGw;;
15+
*) machine="UNKNOWN:${unameOut}"
16+
esac
17+
echo "We are on a ${machine} machine"
18+
19+
if [ "${machine}" == "Darwin" ]; then
20+
EXTRA_GHC_OPTIONS="--ghc-options=-optl-Wl,-dead_strip_dylibs"
21+
else
22+
EXTRA_GHC_OPTIONS=""
23+
fi
24+
1125
pushd ..
12-
stack build cardano-sl-script-runner cardano-sl-node cardano-sl-tools
26+
stack build $EXTRA_GHC_OPTIONS cardano-sl-script-runner cardano-sl-node cardano-sl-tools
1327
export PATH=$(realpath $(stack path --local-install-root)/bin):$PATH
1428
popd
1529

@@ -20,12 +34,10 @@ LOGCFG=$(realpath ./log-config.yaml)
2034
TOPO=$(realpath ./topology-local.yaml)
2135
POLFILE=$(realpath ../scripts/policies/policy_script-runner.yaml)
2236

23-
if [ -z $ALT_MKTEMP ]; then
24-
# non-darwin
25-
T=$(mktemp -d -p . testrun-XXXXXX)
26-
else
27-
# darwin
37+
if [ "${machine}" == "Darwin" ]; then
2838
T=$(mktemp -d -t testrun)
39+
else
40+
T=$(mktemp -d -p . testrun-XXXXXX)
2941
fi
3042

3143
echo "Temp directory: $T"

0 commit comments

Comments
 (0)