Skip to content

Commit c4a154b

Browse files
author
Julian Ospald
committed
Apply further review suggestions
1 parent 1fc3ac4 commit c4a154b

File tree

9 files changed

+73
-64
lines changed

9 files changed

+73
-64
lines changed

lib/core-integration/src/Test/Integration/Scenario/API/Shelley/StakePools.hs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ module Test.Integration.Scenario.API.Shelley.StakePools
1616
import Prelude
1717

1818
import Cardano.Wallet.Api.Types
19-
( ApiStakePool
19+
( ApiCertificate (JoinPool, QuitPool, RegisterRewardAccount)
20+
, ApiStakePool
2021
, ApiT (..)
2122
, ApiTransaction
2223
, ApiWallet
@@ -53,6 +54,8 @@ import Data.IORef
5354
( readIORef )
5455
import Data.List
5556
( find, sortOn )
57+
import Data.List.NonEmpty
58+
( NonEmpty (..) )
5659
import Data.Maybe
5760
( fromMaybe, isJust, isNothing, listToMaybe, mapMaybe )
5861
import Data.Ord
@@ -576,14 +579,17 @@ spec = describe "SHELLEY_STAKE_POOLS" $ do
576579
. find (isNothing . getRetirementEpoch)
577580
$ nonRetiredPools
578581

582+
let isValidCerts (Just (RegisterRewardAccount{}:|[JoinPool{}])) = True
583+
isValidCerts _ = False
584+
579585
-- Join Pool
580586
w <- fixtureWallet ctx
581587
joinStakePoolUnsigned @n @'Shelley ctx w nonRetiringPoolId >>= \o -> do
582588
verify o
583589
[ expectResponseCode HTTP.status200
584590
, expectField #inputs (`shouldSatisfy` (not . null))
585591
, expectField #outputs (`shouldSatisfy` (not . null))
586-
, expectField #certificates (`shouldSatisfy` (not . null))
592+
, expectField #certificates (`shouldSatisfy` isValidCerts)
587593
]
588594

589595
describe "STAKE_POOLS_JOIN_UNSIGNED_02"
@@ -668,13 +674,17 @@ spec = describe "SHELLEY_STAKE_POOLS" $ do
668674
[ expectField #delegation (`shouldBe` delegating pool [])
669675
]
670676

677+
let isValidCerts (Just (QuitPool{}:|[])) = True
678+
isValidCerts _ = False
679+
671680
-- Quit Pool
672681
quitStakePoolUnsigned @n @'Shelley ctx w >>= \o -> do
673682
verify o
674683
[ expectResponseCode HTTP.status200
675684
, expectField #inputs (`shouldSatisfy` (not . null))
676685
, expectField #outputs (`shouldSatisfy` (not . null))
677-
, expectField #certificates (`shouldSatisfy` (not . null))
686+
, expectField #certificates (`shouldSatisfy` ((==1) . length))
687+
, expectField #certificates (`shouldSatisfy` isValidCerts)
678688
]
679689

680690
describe "STAKE_POOLS_QUIT_UNSIGNED_02"

lib/core/src/Cardano/Wallet.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ import Cardano.Wallet.Primitive.AddressDerivation
230230
, encryptPassphrase
231231
, liftIndex
232232
, preparePassphrase
233-
, stakePath
233+
, stakeDerivationPath
234234
)
235235
import Cardano.Wallet.Primitive.AddressDerivation.Byron
236236
( ByronKey, unsafeMkByronKeyFromMasterKey )
@@ -2029,7 +2029,7 @@ joinStakePoolUnsigned' ctx currentEpoch knownPools pid poolStatus wid =
20292029

20302030
let s = getState wal
20312031
dprefix = Seq.derivationPrefix s
2032-
sPath = stakePath dprefix
2032+
sPath = stakeDerivationPath dprefix
20332033

20342034
pure (cs, action, sPath)
20352035

@@ -2146,7 +2146,7 @@ quitStakePoolUnsigned' ctx wid = db & \DBLayer{..} -> do
21462146
$ readCheckpoint (PrimaryKey wid)
21472147
let s = getState cp
21482148
dprefix = Seq.derivationPrefix s
2149-
sPath = stakePath dprefix
2149+
sPath = stakeDerivationPath dprefix
21502150

21512151
pure (cs, action, sPath)
21522152
where

lib/core/src/Cardano/Wallet/Api/Server.hs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,14 +1838,21 @@ mkApiCoinSelection mcerts (UnsignedTx inputs outputs) =
18381838
-> NonEmpty DerivationIndex
18391839
-> NonEmpty Api.ApiCertificate
18401840
mkCertificates action xs =
1841-
let apiStakePath = ApiT <$> xs
1842-
in case action of
1843-
Join pid -> Api.JoinPool apiStakePath (ApiT pid) :| []
1844-
RegisterKeyAndJoin pid ->
1845-
Api.RegisterRewardAccount apiStakePath :|
1846-
[Api.JoinPool apiStakePath (ApiT pid)]
1847-
Quit-> Api.QuitPool apiStakePath :| []
1841+
case action of
1842+
Join pid -> NE.fromList
1843+
[ Api.JoinPool apiStakePath (ApiT pid)
1844+
]
1845+
1846+
RegisterKeyAndJoin pid -> NE.fromList
1847+
[ Api.RegisterRewardAccount apiStakePath
1848+
, Api.JoinPool apiStakePath (ApiT pid)
1849+
]
18481850

1851+
Quit -> NE.fromList
1852+
[ Api.QuitPool apiStakePath
1853+
]
1854+
where
1855+
apiStakePath = ApiT <$> xs
18491856
mkAddressAmount :: TxOut -> AddressAmount (ApiT Address, Proxy n)
18501857
mkAddressAmount (TxOut addr (Coin c)) =
18511858
AddressAmount (ApiT addr, Proxy @n) (Quantity $ fromIntegral c)
@@ -2199,12 +2206,12 @@ instance Buildable e => LiftHandler (ErrSelectCoinsExternal e) where
21992206
ErrSelectCoinsExternalUnableToMakeSelection e ->
22002207
handler e
22012208
ErrSelectCoinsExternalUnableToAssignInputs e ->
2202-
apiError err403 UnableToAssignInputOutput $ mconcat
2203-
[ "Unable to assign inputs from coin selection: "
2209+
apiError err500 UnableToAssignInputOutput $ mconcat
2210+
[ "I'm unable to assign inputs from coin selection: "
22042211
, pretty e]
22052212
ErrSelectCoinsExternalUnableToAssignOutputs e ->
2206-
apiError err403 UnableToAssignInputOutput $ mconcat
2207-
[ "Unable to assign outputs from coin selection: "
2213+
apiError err500 UnableToAssignInputOutput $ mconcat
2214+
[ "I'm unable to assign outputs from coin selection: "
22082215
, pretty e]
22092216

22102217
instance Buildable e => LiftHandler (ErrCoinSelection e) where
@@ -2507,12 +2514,12 @@ instance LiftHandler ErrJoinStakePool where
25072514
, toText pid
25082515
]
25092516
ErrJoinStakePoolUnableToAssignInputs e ->
2510-
apiError err403 UnableToAssignInputOutput $ mconcat
2511-
[ "Unable to assign inputs from coin selection: "
2517+
apiError err500 UnableToAssignInputOutput $ mconcat
2518+
[ "I'm unable to assign inputs from coin selection: "
25122519
, pretty e]
25132520
ErrJoinStakePoolUnableToAssignOutputs e ->
2514-
apiError err403 UnableToAssignInputOutput $ mconcat
2515-
[ "Unable to assign outputs from coin selection: "
2521+
apiError err500 UnableToAssignInputOutput $ mconcat
2522+
[ "I'm unable to assign outputs from coin selection: "
25162523
, pretty e]
25172524

25182525
instance LiftHandler ErrFetchRewards where
@@ -2551,12 +2558,12 @@ instance LiftHandler ErrQuitStakePool where
25512558
, " lovelace first."
25522559
]
25532560
ErrQuitStakePoolUnableToAssignInputs e ->
2554-
apiError err403 UnableToAssignInputOutput $ mconcat
2555-
[ "Unable to assign inputs from coin selection: "
2561+
apiError err500 UnableToAssignInputOutput $ mconcat
2562+
[ "I'm unable to assign inputs from coin selection: "
25562563
, pretty e]
25572564
ErrQuitStakePoolUnableToAssignOutputs e ->
2558-
apiError err403 UnableToAssignInputOutput $ mconcat
2559-
[ "Unable to assign outputs from coin selection: "
2565+
apiError err500 UnableToAssignInputOutput $ mconcat
2566+
[ "I'm unable to assign outputs from coin selection: "
25602567
, pretty e]
25612568

25622569
instance LiftHandler ErrCreateRandomAddress where

lib/core/src/Cardano/Wallet/Api/Types.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ instance DecodeAddress n => FromJSON (ApiSelectCoinsData n) where
10411041
pure $ ApiSelectForDelegation $ ApiSelectCoinsAction v
10421042
(Just v, Nothing) ->
10431043
pure $ ApiSelectForPayment $ ApiSelectCoinsPayments v
1044-
_ -> fail "No valid parse for ApiSelectCoinsAction or ApiSelectCoinsAction"
1044+
_ -> fail "No valid parse for ApiSelectCoinsPayments or ApiSelectCoinsAction"
10451045
instance EncodeAddress n => ToJSON (ApiSelectCoinsData n) where
10461046
toJSON (ApiSelectForPayment v) = toJSON v
10471047
toJSON (ApiSelectForDelegation v) = toJSON v
@@ -1060,7 +1060,7 @@ apiCertificateOptions = Aeson.defaultOptions
10601060
, sumEncoding = TaggedObject
10611061
{
10621062
tagFieldName = "certificate_type"
1063-
, contentsFieldName = "details"
1063+
, contentsFieldName = "details" -- this isn't actually used
10641064
}
10651065
}
10661066

@@ -1080,7 +1080,8 @@ instance FromJSON (ApiT DelegationAction) where
10801080
val -> fail ("Unexpeced action value \"" <> T.unpack val <> "\". Valid values are: \"quit\" and \"join\".")
10811081

10821082
instance ToJSON (ApiT DelegationAction) where
1083-
toJSON (ApiT (RegisterKeyAndJoin _)) = error "RegisterKeyAndJoin not valid"
1083+
toJSON (ApiT (RegisterKeyAndJoin pid)) = object
1084+
[ "action" .= String "register_key_and_join", "pool" .= (ApiT pid) ]
10841085
toJSON (ApiT (Join pid)) = object [ "action" .= String "join", "pool" .= (ApiT pid) ]
10851086
toJSON (ApiT Quit) = object [ "action" .= String "quit" ]
10861087

lib/core/src/Cardano/Wallet/Primitive/AddressDerivation.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ module Cardano.Wallet.Primitive.AddressDerivation
3939
, utxoInternal
4040
, mutableAccount
4141
, zeroAccount
42-
, stakePath
42+
, stakeDerivationPath
4343
, DerivationType (..)
4444
, HardDerivation (..)
4545
, SoftDerivation (..)
@@ -217,16 +217,16 @@ zeroAccount :: Index 'Soft 'AddressK
217217
zeroAccount = minBound
218218

219219
-- | Full path to the stake key. There's only one.
220-
stakePath :: DerivationPrefix -> NonEmpty DerivationIndex
221-
stakePath (DerivationPrefix (purpose, coin, acc)) =
220+
stakeDerivationPath :: DerivationPrefix -> NonEmpty DerivationIndex
221+
stakeDerivationPath (DerivationPrefix (purpose, coin, acc)) =
222222
(fromIndex purpose) :| [
223223
fromIndex coin
224224
, fromIndex acc
225225
, fromIndex mutableAccount
226226
, fromIndex zeroAccount]
227227
where
228228
fromIndex :: Index t l -> DerivationIndex
229-
fromIndex (Index ix) = DerivationIndex ix
229+
fromIndex = DerivationIndex . getIndex
230230

231231
-- | A derivation index, with phantom-types to disambiguate derivation type.
232232
--

lib/core/test/unit/Cardano/Wallet/Api/Malformed.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -857,19 +857,19 @@ instance Malformed (BodyParam (ApiSelectCoinsData ('Testnet pm))) where
857857
jsonValid = (first (BodyParam . Aeson.encode) <$> paymentCases) <> jsonValidAction
858858
jsonValidAction = first (BodyParam . Aeson.encode) <$>
859859
[ ( [aesonQQ| { "action": "join" }|]
860-
, "Error in $: No valid parse for ApiSelectCoinsAction or ApiSelectCoinsAction"
860+
, "Error in $: No valid parse for ApiSelectCoinsPayments or ApiSelectCoinsAction"
861861
)
862862
, ( [aesonQQ| { "action": "" }|]
863-
, "Error in $: No valid parse for ApiSelectCoinsAction or ApiSelectCoinsAction"
863+
, "Error in $: No valid parse for ApiSelectCoinsPayments or ApiSelectCoinsAction"
864864
)
865865
, ( [aesonQQ| { "action": "join", "pool": "" }|]
866-
, "Error in $: No valid parse for ApiSelectCoinsAction or ApiSelectCoinsAction"
866+
, "Error in $: No valid parse for ApiSelectCoinsPayments or ApiSelectCoinsAction"
867867
)
868868
, ( [aesonQQ| { "action": "join", "pool": "1" }|]
869-
, "Error in $: No valid parse for ApiSelectCoinsAction or ApiSelectCoinsAction"
869+
, "Error in $: No valid parse for ApiSelectCoinsPayments or ApiSelectCoinsAction"
870870
)
871871
, ( [aesonQQ| { "pool": "pool1wqaz0q0zhtxlgn0ewssevn2mrtm30fgh2g7hr7z9rj5856457mm" }|]
872-
, "Error in $: No valid parse for ApiSelectCoinsAction or ApiSelectCoinsAction"
872+
, "Error in $: No valid parse for ApiSelectCoinsPayments or ApiSelectCoinsAction"
873873
)
874874
]
875875

lib/shelley/src/Cardano/Wallet/Shelley/Api/Server.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,8 @@ server byron icarus shelley spl ntp =
312312
withLegacyLayer wid
313313
(byron, liftHandler $ throwE ErrNotASequentialWallet)
314314
(icarus, selectCoins icarus (const $ paymentAddress @n) wid x)
315-
byronCoinSelections _ _ = throwError err400
315+
byronCoinSelections _ _ = throwError
316+
$ err400 { errBody = "Byron wallets don't have delegation capabilities." }
316317

317318
byronTransactions :: Server (ByronTransactions n)
318319
byronTransactions =

lib/shelley/src/Cardano/Wallet/Shelley/Transaction.hs

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import Cardano.Binary
4545
( serialize' )
4646
import Cardano.Crypto.DSIGN
4747
( DSIGNAlgorithm (..), SignedDSIGN (..) )
48+
import Cardano.Crypto.Wallet
49+
( XPub )
4850
import Cardano.Ledger.Crypto
4951
( Crypto (..) )
5052
import Cardano.Wallet.Primitive.AddressDerivation
@@ -109,8 +111,6 @@ import qualified Cardano.Api.Typed as Cardano
109111
import qualified Cardano.Chain.Common as Byron
110112
import qualified Cardano.Crypto as CC
111113
import qualified Cardano.Crypto.Hash.Class as Crypto
112-
import Cardano.Crypto.Wallet
113-
( XPub )
114114
import qualified Cardano.Crypto.Wallet as Crypto.HD
115115
import qualified Cardano.Wallet.Primitive.CoinSelection as CS
116116
import qualified Data.ByteArray as BA
@@ -175,39 +175,25 @@ instance TxWitnessTagFor ByronKey where
175175
txWitnessTagFor = TxWitnessByronUTxO Byron
176176

177177

178-
-- | Returns a tuple of unsigned transactions and withdrawals.
179-
mkTxUnsigned
180-
:: Cardano.NetworkId
181-
-> [Cardano.Certificate]
182-
-> Maybe Cardano.TxMetadata
183-
-> SlotNo
184-
-- ^ Time to Live
185-
-> XPrv
186-
-- ^ Reward account
187-
-> CoinSelection
188-
-> (Cardano.TxBody Cardano.Shelley, [(Cardano.StakeAddress, Cardano.Lovelace)])
189-
mkTxUnsigned networkId certs md timeToLive rewardAcnt cs =
190-
let wdrls = mkWithdrawals
191-
networkId
192-
(toChimericAccountRaw . toXPub $ rewardAcnt)
193-
(withdrawal cs)
194-
unsigned = mkUnsignedTx timeToLive cs md wdrls certs
195-
in (unsigned, wdrls)
196-
197178
mkTx
198179
:: forall k. (TxWitnessTagFor k, WalletKey k)
199180
=> Cardano.NetworkId
200181
-> TxPayload Cardano.Shelley
201182
-> SlotNo
202-
-- ^ Time to Live
183+
-- ^ Tip of chain, for calculating TTL
203184
-> (XPrv, Passphrase "encryption")
204185
-- ^ Reward account
205186
-> (Address -> Maybe (k 'AddressK XPrv, Passphrase "encryption"))
206187
-> CoinSelection
207188
-> Either ErrMkTx (Tx, SealedTx, SlotNo)
208189
mkTx networkId (TxPayload md certs mkExtraWits) tip (rewardAcnt, pwdAcnt) keyFrom cs = do
190+
let wdrls = mkWithdrawals
191+
networkId
192+
(toChimericAccountRaw . toXPub $ rewardAcnt)
193+
(withdrawal cs)
194+
209195
let timeToLive = defaultTTL tip
210-
let (unsigned, wdrls) = mkTxUnsigned networkId certs md timeToLive rewardAcnt cs
196+
let unsigned = mkUnsignedTx timeToLive cs md wdrls certs
211197

212198
wits <- case (txWitnessTagFor @k) of
213199
TxWitnessShelleyUTxO -> do

specifications/api/swagger.yaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,19 +531,23 @@ x-transactionOutputs: &transactionOutputs
531531
amount: *transactionAmount
532532

533533
x-delegationAction: &delegationAction
534-
description: A delegation action
534+
description: |
535+
A delegation action.
536+
537+
Pool id is only required for "join" and "register_key_and_join".
535538
type: object
536539
required:
537540
- action
538541
properties:
539542
action:
540543
type: string
541-
enum: ["quit", "join"]
544+
enum: ["quit", "join", "register_key_and_join"]
542545
pool: *stakePoolId
543546

544547
x-rewardAccountPath: &rewardAccountPath
545548
type: array
546-
minItems: 1
549+
minItems: 5
550+
maxItems: 5
547551
items:
548552
type: string
549553

0 commit comments

Comments
 (0)