Skip to content

Commit

Permalink
More tidying of error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
rvl authored and paweljakubas committed Apr 15, 2021
1 parent 44b3ee8 commit 60bfb37
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 55 deletions.
12 changes: 6 additions & 6 deletions lib/core-integration/src/Test/Integration/Framework/TestData.hs
Expand Up @@ -79,9 +79,9 @@ module Test.Integration.Framework.TestData
, errMsg403WrongIndex
, errMsg403OutputTokenBundleSizeExceedsLimit
, errMsg403OutputTokenQuantityExceedsLimit
, errMsg403NotPendingWallet
, errMsg403WalletAlreadyActive
, errMsg403NoDelegationTemplate
, errMsg403AlreadyPresentKey
, errMsg403KeyAlreadyPresent
, errMsg403NoSuchCosigner
) where

Expand Down Expand Up @@ -500,8 +500,8 @@ errMsg403OutputTokenQuantityExceedsLimit
, "."
]

errMsg403NotPendingWallet :: String
errMsg403NotPendingWallet = mconcat
errMsg403WalletAlreadyActive :: String
errMsg403WalletAlreadyActive = mconcat
[ "It looks like you've tried to add a cosigner key for a "
, "shared wallet that is active. This can be done only for "
, "pending shared wallet."
Expand All @@ -514,8 +514,8 @@ errMsg403NoDelegationTemplate = mconcat
, "the wallet that does not define any delegation template."
]

