@@ -16,6 +16,8 @@ module Test.Pos.Chain.Block.Arbitrary
16
16
, genMainBlockBody
17
17
, genMainBlockBodyForSlot
18
18
, genMainBlock
19
+ , genHeaderAndParams
20
+ , genStubbedBHL
19
21
) where
20
22
21
23
import Universum
@@ -48,7 +50,6 @@ import Test.Pos.Chain.Ssc.Arbitrary (SscPayloadDependsOnSlot (..),
48
50
import Test.Pos.Chain.Txp.Arbitrary (genTxPayload )
49
51
import Test.Pos.Chain.Update.Arbitrary (genUpdatePayload )
50
52
import Test.Pos.Core.Arbitrary (genSlotId )
51
- import Test.Pos.Crypto.Dummy (dummyProtocolMagic )
52
53
53
54
newtype BodyDependsOnSlot body = BodyDependsOnSlot
54
55
{ genBodyDepsOnSlot :: Core. SlotId -> Gen body
@@ -98,8 +99,9 @@ instance Arbitrary Block.GenesisBody where
98
99
shrink = genericShrink
99
100
100
101
instance Arbitrary Block. GenesisBlock where
101
- arbitrary = Block. mkGenesisBlock dummyProtocolMagic
102
- <$> (maybe (Left dummyGenesisHash) Right <$> arbitrary)
102
+ arbitrary = Block. mkGenesisBlock
103
+ <$> arbitrary
104
+ <*> (maybe (Left dummyGenesisHash) Right <$> arbitrary)
103
105
<*> arbitrary
104
106
<*> arbitrary
105
107
shrink = genericShrink
@@ -129,7 +131,8 @@ instance Arbitrary Block.MainBlockHeader where
129
131
prevHash <- arbitrary
130
132
difficulty <- arbitrary
131
133
body <- arbitrary
132
- genMainBlockHeader dummyProtocolMagic prevHash difficulty body
134
+ pm <- arbitrary
135
+ genMainBlockHeader pm prevHash difficulty body
133
136
shrink = genericShrink
134
137
135
138
instance Arbitrary Block. MainExtraHeaderData where
@@ -197,7 +200,8 @@ instance Arbitrary (BodyDependsOnSlot Block.MainBody) where
197
200
txPayload <- arbitrary
198
201
generator <- genPayloadDependsOnSlot <$> arbitrary
199
202
mpcData <- generator slotId
200
- dlgPayload <- genDlgPayload dummyProtocolMagic $ Core. siEpoch slotId
203
+ pm <- arbitrary
204
+ dlgPayload <- genDlgPayload pm $ Core. siEpoch slotId
201
205
mpcUpload <- arbitrary
202
206
return $ Block. MainBody txPayload mpcData dlgPayload mpcUpload
203
207
@@ -230,13 +234,14 @@ genMainBlock pm prevHash difficulty = do
230
234
instance Arbitrary Block. MainBlock where
231
235
arbitrary = do
232
236
slot <- arbitrary
237
+ pm <- arbitrary
233
238
bv <- arbitrary
234
239
sv <- arbitrary
235
240
prevHeader <- maybe (Left dummyGenesisHash) Right <$> arbitrary
236
241
sk <- arbitrary
237
242
BodyDependsOnSlot {.. } <- arbitrary :: Gen (BodyDependsOnSlot Block. MainBody )
238
243
body <- genBodyDepsOnSlot slot
239
- pure $ mkMainBlock dummyProtocolMagic bv sv prevHeader slot sk Nothing body
244
+ pure $ mkMainBlock pm bv sv prevHeader slot sk Nothing body
240
245
shrink = genericShrink
241
246
242
247
instance Buildable (Block. BlockHeader , PublicKey ) where
@@ -274,26 +279,28 @@ instance Show BlockHeaderList where
274
279
-- * if an epoch is `n` slots long, every `n+1`-th block will be of the
275
280
-- genesis kind.
276
281
recursiveHeaderGen
277
- :: GenesisHash
282
+ :: ProtocolMagic
283
+ -> GenesisHash
278
284
-> Bool -- ^ Whether to create genesis block before creating main block for 0th slot
279
285
-> [Either SecretKey (SecretKey , SecretKey )]
280
286
-> [Core. SlotId ]
281
287
-> [Block. BlockHeader ]
282
288
-> Gen [Block. BlockHeader ]
283
- recursiveHeaderGen gHash
289
+ recursiveHeaderGen pm
290
+ gHash
284
291
genesis
285
292
(eitherOfLeader : leaders)
286
293
(Core. SlotId {.. } : rest)
287
294
blockchain
288
295
| genesis && Core. getSlotIndex siSlot == 0 = do
289
296
gBody <- arbitrary
290
297
let pHeader = maybe (Left gHash) Right ((fmap fst . uncons) blockchain)
291
- gHeader = Block. BlockHeaderGenesis $ Block. mkGenesisHeader dummyProtocolMagic pHeader siEpoch gBody
298
+ gHeader = Block. BlockHeaderGenesis $ Block. mkGenesisHeader pm pHeader siEpoch gBody
292
299
mHeader <- genMainHeader (Just gHeader)
293
- recursiveHeaderGen gHash True leaders rest (mHeader : gHeader : blockchain)
300
+ recursiveHeaderGen pm gHash True leaders rest (mHeader : gHeader : blockchain)
294
301
| otherwise = do
295
302
curHeader <- genMainHeader ((fmap fst . uncons) blockchain)
296
- recursiveHeaderGen gHash True leaders rest (curHeader : blockchain)
303
+ recursiveHeaderGen pm gHash True leaders rest (curHeader : blockchain)
297
304
where
298
305
genMainHeader prevHeader = do
299
306
body <- arbitrary
@@ -306,13 +313,13 @@ recursiveHeaderGen gHash
306
313
Left sk -> (sk, Nothing )
307
314
Right (issuerSK, delegateSK) ->
308
315
let delegatePK = toPublic delegateSK
309
- proxy = ( createPsk dummyProtocolMagic issuerSK delegatePK (Core. HeavyDlgIndex siEpoch)
316
+ proxy = ( createPsk pm issuerSK delegatePK (Core. HeavyDlgIndex siEpoch)
310
317
, toPublic issuerSK)
311
318
in (delegateSK, Just proxy)
312
319
pure $ Block. BlockHeaderMain $
313
- Block. mkMainHeader dummyProtocolMagic (maybe (Left gHash) Right prevHeader) slotId leader proxySK body extraHData
314
- recursiveHeaderGen _ _ [] _ b = return b
315
- recursiveHeaderGen _ _ _ [] b = return b
320
+ Block. mkMainHeader pm (maybe (Left gHash) Right prevHeader) slotId leader proxySK body extraHData
321
+ recursiveHeaderGen _ _ _ [] _ b = return b
322
+ recursiveHeaderGen _ _ _ _ [] b = return b
316
323
317
324
318
325
-- | Maximum start epoch in block header verification tests
@@ -341,19 +348,25 @@ bhlEpochs = 2
341
348
-- Note that a leader is generated for each slot.
342
349
-- (Not exactly a leader - see previous comment)
343
350
instance Arbitrary BlockHeaderList where
344
- arbitrary = do
345
- incompleteEpochSize <- choose (1 , dummyEpochSlots - 1 )
346
- let slot = Core. SlotId 0 localSlotIndexMinBound
347
- generateBHL dummyGenesisHash True slot (dummyEpochSlots * bhlEpochs + incompleteEpochSize)
351
+ arbitrary = arbitrary >>= genStubbedBHL
352
+
353
+ genStubbedBHL
354
+ :: ProtocolMagic
355
+ -> Gen BlockHeaderList
356
+ genStubbedBHL pm = do
357
+ incompleteEpochSize <- choose (1 , dummyEpochSlots - 1 )
358
+ let slot = Core. SlotId 0 localSlotIndexMinBound
359
+ generateBHL pm dummyGenesisHash True slot (dummyEpochSlots * bhlEpochs + incompleteEpochSize)
348
360
349
361
generateBHL
350
- :: GenesisHash
362
+ :: ProtocolMagic
363
+ -> GenesisHash
351
364
-> Bool -- ^ Whether to create genesis block before creating main
352
365
-- block for 0th slot
353
366
-> Core. SlotId -- ^ Start slot
354
367
-> Core. SlotCount -- ^ Slot count
355
368
-> Gen BlockHeaderList
356
- generateBHL gHash createInitGenesis startSlot slotCount = BHL <$> do
369
+ generateBHL pm gHash createInitGenesis startSlot slotCount = BHL <$> do
357
370
let correctLeaderGen :: Gen (Either SecretKey (SecretKey , SecretKey ))
358
371
correctLeaderGen =
359
372
-- We don't want to create blocks with self-signed psks
@@ -368,6 +381,7 @@ generateBHL gHash createInitGenesis startSlot slotCount = BHL <$> do
368
381
[Core. flattenSlotId dummyEpochSlots startSlot .. ]
369
382
(, actualLeaders) <$>
370
383
recursiveHeaderGen
384
+ pm
371
385
gHash
372
386
createInitGenesis
373
387
leadersList
@@ -383,69 +397,72 @@ newtype HeaderAndParams = HAndP
383
397
{ getHAndP :: (Block. VerifyHeaderParams , Block. BlockHeader )
384
398
} deriving (Eq , Show )
385
399
400
+ genHeaderAndParams :: ProtocolMagic -> Gen HeaderAndParams
401
+ genHeaderAndParams pm = do
402
+ -- This integer is used as a seed to randomly choose a slot down below
403
+ seed <- arbitrary :: Gen Int
404
+ startSlot <- Core. SlotId <$> choose (0 , bhlMaxStartingEpoch) <*> arbitrary
405
+ (headers, leaders) <- first reverse . getHeaderList <$>
406
+ (generateBHL pm dummyGenesisHash True startSlot =<< choose (1 , 2 ))
407
+ let num = length headers
408
+ -- 'skip' is the random number of headers that should be skipped in
409
+ -- the header chain. This ensures different parts of it are chosen
410
+ -- each time.
411
+ skip <- choose (0 , num - 1 )
412
+ let atMost2HeadersAndLeaders = take 2 $ drop skip headers
413
+ (prev, header) =
414
+ case atMost2HeadersAndLeaders of
415
+ [h] -> (Nothing , h)
416
+ [h1, h2] -> (Just h1, h2)
417
+ _ -> error " [BlockSpec] the headerchain doesn't have enough headers"
418
+ -- This binding captures the chosen header's epoch. It is used to
419
+ -- drop all all leaders of headers from previous epochs.
420
+ thisEpochStartIndex = fromIntegral dummyEpochSlots *
421
+ fromIntegral (header ^. Core. epochIndexL)
422
+ thisHeadersEpoch = drop thisEpochStartIndex leaders
423
+ -- A helper function. Given integers 'x' and 'y', it chooses a
424
+ -- random integer in the interval [x, y]
425
+ betweenXAndY :: Random a => a -> a -> a
426
+ betweenXAndY x y = fst . randomR (x, y) . mkStdGen $ seed
427
+ -- One of the fields in the 'VerifyHeaderParams' type is 'Just
428
+ -- SlotId'. The following binding is where it is calculated.
429
+ randomSlotBeforeThisHeader =
430
+ case header of
431
+ -- If the header is of the genesis kind, this field is
432
+ -- not needed.
433
+ Block. BlockHeaderGenesis _ -> Nothing
434
+ -- If it's a main blockheader, then a valid "current"
435
+ -- SlotId for testing is any with an epoch greater than
436
+ -- the header's epoch and with any slot index, or any in
437
+ -- the same epoch but with a greater or equal slot index
438
+ -- than the header.
439
+ Block. BlockHeaderMain h -> -- Nothing {-
440
+ let (Core. SlotId e s) = view Block. headerSlotL h
441
+ rndEpoch :: Core. EpochIndex
442
+ rndEpoch = betweenXAndY e maxBound
443
+ rndSlotIdx :: Core. LocalSlotIndex
444
+ rndSlotIdx = if rndEpoch > e
445
+ then betweenXAndY localSlotIndexMinBound (localSlotIndexMaxBound dummyEpochSlots)
446
+ else betweenXAndY s (localSlotIndexMaxBound dummyEpochSlots)
447
+ rndSlot = Core. SlotId rndEpoch rndSlotIdx
448
+ in Just rndSlot
449
+ hasUnknownAttributes =
450
+ not . areAttributesKnown $
451
+ case header of
452
+ Block. BlockHeaderGenesis h -> h ^. Block. gbhExtra . Block. gehAttributes
453
+ Block. BlockHeaderMain h -> h ^. Block. gbhExtra . Block. mehAttributes
454
+ params = Block. VerifyHeaderParams
455
+ { Block. vhpPrevHeader = prev
456
+ , Block. vhpCurrentSlot = randomSlotBeforeThisHeader
457
+ , Block. vhpLeaders = nonEmpty $ map Core. addressHash thisHeadersEpoch
458
+ , Block. vhpMaxSize = Just (biSize header)
459
+ , Block. vhpVerifyNoUnknown = not hasUnknownAttributes
460
+ }
461
+ return . HAndP $ (params, header)
462
+
386
463
-- | A lot of the work to generate a valid sequence of blockheaders has
387
464
-- already been done in the 'Arbitrary' instance of the 'BlockHeaderList'
388
465
-- type, so it is used here and at most 3 blocks are taken from the generated
389
466
-- list.
390
467
instance Arbitrary HeaderAndParams where
391
- arbitrary = do
392
- -- This integer is used as a seed to randomly choose a slot down below
393
- seed <- arbitrary :: Gen Int
394
- startSlot <- Core. SlotId <$> choose (0 , bhlMaxStartingEpoch) <*> arbitrary
395
- (headers, leaders) <- first reverse . getHeaderList <$>
396
- (generateBHL dummyGenesisHash True startSlot =<< choose (1 , 2 ))
397
- let num = length headers
398
- -- 'skip' is the random number of headers that should be skipped in
399
- -- the header chain. This ensures different parts of it are chosen
400
- -- each time.
401
- skip <- choose (0 , num - 1 )
402
- let atMost2HeadersAndLeaders = take 2 $ drop skip headers
403
- (prev, header) =
404
- case atMost2HeadersAndLeaders of
405
- [h] -> (Nothing , h)
406
- [h1, h2] -> (Just h1, h2)
407
- _ -> error " [BlockSpec] the headerchain doesn't have enough headers"
408
- -- This binding captures the chosen header's epoch. It is used to
409
- -- drop all all leaders of headers from previous epochs.
410
- thisEpochStartIndex = fromIntegral dummyEpochSlots *
411
- fromIntegral (header ^. Core. epochIndexL)
412
- thisHeadersEpoch = drop thisEpochStartIndex leaders
413
- -- A helper function. Given integers 'x' and 'y', it chooses a
414
- -- random integer in the interval [x, y]
415
- betweenXAndY :: Random a => a -> a -> a
416
- betweenXAndY x y = fst . randomR (x, y) . mkStdGen $ seed
417
- -- One of the fields in the 'VerifyHeaderParams' type is 'Just
418
- -- SlotId'. The following binding is where it is calculated.
419
- randomSlotBeforeThisHeader =
420
- case header of
421
- -- If the header is of the genesis kind, this field is
422
- -- not needed.
423
- Block. BlockHeaderGenesis _ -> Nothing
424
- -- If it's a main blockheader, then a valid "current"
425
- -- SlotId for testing is any with an epoch greater than
426
- -- the header's epoch and with any slot index, or any in
427
- -- the same epoch but with a greater or equal slot index
428
- -- than the header.
429
- Block. BlockHeaderMain h -> -- Nothing {-
430
- let (Core. SlotId e s) = view Block. headerSlotL h
431
- rndEpoch :: Core. EpochIndex
432
- rndEpoch = betweenXAndY e maxBound
433
- rndSlotIdx :: Core. LocalSlotIndex
434
- rndSlotIdx = if rndEpoch > e
435
- then betweenXAndY localSlotIndexMinBound (localSlotIndexMaxBound dummyEpochSlots)
436
- else betweenXAndY s (localSlotIndexMaxBound dummyEpochSlots)
437
- rndSlot = Core. SlotId rndEpoch rndSlotIdx
438
- in Just rndSlot
439
- hasUnknownAttributes =
440
- not . areAttributesKnown $
441
- case header of
442
- Block. BlockHeaderGenesis h -> h ^. Block. gbhExtra . Block. gehAttributes
443
- Block. BlockHeaderMain h -> h ^. Block. gbhExtra . Block. mehAttributes
444
- params = Block. VerifyHeaderParams
445
- { Block. vhpPrevHeader = prev
446
- , Block. vhpCurrentSlot = randomSlotBeforeThisHeader
447
- , Block. vhpLeaders = nonEmpty $ map Core. addressHash thisHeadersEpoch
448
- , Block. vhpMaxSize = Just (biSize header)
449
- , Block. vhpVerifyNoUnknown = not hasUnknownAttributes
450
- }
451
- return . HAndP $ (params, header)
468
+ arbitrary = arbitrary >>= genHeaderAndParams
0 commit comments