Skip to content

Commit

Permalink
add no such cosigner error and fix other things suggested in review
Browse files Browse the repository at this point in the history
correct rebase artefact
  • Loading branch information
paweljakubas committed Apr 15, 2021
1 parent d7fb630 commit 34f3db5
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 29 deletions.
Expand Up @@ -82,6 +82,7 @@ module Test.Integration.Framework.TestData
, errMsg403NotPendingWallet
, errMsg403NoDelegationTemplate
, errMsg403AlreadyPresentKey
, errMsg403NoSuchCosigner
) where

import Prelude
Expand Down Expand Up @@ -520,3 +521,10 @@ errMsg403AlreadyPresentKey cred = mconcat
, "and is ascribed to another cosigner. Or you are updating with the same key. "
, "Make sure each cosigner has unique key withing each script template."
]

errMsg403NoSuchCosigner :: Text -> Int -> String
errMsg403NoSuchCosigner cred cosigner = mconcat
[ "It looks like you've tried to add cosigner key for "
, "shared wallet for ", unpack cred," template that does not contain "
, "consigner#",show cosigner," inside script template."
]
Expand Up @@ -86,6 +86,7 @@ import Test.Integration.Framework.DSL
import Test.Integration.Framework.TestData
( errMsg403AlreadyPresentKey
, errMsg403NoDelegationTemplate
, errMsg403NoSuchCosigner
, errMsg403NotPendingWallet
)

Expand Down Expand Up @@ -496,6 +497,14 @@ spec = describe "SHARED_WALLETS" $ do
rPatch4 <- patchSharedWallet ctx wal Delegation payloadPatch4
expectResponseCode HTTP.status403 rPatch4
expectErrorMessage (errMsg403AlreadyPresentKey (toText Delegation)) rPatch4

