Skip to content

Commit 2c2f487

Browse files
committed
ThreadNet: refactor critical transaction constructors
- make the transactions' intent more clear by only including the relevant payloads - add comments
1 parent 7fad20f commit 2c2f487

File tree

5 files changed

+150
-159
lines changed

5 files changed

+150
-159
lines changed

ouroboros-consensus-cardano/src/unstable-shelley-testlib/Test/ThreadNet/Infra/Shelley.hs

Lines changed: 133 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ module Test.ThreadNet.Infra.Shelley
2828
, mkKeyHashVrf
2929
, mkKeyPair
3030
, mkLeaderCredentials
31-
, mkMASetDecentralizationParamTxs
3231
, mkProtocolShelley
33-
, mkSetDecentralizationParamTxs
32+
, mkSetDecentralizationParamTx
33+
, mkUpdateProtVerTxShelley
34+
, mkUpdateProtVerTxAllegra
3435
, mkVerKey
3536
, networkId
3637
, tpraosSlotLength
@@ -60,9 +61,7 @@ import Cardano.Crypto.VRF
6061
import qualified Cardano.Ledger.Allegra.Scripts as SL
6162
import Cardano.Ledger.BaseTypes (boundRational, unNonZero)
6263
import Cardano.Ledger.Hashes
63-
( EraIndependentTxBody
64-
, HashAnnotated (..)
65-
, SafeHash
64+
( HashAnnotated (..)
6665
, hashAnnotated
6766
)
6867
import qualified Cardano.Ledger.Keys as LK
@@ -81,7 +80,6 @@ import qualified Cardano.Protocol.TPraos.OCert as SL
8180
import Control.Monad.Except (throwError)
8281
import qualified Control.Tracer as Tracer
8382
import qualified Data.ByteString as BS
84-
import Data.Coerce (coerce)
8583
import Data.ListMap (ListMap (ListMap))
8684
import qualified Data.ListMap as ListMap
8785
import Data.Map.Strict (Map)
@@ -128,7 +126,7 @@ import qualified Test.Cardano.Ledger.Core.KeyPair as TL
128126
)
129127
import qualified Test.Cardano.Ledger.Shelley.Generator.Core as Gen
130128
import Test.Cardano.Ledger.Shelley.Utils (unsafeBoundRational)
131-
import Test.QuickCheck
129+
import Test.QuickCheck hiding (Result (..))
132130
import Test.Util.Orphans.Arbitrary ()
133131
import Test.Util.Slots (NumSlots (..))
134132
import Test.Util.Time (dawnOfTime)
@@ -484,75 +482,54 @@ mkProtocolShelley genesis initialNonce protVer coreNode =
484482
Necessary transactions for updating the 'DecentralizationParam'
485483
-------------------------------------------------------------------------------}
486484

487-
incrementMinorProtVer :: SL.ProtVer -> SL.ProtVer
488-
incrementMinorProtVer (SL.ProtVer major minor) = SL.ProtVer major (succ minor)
489-
490-
mkSetDecentralizationParamTxs ::
491-
forall c.
492-
ShelleyBasedEra ShelleyEra =>
493-
[CoreNode c] ->
485+
-- | A Shelley transaction to update the protocol version.
486+
--
487+
-- See 'mkUpdateProtVerTxAllegra' for later eras.
488+
mkUpdateProtVerTxShelley ::
489+
forall proto.
490+
[CoreNode (ProtoCrypto proto)] ->
491+
-- | The proposed protocol version
492+
ProtVer ->
493+
-- | The TTL
494+
SlotNo ->
495+
GenTx (ShelleyBlock proto ShelleyEra)
496+
mkUpdateProtVerTxShelley coreNodes pVer ttl =
497+
let txBody =
498+
mkUpdateProtVerShelleyEraTxBody @proto @ShelleyEra coreNodes pVer
499+
& (SL.ttlTxBodyL .~ ttl)
500+
in mkShelleyTx $
501+
SL.mkBasicTx txBody
502+
& (SL.witsTxL .~ witnesses @proto coreNodes txBody)
503+
504+
-- | A Shelley transaction to update the protocol version
505+
-- and the decentralisation parameter.
506+
--
507+
-- It is very similar to 'mkUpdateProtVerTxShelley', but additionally
508+
-- includes the decentralisation parameter update.
509+
mkSetDecentralizationParamTx ::
510+
forall proto.
511+
[CoreNode (ProtoCrypto proto)] ->
494512
-- | The proposed protocol version
495513
ProtVer ->
496514
-- | The TTL
497515
SlotNo ->
498516
-- | The new value
499517
DecentralizationParam ->
500-
[GenTx (ShelleyBlock (TPraos c) ShelleyEra)]
501-
mkSetDecentralizationParamTxs coreNodes pVer ttl dNew =
502-
(: []) $
503-
mkShelleyTx $
504-
SL.mkBasicTx body & SL.witsTxL .~ witnesses
518+
GenTx (ShelleyBlock proto ShelleyEra)
519+
mkSetDecentralizationParamTx coreNodes pVer ttl dNew =
520+
let txBody =
521+
mkUpdateProtVerShelleyEraTxBody @proto @ShelleyEra coreNodes pVer
522+
& (SL.ttlTxBodyL .~ ttl)
523+
& (SL.updateTxBodyL .~ SL.SJust update)
524+
in mkShelleyTx $
525+
SL.mkBasicTx txBody
526+
& (SL.witsTxL .~ witnesses @proto coreNodes txBody)
505527
where
506528
-- The funds touched by this transaction assume it's the first transaction
507529
-- executed.
508530
scheduledEpoch :: EpochNo
509531
scheduledEpoch = EpochNo 0
510532

