Skip to content

Commit a10f917

Browse files
authored
Merge pull request #781 from IntersectMBO/add-pool-operator-extended-key-support
Add pool operator extended key support
2 parents 8b37256 + a47eeb8 commit a10f917

File tree

6 files changed

+105
-9
lines changed

6 files changed

+105
-9
lines changed

cardano-api/gen/Test/Gen/Cardano/Api/Typed.hs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,6 @@ import qualified Hedgehog.Gen as Gen
197197
import qualified Hedgehog.Gen.QuickCheck as Q
198198
import qualified Hedgehog.Range as Range
199199

200-
201-
202200
genAddressByron :: Gen (Address ByronAddr)
203201
genAddressByron =
204202
makeByronAddress
@@ -572,10 +570,13 @@ genOperationalCertificateWithCounter
572570
genOperationalCertificateWithCounter = do
573571
kesVKey <- genVerificationKey AsKesKey
574572
stkPoolOrGenDelExtSign <-
575-
Gen.either (genSigningKey AsStakePoolKey) (genSigningKey AsGenesisDelegateExtendedKey)
573+
Gen.either (Gen.choice [ AnyStakePoolNormalSigningKey <$> genSigningKey AsStakePoolKey
574+
, AnyStakePoolExtendedSigningKey <$> genSigningKey AsStakePoolExtendedKey
575+
])
576+
(genSigningKey AsGenesisDelegateExtendedKey)
576577
kesP <- genKESPeriod
577578
c <- Gen.integral $ Range.linear 0 1000
578-
let stakePoolVer = either getVerificationKey (convert' . getVerificationKey) stkPoolOrGenDelExtSign
579+
let stakePoolVer = either castAnyStakePoolSigningKeyToNormalVerificationKey (convert' . getVerificationKey) stkPoolOrGenDelExtSign
579580
iCounter = OperationalCertificateIssueCounter c stakePoolVer
580581

581582
case issueOperationalCertificate kesVKey stkPoolOrGenDelExtSign kesP iCounter of
@@ -584,6 +585,15 @@ genOperationalCertificateWithCounter = do
584585
Left err -> error $ docToString $ prettyError err
585586
Right pair -> return pair
586587
where
588+
castAnyStakePoolSigningKeyToNormalVerificationKey
589+
:: AnyStakePoolSigningKey
590+
-> VerificationKey StakePoolKey
591+
castAnyStakePoolSigningKeyToNormalVerificationKey anyStakePoolSKey =
592+
case anyStakePoolSigningKeyToVerificationKey anyStakePoolSKey of
593+
AnyStakePoolNormalVerificationKey normalStakePoolVKey -> normalStakePoolVKey
594+
AnyStakePoolExtendedVerificationKey extendedStakePoolVKey ->
595+
castVerificationKey extendedStakePoolVKey
596+
587597
convert'
588598
:: VerificationKey GenesisDelegateExtendedKey
589599
-> VerificationKey StakePoolKey

cardano-api/src/Cardano/Api/Internal/Keys/Shelley.hs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
{-# LANGUAGE DataKinds #-}
22
{-# LANGUAGE DeriveAnyClass #-}
33
{-# LANGUAGE DerivingVia #-}
4+
{-# LANGUAGE FlexibleContexts #-}
45
{-# LANGUAGE FlexibleInstances #-}
6+
{-# LANGUAGE GADTs #-}
57
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
68
{-# LANGUAGE InstanceSigs #-}
79
{-# LANGUAGE MultiParamTypeClasses #-}
10+
{-# LANGUAGE RankNTypes #-}
811
{-# LANGUAGE ScopedTypeVariables #-}
912
{-# LANGUAGE TypeFamilies #-}
13+
{-# LANGUAGE UndecidableInstances #-}
1014
-- The Shelley ledger uses promoted data kinds which we have to use, but we do
1115
-- not export any from this API. We also use them unticked as nature intended.
1216
{-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
@@ -37,6 +41,10 @@ module Cardano.Api.Internal.Keys.Shelley
3741
, VerificationKey (..)
3842
, SigningKey (..)
3943
, Hash (..)
44+
, AnyStakePoolVerificationKey (..)
45+
, anyStakePoolVerificationKeyHash
46+
, AnyStakePoolSigningKey (..)
47+
, anyStakePoolSigningKeyToVerificationKey
4048
)
4149
where
4250

@@ -60,7 +68,11 @@ import Cardano.Crypto.Wallet qualified as Crypto.HD
6068
import Cardano.Ledger.Keys (DSIGN)
6169
import Cardano.Ledger.Keys qualified as Shelley
6270

63-
import Data.Aeson.Types (ToJSONKey (..), toJSONKeyText, withText)
71+
import Data.Aeson.Types
72+
( ToJSONKey (..)
73+
, toJSONKeyText
74+
, withText
75+
)
6476
import Data.Bifunctor (first)
6577
import Data.ByteString (ByteString)
6678
import Data.ByteString qualified as BS
@@ -1658,6 +1670,29 @@ instance CastSigningKeyRole GenesisUTxOKey PaymentKey where
16581670
-- stake pool keys
16591671
--
16601672

1673+
-- | Wrapper that handles both normal and extended StakePoolKeys VerificationKeys
1674+
data AnyStakePoolVerificationKey
1675+
= AnyStakePoolNormalVerificationKey (VerificationKey StakePoolKey)
1676+
| AnyStakePoolExtendedVerificationKey (VerificationKey StakePoolExtendedKey)
1677+
deriving (Show, Eq)
1678+
1679+
anyStakePoolVerificationKeyHash :: AnyStakePoolVerificationKey -> Hash StakePoolKey
1680+
anyStakePoolVerificationKeyHash (AnyStakePoolNormalVerificationKey vk) = verificationKeyHash vk
1681+
anyStakePoolVerificationKeyHash (AnyStakePoolExtendedVerificationKey vk) =
1682+
let StakePoolExtendedKeyHash hash = verificationKeyHash vk in StakePoolKeyHash hash
1683+
1684+
-- | Wrapper that handles both normal and extended StakePoolKeys SigningKeys
1685+
data AnyStakePoolSigningKey
1686+
= AnyStakePoolNormalSigningKey (SigningKey StakePoolKey)
1687+
| AnyStakePoolExtendedSigningKey (SigningKey StakePoolExtendedKey)
1688+
deriving Show
1689+
1690+
anyStakePoolSigningKeyToVerificationKey :: AnyStakePoolSigningKey -> AnyStakePoolVerificationKey
1691+
anyStakePoolSigningKeyToVerificationKey (AnyStakePoolNormalSigningKey sk) =
1692+
AnyStakePoolNormalVerificationKey (getVerificationKey sk)
1693+
anyStakePoolSigningKeyToVerificationKey (AnyStakePoolExtendedSigningKey vk) =
1694+
AnyStakePoolExtendedVerificationKey (getVerificationKey vk)
1695+
16611696
data StakePoolKey
16621697

16631698
instance HasTypeProxy StakePoolKey where
@@ -1892,6 +1927,10 @@ instance SerialiseAsRawBytes (Hash StakePoolExtendedKey) where
18921927
(SerialiseAsRawBytesError "Unable to deserialise Hash StakePoolExtendedKey")
18931928
(StakePoolExtendedKeyHash . Shelley.KeyHash <$> Crypto.hashFromBytes bs)
18941929

1930+
instance SerialiseAsBech32 (Hash StakePoolExtendedKey) where
1931+
bech32PrefixFor _ = "pool_xvkh"
1932+
bech32PrefixesPermitted _ = ["pool_xvkh"]
1933+
18951934
instance HasTextEnvelope (VerificationKey StakePoolExtendedKey) where
18961935
textEnvelopeType _ = "StakePoolExtendedVerificationKey_ed25519_bip32"
18971936

@@ -1906,6 +1945,24 @@ instance SerialiseAsBech32 (SigningKey StakePoolExtendedKey) where
19061945
bech32PrefixFor _ = "pool_xsk"
19071946
bech32PrefixesPermitted _ = ["pool_xsk"]
19081947

1948+
instance ToJSON (Hash StakePoolExtendedKey) where
1949+
toJSON = toJSON . serialiseToBech32
1950+
1951+
instance ToJSONKey (Hash StakePoolExtendedKey) where
1952+
toJSONKey = toJSONKeyText serialiseToBech32
1953+
1954+
instance FromJSON (Hash StakePoolExtendedKey) where
1955+
parseJSON = withText "PoolId" $ \str ->
1956+
case deserialiseFromBech32 (AsHash AsStakePoolExtendedKey) str of
1957+
Left err ->
1958+
fail $
1959+
docToString $
1960+
mconcat
1961+
[ "Error deserialising Hash StakePoolKey: " <> pretty str
1962+
, " Error: " <> prettyError err
1963+
]
1964+
Right h -> pure h
1965+
19091966
instance CastVerificationKeyRole StakePoolExtendedKey StakePoolKey where
19101967
castVerificationKey (StakePoolExtendedVerificationKey vk) =
19111968
StakePoolVerificationKey

cardano-api/src/Cardano/Api/Internal/OperationalCertificate.hs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ instance Error OperationalCertIssueError where
109109
issueOperationalCertificate
110110
:: VerificationKey KesKey
111111
-> Either
112-
(SigningKey StakePoolKey)
112+
AnyStakePoolSigningKey
113113
(SigningKey GenesisDelegateExtendedKey)
114114
-- TODO: this may be better with a type that
115115
-- captured the three (four?) choices, stake pool
@@ -134,8 +134,21 @@ issueOperationalCertificate
134134
, OperationalCertificateIssueCounter (succ counter) poolVKey
135135
)
136136
where
137+
castAnyStakePoolSigningKeyToNormalVerificationKey
138+
:: AnyStakePoolSigningKey
139+
-> VerificationKey StakePoolKey
140+
castAnyStakePoolSigningKeyToNormalVerificationKey anyStakePoolSKey =
141+
case anyStakePoolSigningKeyToVerificationKey anyStakePoolSKey of
142+
AnyStakePoolNormalVerificationKey normalStakePoolVKey -> normalStakePoolVKey
143+
AnyStakePoolExtendedVerificationKey extendedStakePoolVKey ->
144+
castVerificationKey extendedStakePoolVKey
145+
137146
poolVKey' :: VerificationKey StakePoolKey
138-
poolVKey' = either getVerificationKey (convert . getVerificationKey) skey
147+
poolVKey' =
148+
either
149+
castAnyStakePoolSigningKeyToNormalVerificationKey
150+
(convert . getVerificationKey)
151+
skey
139152
where
140153
convert
141154
:: VerificationKey GenesisDelegateExtendedKey
@@ -164,8 +177,13 @@ issueOperationalCertificate
164177
where
165178
skey' :: ShelleySigningKey
166179
skey' = case skey of
167-
Left (StakePoolSigningKey poolSKey) ->
180+
Left (AnyStakePoolNormalSigningKey (StakePoolSigningKey poolSKey)) ->
168181
ShelleyNormalSigningKey poolSKey
182+
Left
183+
( AnyStakePoolExtendedSigningKey
184+
(StakePoolExtendedSigningKey poolExtendedSKey)
185+
) ->
186+
ShelleyExtendedSigningKey poolExtendedSKey
169187
Right (GenesisDelegateExtendedSigningKey delegSKey) ->
170188
ShelleyExtendedSigningKey delegSKey
171189

cardano-api/src/Cardano/Api/Internal/Tx/Sign.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,7 @@ data ShelleyWitnessSigningKey
790790
| WitnessStakeKey (SigningKey StakeKey)
791791
| WitnessStakeExtendedKey (SigningKey StakeExtendedKey)
792792
| WitnessStakePoolKey (SigningKey StakePoolKey)
793+
| WitnessStakePoolExtendedKey (SigningKey StakePoolExtendedKey)
793794
| WitnessGenesisKey (SigningKey GenesisKey)
794795
| WitnessGenesisExtendedKey (SigningKey GenesisExtendedKey)
795796
| WitnessGenesisDelegateKey (SigningKey GenesisDelegateKey)
@@ -1163,6 +1164,7 @@ toShelleySigningKey key = case key of
11631164
-- The cases for extended keys
11641165
WitnessPaymentExtendedKey (PaymentExtendedSigningKey sk) -> ShelleyExtendedSigningKey sk
11651166
WitnessStakeExtendedKey (StakeExtendedSigningKey sk) -> ShelleyExtendedSigningKey sk
1167+
WitnessStakePoolExtendedKey (StakePoolExtendedSigningKey sk) -> ShelleyExtendedSigningKey sk
11661168
WitnessGenesisExtendedKey (GenesisExtendedSigningKey sk) -> ShelleyExtendedSigningKey sk
11671169
WitnessGenesisDelegateExtendedKey (GenesisDelegateExtendedSigningKey sk) -> ShelleyExtendedSigningKey sk
11681170
WitnessCommitteeColdExtendedKey (CommitteeColdExtendedSigningKey sk) -> ShelleyExtendedSigningKey sk

cardano-api/src/Cardano/Api/Shelley.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ module Cardano.Api.Shelley
199199
, DRepMetadataReference (DRepMetadataReference)
200200

201201
-- ** Stake pool operator's keys
202+
, AnyStakePoolVerificationKey (..)
203+
, anyStakePoolVerificationKeyHash
204+
, AnyStakePoolSigningKey (..)
205+
, anyStakePoolSigningKeyToVerificationKey
202206
, StakePoolExtendedKey
203207
, StakePoolKey
204208
, PoolId

cardano-api/test/cardano-api-golden/Test/Golden/ErrorsSpec.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,12 @@ test_OperationalCertIssueError =
211211
testAllErrorMessages_
212212
"Cardano.Api.OperationalCertificate"
213213
"OperationalCertIssueError"
214-
[ ("OperationalCertKeyMismatch", OperationalCertKeyMismatch stakePoolVerKey1 stakePoolVerKey2)
214+
[
215+
( "OperationalCertKeyMismatch"
216+
, OperationalCertKeyMismatch
217+
stakePoolVerKey1
218+
stakePoolVerKey2
219+
)
215220
]
216221

217222
test_ProtocolParametersError :: TestTree

0 commit comments

Comments
 (0)