let payloadPatch5 = Json [json| {
"account_public_key": #{accXPub0},
"cosigner": "cosigner#7"
} |]
rPatch5 <- patchSharedWallet ctx wal Payment payloadPatch5
expectResponseCode HTTP.status403 rPatch5
expectErrorMessage (errMsg403NoSuchCosigner (toText Payment) 7) rPatch5
where
xpubFromText :: Text -> Maybe XPub
xpubFromText = fmap eitherToMaybe fromHexText >=> xpubFromBytes
Expand Down
12 changes: 12 additions & 0 deletions lib/core/src/Cardano/Wallet.hs
Expand Up @@ -259,6 +259,7 @@ import Cardano.Wallet.Primitive.AddressDiscovery.SharedState
, SharedStateFields (..)
, SharedStatePending (..)
, addCosignerAccXPub
, retrieveAllCosigners
)
import Cardano.Wallet.Primitive.CoinSelection.MA.RoundRobin
( SelectionError (..)
Expand Down Expand Up @@ -2128,6 +2129,12 @@ updateCosigner ctx wid accXPub cosigner cred = db & \DBLayer{..} -> do
PendingFields (SharedStatePending _ pT dTM _) -> do
when (cred == Delegation && isNothing dTM)$
throwE ErrAddCosignerKeyNoDelegationTemplate

when (cred == Payment && isCosignerMissing pT) $
throwE $ ErrAddCosignerKeyNoSuchCosigner cosigner Payment
when (cred == Delegation && isCosignerMissing (fromJust dTM)) $
throwE $ ErrAddCosignerKeyNoSuchCosigner cosigner Delegation

when (cred == Payment && isKeyAlreadyPresent pT) $
throwE $ ErrAddCosignerKeyAlreadyPresentKey Payment
when (cred == Delegation && isKeyAlreadyPresent (fromJust dTM)) $
Expand All @@ -2142,6 +2149,8 @@ updateCosigner ctx wid accXPub cosigner cred = db & \DBLayer{..} -> do
db = ctx ^. dbLayer @s @k
isKeyAlreadyPresent (ScriptTemplate cosignerKeys _) =
getRawKey accXPub `elem` Map.elems cosignerKeys
isCosignerMissing (ScriptTemplate _ script') =
cosigner `notElem` retrieveAllCosigners script'

{-------------------------------------------------------------------------------
Errors
Expand Down Expand Up @@ -2172,6 +2181,9 @@ data ErrAddCosignerKey
-- ^ Adding the same key for different cosigners for a given script is not allowed.
| ErrAddCosignerKeyNoDelegationTemplate
-- ^ Adding key for a cosigner for a non-existant delegation template is not allowed.
| ErrAddCosignerKeyNoSuchCosigner Cosigner CredentialType
-- ^ Adding key for a cosigners for a given script is possible for the
-- cosigner present in the script template.
deriving (Eq, Show)

data ErrReadAccountPublicKey
Expand Down
52 changes: 30 additions & 22 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Expand Up @@ -111,6 +111,8 @@ import Prelude

import Cardano.Address.Derivation
( XPrv, XPub, xpubPublicKey, xpubToBytes )
import Cardano.Address.Script
( Cosigner (..) )
import Cardano.Api.Typed
( AnyCardanoEra (..), CardanoEra (..), SerialiseAsCBOR (..) )
import Cardano.BM.Tracing
Expand Down Expand Up @@ -3036,26 +3038,26 @@ instance IsServerError ErrWithdrawalNotWorth where
, "request."
]

instance LiftHandler ErrSignMetadataWith where
handler = \case
ErrSignMetadataWithRootKey e -> handler e
ErrSignMetadataWithNoSuchWallet e -> handler e
ErrSignMetadataWithInvalidIndex e -> handler e

instance LiftHandler ErrReadAccountPublicKey where
handler = \case
ErrReadAccountPublicKeyRootKey e -> handler e
ErrReadAccountPublicKeyNoSuchWallet e -> handler e
ErrReadAccountPublicKeyInvalidIndex e -> handler e

instance LiftHandler ErrDerivePublicKey where
handler = \case
ErrDerivePublicKeyNoSuchWallet e -> handler e
ErrDerivePublicKeyInvalidIndex e -> handler e

instance LiftHandler ErrAddCosignerKey where
handler = \case
ErrAddCosignerKeyNoSuchWallet e -> handler e
instance IsServerError ErrSignMetadataWith where
toServerError = \case
ErrSignMetadataWithRootKey e -> toServerError e
ErrSignMetadataWithNoSuchWallet e -> toServerError e
ErrSignMetadataWithInvalidIndex e -> toServerError e

instance IsServerError ErrReadAccountPublicKey where
toServerError = \case
ErrReadAccountPublicKeyRootKey e -> toServerError e
ErrReadAccountPublicKeyNoSuchWallet e -> toServerError e
ErrReadAccountPublicKeyInvalidIndex e -> toServerError e

instance IsServerError ErrDerivePublicKey where
toServerError = \case
ErrDerivePublicKeyNoSuchWallet e -> toServerError e
ErrDerivePublicKeyInvalidIndex e -> toServerError e

instance IsServerError ErrAddCosignerKey where
toServerError = \case
ErrAddCosignerKeyNoSuchWallet e -> toServerError e
ErrAddCosignerKeyActiveWallet ->
apiError err403 SharedWalletNotPending $ mconcat
[ "It looks like you've tried to add cosigner key for "
Expand All @@ -3075,9 +3077,15 @@ instance LiftHandler ErrAddCosignerKey where
, "and is ascribed to another cosigner. Or you are updating with the same key. "
, "Make sure each cosigner has unique key withing each script template."
]
ErrAddCosignerKeyNoSuchCosigner (Cosigner c) cred ->
apiError err403 SharedWalletNoSuchCosigner $ mconcat
[ "It looks like you've tried to add cosigner key for "
, "shared wallet for ", toText cred," template that does not contain "
, "consigner#",pretty c," inside script template."
]

instance LiftHandler (ErrInvalidDerivationIndex 'Soft level) where
handler = \case
instance IsServerError (ErrInvalidDerivationIndex 'Soft level) where
toServerError = \case
ErrIndexOutOfBound minIx maxIx _ix ->
apiError err403 SoftDerivationRequired $ mconcat
[ "It looks like you've provided a derivation index that is "
Expand Down
9 changes: 5 additions & 4 deletions lib/core/src/Cardano/Wallet/Api/Types.hs
Expand Up @@ -345,7 +345,7 @@ import Data.Time.Text
import Data.Typeable
( Typeable )
import Data.Word
( Word16, Word32, Word64, Word8 )
( Word16, Word32, Word64 )
import Data.Word.Odd
( Word31 )
import Fmt
Expand Down Expand Up @@ -1161,6 +1161,7 @@ data ApiErrorCode
| SharedWalletNotPending
| SharedWalletNoDelegationTemplate
| SharedWalletKeyAlreadyExists
| SharedWalletNoSuchCosigner
deriving (Eq, Generic, Show, Data, Typeable)
deriving anyclass NFData

Expand Down Expand Up @@ -2469,11 +2470,11 @@ instance ToText (ApiT Cosigner) where

instance FromText (ApiT Cosigner) where
fromText txt = case T.splitOn "cosigner#" txt of
["",numTxt] -> case T.decimal numTxt of
["",numTxt] -> case T.decimal @Integer numTxt of
Right (num,"") -> do
when (num < minBound @Word8 || num > maxBound @Word8) $
when (num < 0 || num > 255) $
Left $ TextDecodingError "Cosigner number should be between '0' and '255'"
pure $ ApiT $ Cosigner num
pure $ ApiT $ Cosigner $ fromIntegral num
_ -> Left $ TextDecodingError "Cosigner should be enumerated with number"
_ -> Left $ TextDecodingError "Cosigner should be of form: cosigner#num"

Expand Down
Expand Up @@ -5,7 +5,6 @@
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
Expand Down
4 changes: 2 additions & 2 deletions lib/core/test/unit/Cardano/Wallet/DB/SqliteSpec.hs
Expand Up @@ -225,7 +225,7 @@ import Test.Hspec
import Test.Hspec.Extra
( parallel )
import Test.QuickCheck
( Property, generate, noShrinking, property, (==>) )
( Property, generate, property, (==>) )
import Test.QuickCheck.Monadic
( monadicIO )
import Test.Utils.Paths
Expand Down Expand Up @@ -432,7 +432,7 @@ sqliteSpecShared = do
around withShelleyDBLayerInMemory $ do
parallel $ describe "Sqlite (SharedState)" properties
parallel $ describe "Sqlite State machine tests (SharedState)" $ do
it "Sequential" (noShrinking . (prop_sequential :: TestDBShared -> Property))
it "Sequential" (prop_sequential :: TestDBShared -> Property)

testMigrationTxMetaFee
:: forall k s.
Expand Down
62 changes: 62 additions & 0 deletions specifications/api/swagger.yaml
Expand Up @@ -2930,6 +2930,58 @@ x-errOutputTokenQuantityExceedsLimit: &errOutputTokenQuantityExceedsLimit
type: string
enum: ['output_token_quantity_exceeds_limit']

x-errSharedWalletNotPending: &errSharedWalletNotPending
<<: *responsesErr
title: shared_wallet_not_pending
properties:
message:
type: string
description: |
Returned when a user tries to add cosigner key to a shared wallet
that is active, not pending anymore.
code:
type: string
enum: ['shared_wallet_not_pending']

x-errSharedWalletNoDelegationTemplate: &errSharedWalletNoDelegationTemplate
<<: *responsesErr
title: shared_wallet_no_delegation_template
properties:
message:
type: string
description: |
Returned when a user tries to add cosigner key to a shared wallet
for delegation, but the shared wallet misses the delegation template.
code:
type: string
enum: ['shared_wallet_no_delegation_template']

x-errSharedWalletKeyAlreadyExists: &errSharedWalletKeyAlreadyExists
<<: *responsesErr
title: shared_wallet_key_already_exists
properties:
message:
type: string
description: |
Returned when a user tries to add cosigner key to a shared wallet
but the same key is already present in a given template.
code:
type: string
enum: ['shared_wallet_key_already_exists']

x-errSharedWalletNoSuchCosigner: &errSharedWalletNoSuchCosigner
<<: *responsesErr
title: shared_wallet_no_such_cosigner
properties:
message:
type: string
description: |
Returned when a user tries to add cosigner key to a shared wallet
in script template that misses the cosigner.
code:
type: string
enum: ['shared_wallet_no_such_cosigner']

# TODO: Map this error to the place it belongs.
x-errNetworkUnreachable: &errNetworkUnreachable
<<: *responsesErr
Expand Down Expand Up @@ -3476,6 +3528,16 @@ x-responsesPatchSharedWallet: &responsesPatchSharedWallet
<<: *responsesErr400
<<: *responsesErr404WalletNotFound
<<: *responsesErr406
403:
description: Forbidden
content:
application/json:
schema:
oneOf:
- <<: *errSharedWalletKeyAlreadyExists
- <<: *errSharedWalletNoDelegationTemplate
- <<: *errSharedWalletNotPending
- <<: *errSharedWalletNoSuchCosigner
200:
description: Ok
content:
Expand Down

0 comments on commit 34f3db5

Please sign in to comment.