511-
witnesses :: SL.TxWits ShelleyEra
512-
witnesses = SL.mkBasicTxWits & SL.addrTxWitsL .~ signatures
513-
514-
-- Every node signs the transaction body, since it includes a " vote " from
515-
-- every node.
516-
signatures :: Set (SL.WitVKey 'SL.Witness)
517-
signatures =
518-
TL.mkWitnessesVKey
519-
(hashAnnotated body)
520-
[ TL.KeyPair (SL.VKey vk) sk
521-
| cn <- coreNodes
522-
, let sk = cnDelegateKey cn
523-
, let vk = deriveVerKeyDSIGN sk
524-
]
525-
526-
-- Nothing but the parameter update and the obligatory touching of an
527-
-- input.
528-
body :: SL.TxBody ShelleyEra
529-
body =
530-
SL.mkBasicTxBody
531-
& SL.inputsTxBodyL .~ Set.singleton (fst touchCoins)
532-
& SL.outputsTxBodyL .~ Seq.singleton (snd touchCoins)
533-
& SL.ttlTxBodyL .~ ttl
534-
& SL.updateTxBodyL .~ SL.SJust update
535-
536-
-- Every Shelley transaction requires one input.
537-
--
538-
-- We use the input of the first node, but we just put it all right back.
539-
--
540-
-- ASSUMPTION: This transaction runs in the first slot.
541-
touchCoins :: (SL.TxIn, SL.TxOut ShelleyEra)
542-
touchCoins = case coreNodes of
543-
[] -> error "no nodes!"
544-
cn : _ ->
545-
( SL.initialFundsPseudoTxIn addr
546-
, SL.ShelleyTxOut addr coin
547-
)
548-
where
549-
addr =
550-
SL.Addr
551-
networkId
552-
(mkCredential (cnDelegateKey cn))
553-
(SL.StakeRefBase (mkCredential (cnStakingKey cn)))
554-
coin = SL.Coin $ fromIntegral initialLovelacePerCoreNode
555-
556533
-- One replicant of the parameter update per each node.
557534
update :: SL.Update ShelleyEra
558535
update =
@@ -566,102 +543,77 @@ mkSetDecentralizationParamTxs coreNodes pVer ttl dNew =
566543
boundRational $
567544
decentralizationParamToRational dNew
568545
)
569-
& SL.ppuProtocolVersionL .~ SL.SJust pVer
570546
)
571547
| cn <- coreNodes
572548
]
573549