errMsg403AlreadyPresentKey :: Text -> String
errMsg403AlreadyPresentKey cred = mconcat
errMsg403KeyAlreadyPresent :: Text -> String
errMsg403KeyAlreadyPresent cred = mconcat
[ "It looks like you've tried to add a cosigner key to a shared wallet's "
, unpack cred," template that is already ascribed to another cosigner. "
, "Please make sure to assign a different key to each cosigner."
Expand Down
Expand Up @@ -84,10 +84,10 @@ import Test.Integration.Framework.DSL
, verify
)
import Test.Integration.Framework.TestData
( errMsg403AlreadyPresentKey
( errMsg403KeyAlreadyPresent
, errMsg403NoDelegationTemplate
, errMsg403NoSuchCosigner
, errMsg403NotPendingWallet
, errMsg403WalletAlreadyActive
)

import qualified Data.Map.Strict as Map
Expand Down Expand Up @@ -370,7 +370,7 @@ spec = describe "SHARED_WALLETS" $ do

rPatch <- patchSharedWallet ctx wal Payment payloadPatch
expectResponseCode HTTP.status403 rPatch
expectErrorMessage errMsg403NotPendingWallet rPatch
expectErrorMessage errMsg403WalletAlreadyActive rPatch

it "SHARED_WALLETS_PATCH_04 - Cannot add cosigner key when delegation script missing and cannot add already existant key to other cosigner" $ \ctx -> runResourceT $ do
let payloadCreate = Json [json| {
Expand Down Expand Up @@ -480,23 +480,23 @@ spec = describe "SHARED_WALLETS" $ do
} |]
rPatch2 <- patchSharedWallet ctx wal Payment payloadPatch2
expectResponseCode HTTP.status403 rPatch2
expectErrorMessage (errMsg403AlreadyPresentKey (toText Payment)) rPatch2
expectErrorMessage (errMsg403KeyAlreadyPresent (toText Payment)) rPatch2

let payloadPatch3 = Json [json| {
"account_public_key": #{accXPub0},
"cosigner": "cosigner#1"
} |]
rPatch3 <- patchSharedWallet ctx wal Payment payloadPatch3
expectResponseCode HTTP.status403 rPatch3
expectErrorMessage (errMsg403AlreadyPresentKey (toText Payment)) rPatch3
expectErrorMessage (errMsg403KeyAlreadyPresent (toText Payment)) rPatch3

let payloadPatch4 = Json [json| {
"account_public_key": #{accXPub1},
"cosigner": "cosigner#1"
} |]
rPatch4 <- patchSharedWallet ctx wal Delegation payloadPatch4
expectResponseCode HTTP.status403 rPatch4
expectErrorMessage (errMsg403AlreadyPresentKey (toText Delegation)) rPatch4
expectErrorMessage (errMsg403KeyAlreadyPresent (toText Delegation)) rPatch4

let payloadPatch5 = Json [json| {
"account_public_key": #{accXPub0},
Expand Down
26 changes: 14 additions & 12 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Expand Up @@ -309,7 +309,8 @@ import Cardano.Wallet.Primitive.AddressDiscovery.Sequential
, purposeCIP1852
)
import Cardano.Wallet.Primitive.AddressDiscovery.SharedState
( SharedState (..)
( ErrAddCosigner (..)
, SharedState (..)
, SharedStateFields (..)
, SharedStatePending (..)
, mkSharedStateFromAccountXPub
Expand Down Expand Up @@ -3056,29 +3057,30 @@ instance IsServerError ErrDerivePublicKey where
instance IsServerError ErrAddCosignerKey where
toServerError = \case
ErrAddCosignerKeyNoSuchWallet e -> toServerError e
ErrAddCosignerKeyActiveWallet ->
ErrAddCosignerKey WalletAlreadyActive ->
apiError err403 SharedWalletNotPending $ mconcat
[ "It looks like you've tried to add a cosigner key for a "
, "shared wallet that is active. This can be done only for "
, "pending shared wallet."
]
ErrAddCosignerKeyNoDelegationTemplate ->
ErrAddCosignerKey NoDelegationTemplate ->
apiError err403 SharedWalletNoDelegationTemplate $ mconcat
[ "It looks like you've tried to add a cosigner key to "
, "a shared wallet's delegation template. This cannot be done for "
, "the wallet that does not define any delegation template."
, "a shared wallet's delegation template. This cannot be done "
, "for the wallet that does not define any delegation template."
]
ErrAddCosignerKeyAlreadyPresentKey cred ->
ErrAddCosignerKey (KeyAlreadyPresent cred) ->
apiError err403 SharedWalletKeyAlreadyExists $ mconcat
[ "It looks like you've tried to add a cosigner key to a shared wallet's "
, toText cred," template that is already ascribed to another cosigner. "
[ "It looks like you've tried to add a cosigner key to a "
, "shared wallet's ", toText cred, " template that is already "
, "ascribed to another cosigner. "
, "Please make sure to assign a different key to each cosigner."
]
ErrAddCosignerKeyNoSuchCosigner (Cosigner c) cred ->
ErrAddCosignerKey (NoSuchCosigner cred (Cosigner c)) ->
apiError err403 SharedWalletNoSuchCosigner $ mconcat
[ "It looks like you've tried to add a cosigner key to a shared wallet's "
, toText cred," template to a non-existing cosigner index: "
, pretty c,"."
[ "It looks like you've tried to add a cosigner key to a "
, "shared wallet's ", toText cred, " template to a "
, "non-existing cosigner index: ", pretty c,"."
]

instance IsServerError (ErrInvalidDerivationIndex 'Soft level) where
Expand Down
Expand Up @@ -84,15 +84,14 @@ import Data.Coerce
( coerce )
import Data.Either
( isRight )
import Data.Maybe
( fromJust, isNothing )
import Data.Proxy
( Proxy (..) )
import GHC.Generics
( Generic )
import Type.Reflection
( Typeable )

import qualified Data.Foldable as F
import qualified Data.Map.Strict as Map

{-------------------------------------------------------------------------------
Expand Down Expand Up @@ -228,12 +227,12 @@ mkSharedState
=> Index 'Hardened 'AccountK
-> SharedStatePending k
-> SharedState n k
mkSharedState accIx state = updateSharedState id $ SharedState
{ derivationPrefix
, fields = PendingFields state
}
mkSharedState accIx pending = updateSharedState state id
where
derivationPrefix = DerivationPrefix (purposeCIP1854, coinTypeAda, accIx)
state = SharedState
{ derivationPrefix = DerivationPrefix (purposeCIP1854, coinTypeAda, accIx)
, fields = PendingFields pending
}

type SupportsSharedState (n :: NetworkDiscriminant) k =
( MkKeyFingerprint k Address
Expand All @@ -257,13 +256,13 @@ mkSharedStateFromRootXPrv (rootXPrv, pwd) accIx gap pTemplate dTemplateM =
where
accXPub = publicKey $ deriveAccountPrivateKey pwd rootXPrv accIx

-- | Turn a "pending" into an "active" state or identity if already "active"
-- | Turn a "pending" into an "active" state or identity if already "active".
updateSharedState
:: forall n k. SupportsSharedState n k
=> (SharedStatePending k -> SharedStatePending k)
-> SharedState n k
=> SharedState n k
-> (SharedStatePending k -> SharedStatePending k)
-> SharedState n k
updateSharedState f st = case fields st of
updateSharedState st f = case fields st of
ReadyFields _ -> st
PendingFields pending -> case sharedStateFromPending @n (f pending) of
Just ready -> st { fields = ReadyFields ready }
Expand Down Expand Up @@ -292,23 +291,27 @@ data ErrAddCosigner
= NoDelegationTemplate
-- ^ Adding key for a cosigner for a non-existant delegation template is
-- not allowed.
| NoSuchCosigner Cosigner CredentialType
| NoSuchCosigner CredentialType Cosigner
-- ^ Adding key for a cosigners for a given script is possible for the
-- cosigner present in the script template.
| AlreadyPresentKey CredentialType
| KeyAlreadyPresent CredentialType
-- ^ Adding the same key for different cosigners for a given script is
-- not allowed.
| WalletAlreadyActive
-- ^ Adding is possible only to pending shared wallet.
deriving (Eq, Show)

-- | The cosigner with his account public key is updated per template.
-- For every template the script is checked if the cosigner is present.
-- If yes, then the key is inserted. If no `NoSuchCosigner` is emitted.
--
-- For each template the script is checked for presence of the cosigner:
-- * If present, then the key is inserted into the staate.
-- * Otherwise, fail with 'NoSuchCosigner'.
-- If the key is already present it is going to be updated.
-- For a given template all keys must be unique. If already present key is tried to be added,
-- `AlreadyPresentKey` error is produced. The updating works only with pending shared state,
-- `KeyAlreadyPresent` error is produced. The updating works only with pending shared state,
--
-- When an active shared state is used `WalletAlreadyActive` error is triggered.
--
-- Updating the key for delegation script can be successful only if delegation script is
-- present. Otherwise, `NoDelegationTemplate` error is triggered.
addCosignerAccXPub
Expand All @@ -321,23 +324,21 @@ addCosignerAccXPub
addCosignerAccXPub accXPub cosigner cred st = case fields st of
ReadyFields _ ->
Left WalletAlreadyActive
PendingFields (SharedStatePending _ pT dTM _) ->
if (cred == Delegation && isNothing dTM) then
Left NoDelegationTemplate
else if (cred == Payment && isCosignerMissing pT) then
Left $ NoSuchCosigner cosigner Payment
else if (cred == Delegation && isCosignerMissing (fromJust dTM)) then
Left $ NoSuchCosigner cosigner Delegation
else if (cred == Payment && isKeyAlreadyPresent pT) then
Left $ AlreadyPresentKey Payment
else if (cred == Delegation && isKeyAlreadyPresent (fromJust dTM)) then
Left $ AlreadyPresentKey Delegation
else
Right $ updateSharedState
(addCosignerAccXPubPending accXPub cosigner cred) st
PendingFields (SharedStatePending _ paymentTmpl delegTmpl _) ->
case (cred, paymentTmpl, delegTmpl) of
(Payment, pt, _)
| isCosignerMissing pt -> Left $ NoSuchCosigner cred cosigner
| isKeyAlreadyPresent pt -> Left $ KeyAlreadyPresent cred
(Delegation, _, Just dt)
| isCosignerMissing dt -> Left $ NoSuchCosigner cred cosigner
| isKeyAlreadyPresent dt -> Left $ KeyAlreadyPresent cred
(Delegation, _, Nothing) -> Left NoDelegationTemplate
_ -> Right $
updateSharedState st $
addCosignerAccXPubPending accXPub cosigner cred
where
isKeyAlreadyPresent (ScriptTemplate cosignerKeys _) =
getRawKey accXPub `elem` Map.elems cosignerKeys
getRawKey accXPub `F.elem` cosignerKeys
isCosignerMissing (ScriptTemplate _ script') =
cosigner `notElem` retrieveAllCosigners script'

Expand Down

0 comments on commit 60bfb37

Please sign in to comment.