574-
{-------------------------------------------------------------------------------
575-
Auxiliary
576-
-------------------------------------------------------------------------------}
577-
578-
initialLovelacePerCoreNode :: Word64
579-
initialLovelacePerCoreNode = 1000000
580-
581-
mkCredential :: SignKeyDSIGN LK.DSIGN -> SL.Credential r
582-
mkCredential = SL.KeyHashObj . mkKeyHash
583-
584-
mkKeyHash :: SignKeyDSIGN LK.DSIGN -> SL.KeyHash r
585-
mkKeyHash = SL.hashKey . mkVerKey
586-
587-
mkVerKey :: SignKeyDSIGN LK.DSIGN -> SL.VKey r
588-
mkVerKey = SL.VKey . deriveVerKeyDSIGN
589-
590-
mkKeyPair :: SignKeyDSIGN LK.DSIGN -> TL.KeyPair r
591-
mkKeyPair sk = TL.KeyPair{vKey = mkVerKey sk, sKey = sk}
592-
593-
mkKeyHashVrf :: forall c r. Crypto c => SignKeyVRF (VRF c) -> LK.VRFVerKeyHash (r :: LK.KeyRoleVRF)
594-
mkKeyHashVrf = hashVerKeyVRF @c . deriveVerKeyVRF
595-
596-
networkId :: SL.Network
597-
networkId = SL.Testnet
598-
599-
{-------------------------------------------------------------------------------
600-
Temporary Workaround
601-
-------------------------------------------------------------------------------}
602-
603-
-- | TODO This is a copy-paste-edit of 'mkSetDecentralizationParamTxs'
550+
-- | An Allegra transaction to update the protocol version.
604551
--
605-
-- Our current plan is to replace all of this infrastructure with the ThreadNet
606-
-- rewrite; so we're minimizing the work and maintenance here for now.
607-
mkMASetDecentralizationParamTxs ::
552+
-- This transaction is also valid for Mary, Alonzo and Babbage.
553+
-- See 'mkUpdateProtVerTxConway' for later eras.
554+
mkUpdateProtVerTxAllegra ::
608555
forall proto era.
609556
( ShelleyBasedEra era
610-
, SL.AllegraEraTxBody era
611557
, SL.ShelleyEraTxBody era
612-
, SL.AtMostEra "Alonzo" era
558+
, SL.AllegraEraTxBody era
613559
) =>
614560
[CoreNode (ProtoCrypto proto)] ->
615561
-- | The proposed protocol version
616562
ProtVer ->
617563
-- | The TTL
618564
SlotNo ->
619-
-- | The new value
620-
DecentralizationParam ->
621-
[GenTx (ShelleyBlock proto era)]
622-
mkMASetDecentralizationParamTxs coreNodes pVer ttl dNew =
623-
(: []) $
624-
mkShelleyTx $
625-
SL.mkBasicTx body & SL.witsTxL .~ witnesses
565+
GenTx (ShelleyBlock proto era)
566+
mkUpdateProtVerTxAllegra coreNodes pVer ttl =
567+
let txBody =
568+
mkUpdateProtVerShelleyEraTxBody @proto @era coreNodes pVer
569+
& (SL.vldtTxBodyL .~ vldt)
570+
vldt =
571+
SL.ValidityInterval
572+
{ invalidBefore = SL.SNothing
573+
, invalidHereafter = SL.SJust ttl
574+
}
575+
in mkShelleyTx $
576+
SL.mkBasicTx txBody
577+
& (SL.witsTxL .~ witnesses @proto coreNodes txBody)
578+
579+
-- | A transaction body template for ThreadNet tests with the following features:
580+
-- - minimal era constraints
581+
-- - contains a protocol parameter update signed by all core nodes
582+
--
583+
-- The functions constructing the transations using this body will
584+
-- need to create the witnesses using the core node's signatures,
585+
-- see 'witnesses'.
586+
--
587+
-- This transaction uses the Shelley era governance to update the protocol version.
588+
-- Note that this transaction is not valid (and wouldn't even type check) in Conway.
589+
mkUpdateProtVerShelleyEraTxBody ::
590+
forall proto era.
591+
( ShelleyBasedEra era
592+
, SL.ShelleyEraTxBody era
593+
) =>
594+
[CoreNode (ProtoCrypto proto)] ->
595+
-- | The proposed protocol version
596+
ProtVer ->
597+
SL.TxBody era
598+
mkUpdateProtVerShelleyEraTxBody coreNodes pVer =
599+
body
626600
where
627601
-- The funds touched by this transaction assume it's the first transaction
628602
-- executed.
629603
scheduledEpoch :: EpochNo
630604
scheduledEpoch = EpochNo 0
631605

632-
witnesses :: SL.TxWits era
633-
witnesses = SL.mkBasicTxWits & SL.addrTxWitsL .~ signatures
634-
635-
-- Every node signs the transaction body, since it includes a " vote " from
636-
-- every node.
637-
signatures :: Set (SL.WitVKey 'SL.Witness)
638-
signatures =
639-
TL.mkWitnessesVKey
640-
(eraIndTxBodyHash' body)
641-
[ TL.KeyPair (SL.VKey vk) sk
642-
| cn <- coreNodes
643-
, let sk = cnDelegateKey cn
644-
, let vk = deriveVerKeyDSIGN sk
645-
]
646-
647606
-- Nothing but the parameter update and the obligatory touching of an
648607
-- input.
649608
body :: SL.TxBody era
650609
body =
651610
SL.mkBasicTxBody
652-
& SL.inputsTxBodyL .~ inputs
653-
& SL.outputsTxBodyL .~ outputs
654-
& SL.vldtTxBodyL .~ vldt
655-
& SL.updateTxBodyL .~ update'
611+
& (SL.inputsTxBodyL .~ inputs)
612+
& (SL.outputsTxBodyL .~ outputs)
613+
& (SL.updateTxBodyL .~ SL.SJust update)
656614
where
657615
inputs = Set.singleton (fst touchCoins)
658616
outputs = Seq.singleton (snd touchCoins)
659-
vldt =
660-
SL.ValidityInterval
661-
{ invalidBefore = SL.SNothing
662-
, invalidHereafter = SL.SJust ttl
663-
}
664-
update' = SL.SJust update
665617

666618
-- Every Shelley transaction requires one input.
667619
--
@@ -683,27 +635,63 @@ mkMASetDecentralizationParamTxs coreNodes pVer ttl dNew =
683635
(SL.StakeRefBase (mkCredential (cnStakingKey cn)))
684636
coin = SL.inject $ SL.Coin $ fromIntegral initialLovelacePerCoreNode
685637

686-
-- One replicant of the parameter update per each node.
638+
-- One replicant of the protocol version update per each node.
687639
update :: SL.Update era
688640
update =
689641
flip SL.Update scheduledEpoch $
690642
SL.ProposedPPUpdates $
691643
Map.fromList $
692644
[ ( SL.hashKey $ SL.VKey $ deriveVerKeyDSIGN $ cnGenesisKey cn
693645
, SL.emptyPParamsUpdate
694-
& SL.ppuDL
695-
.~ ( maybeToStrictMaybe $
696-
boundRational $
697-
decentralizationParamToRational dNew
698-
)
699-
& SL.ppuProtocolVersionL .~ SL.SJust pVer
646+
& (SL.ppuProtocolVersionL .~ SL.SJust pVer)
700647
)
701648
| cn <- coreNodes
702649
]
703650

704-
eraIndTxBodyHash' ::
705-
HashAnnotated body EraIndependentTxBody =>
706-
body ->
707-
SafeHash
708-
EraIndependentTxBody
709-
eraIndTxBodyHash' = coerce . hashAnnotated
651+
{-------------------------------------------------------------------------------
652+
Auxiliary
653+
-------------------------------------------------------------------------------}
654+
655+
initialLovelacePerCoreNode :: Word64
656+
initialLovelacePerCoreNode = 1000000
657+
658+
mkCredential :: SignKeyDSIGN LK.DSIGN -> SL.Credential r
659+
mkCredential = SL.KeyHashObj . mkKeyHash
660+
661+
mkKeyHash :: SignKeyDSIGN LK.DSIGN -> SL.KeyHash r
662+
mkKeyHash = SL.hashKey . mkVerKey
663+
664+
mkVerKey :: SignKeyDSIGN LK.DSIGN -> SL.VKey r
665+
mkVerKey = SL.VKey . deriveVerKeyDSIGN
666+
667+
mkKeyPair :: SignKeyDSIGN LK.DSIGN -> TL.KeyPair r
668+
mkKeyPair sk = TL.KeyPair{vKey = mkVerKey sk, sKey = sk}
669+
670+
mkKeyHashVrf :: forall c r. Crypto c => SignKeyVRF (VRF c) -> LK.VRFVerKeyHash (r :: LK.KeyRoleVRF)
671+
mkKeyHashVrf = hashVerKeyVRF @c . deriveVerKeyVRF
672+
673+
networkId :: SL.Network
674+
networkId = SL.Testnet
675+
676+
incrementMinorProtVer :: SL.ProtVer -> SL.ProtVer
677+
incrementMinorProtVer (SL.ProtVer major minor) = SL.ProtVer major (succ minor)
678+
679+
-- | Create a witness for a transaction body.
680+
--
681+
-- Every node signs the transaction body, since it includes a " vote " from
682+
-- every node.
683+
witnesses ::
684+
forall proto era.
685+
ShelleyBasedEra era =>
686+
[CoreNode (ProtoCrypto proto)] -> SL.TxBody era -> SL.TxWits era
687+
witnesses coreNodes body = SL.mkBasicTxWits & SL.addrTxWitsL .~ signatures
688+
where
689+
signatures :: Set (SL.WitVKey 'SL.Witness)
690+
signatures =
691+
TL.mkWitnessesVKey
692+
(hashAnnotated body)
693+
[ TL.KeyPair (SL.VKey vk) sk
694+
| cn <- coreNodes
695+
, let sk = cnDelegateKey cn
696+
, let vk = deriveVerKeyDSIGN sk
697+
]

ouroboros-consensus-cardano/test/cardano-test/Test/ThreadNet/AllegraMary.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,12 @@ prop_simple_allegraMary_convergence
196196
if not setupHardFork
197197
then []
198198
else
199-
fmap GenTxShelley1 $
200-
Shelley.mkMASetDecentralizationParamTxs
199+
-- a single transation to update the protocol version
200+
fmap GenTxShelley1 . (: []) $
201+
Shelley.mkUpdateProtVerTxAllegra
201202
coreNodes
202203
(SL.ProtVer majorVersion2 0)
203204
(SlotNo $ unNumSlots numSlots) -- never expire
204-
setupD -- unchanged
205205
, tniProtocolInfo = protocolInfo
206206
, tniBlockForging = blockForging nullTracer
207207
}

0 commit comments

Comments
 (0)