Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ADP-3359] Report unaccepted-era transactions as HTTP 403 errors #4595

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions lib/api/src/Cardano/Wallet/Api/Http/Server/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import Cardano.Wallet.Api.Types.Error
, ApiErrorNotEnoughMoneyShortfall (..)
, ApiErrorSharedWalletNoSuchCosigner (..)
, ApiErrorTxOutputLovelaceInsufficient (..)
, ApiErrorUnsupportedEra (..)
)
import Cardano.Wallet.Primitive.Ledger.Convert
( Convert (toWallet)
Expand Down Expand Up @@ -198,6 +199,7 @@ import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
import qualified Data.Foldable as F
import qualified Data.List as L
import qualified Data.Set as Set
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Internal.Cardano.Write.Tx as Write
Expand Down Expand Up @@ -626,18 +628,38 @@ instance IsServerError ErrRemoveTx where
instance IsServerError ErrPostTx where
toServerError = \case
ErrPostTxValidationError err ->
apiError err500 CreatedInvalidTransaction $ mconcat
[ "The submitted transaction was rejected by the local "
, "node. Here's an error message that may help with "
, "debugging:\n", err
]
apiError err500 CreatedInvalidTransaction
$ mconcat
[ "The submitted transaction was rejected by the local "
, "node. Here's an error message that may help with "
, "debugging:\n"
, err
]
ErrPostTxMempoolFull ->
apiError err425
{errBody = "Mempool is full, please try resubmitting again later."}
MempoolIsFull $ mconcat
[ "The submitted transaction was rejected by the Cardano node "
, "because its mempool was full."
]
apiError
err425
{ errBody =
"Mempool is full, please try resubmitting again later."
}
MempoolIsFull
$ mconcat
[ "The submitted transaction was rejected by the Cardano "
, "node because its mempool was full."
]
e@(ErrPostTxEraUnsupported unsupported) ->
apiError err403 error' $ toText e
where
error' =
UnsupportedEra
$ ApiErrorUnsupportedEra
{ unsupportedEra = toApiEra unsupported
, supportedEras =
Set.fromList
( toApiEra
. Write.toAnyCardanoEra
<$> [minBound .. maxBound]
)
}

instance IsServerError ErrSubmitTransaction where
toServerError = \case
Expand Down
15 changes: 15 additions & 0 deletions lib/api/src/Cardano/Wallet/Api/Types/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module Cardano.Wallet.Api.Types.Error
, ApiErrorNotEnoughMoneyShortfall (..)
, ApiErrorMissingWitnessesInTransaction (..)
, ApiErrorNoSuchPool (..)
, ApiErrorUnsupportedEra (..)
)
where

Expand Down Expand Up @@ -76,6 +77,9 @@ import Data.Data
import Data.Maybe
( fromMaybe
)
import Data.Set
( Set
)
import Data.Text
( Text
)
Expand Down Expand Up @@ -217,6 +221,7 @@ data ApiErrorInfo
| BlockHeaderNotFound
| TranslationByronTxOutInContext
| BalanceTxInlinePlutusV3ScriptNotSupportedInBabbage
| UnsupportedEra !ApiErrorUnsupportedEra

deriving (Eq, Generic, Show, Data, Typeable)
deriving anyclass NFData
Expand All @@ -235,6 +240,16 @@ apiErrorInfoOptions = defaultSumTypeOptions
}
}

data ApiErrorUnsupportedEra = ApiErrorUnsupportedEra
{ unsupportedEra :: !ApiEra
-- ^ The unsupported era (as specified by the caller).
, supportedEras :: !(Set ApiEra)
-- ^ The set of eras that we currently support.
}
deriving (Data, Eq, Generic, Show, Typeable)
deriving (FromJSON, ToJSON) via DefaultRecord ApiErrorUnsupportedEra
deriving anyclass NFData
paolino marked this conversation as resolved.
Show resolved Hide resolved

data ApiErrorSharedWalletNoSuchCosigner = ApiErrorSharedWalletNoSuchCosigner
{ cosignerIndex
:: !ApiCosignerIndex
Expand Down
14 changes: 11 additions & 3 deletions lib/network-layer/src/Cardano/Wallet/Network.hs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ import qualified Internal.Cardano.Write.Tx as Write
{-----------------------------------------------------------------------------
NetworkLayer
------------------------------------------------------------------------------}

paolino marked this conversation as resolved.
Show resolved Hide resolved
-- | Interface for network capabilities.
data NetworkLayer m block = NetworkLayer
{ chainSync
Expand Down Expand Up @@ -134,8 +135,7 @@ data NetworkLayer m block = NetworkLayer
-- only change once per epoch.
, currentProtocolParametersInRecentEras
:: m (MaybeInRecentEra Write.PParams)
-- ^ Get the last known protocol parameters for recent eras.

-- ^ Get the last known protocol parameters for recent eras.
, currentSlottingParameters
:: m SlottingParameters
-- ^ Get the last known slotting parameters. In principle, these can
Expand Down Expand Up @@ -193,6 +193,7 @@ instance Functor m => Functor (NetworkLayer m) where
{-----------------------------------------------------------------------------
ChainFollower
------------------------------------------------------------------------------}

-- | A collection of callbacks to use with the 'chainSync' function.
data ChainFollower m point tip blocks = ChainFollower
{ checkpointPolicy :: Integer -> CheckpointPolicy
Expand Down Expand Up @@ -275,14 +276,21 @@ mapChainFollower fpoint12 fpoint21 ftip fblocks cf =
-------------------------------------------------------------------------------}

-- | Error while trying to send a transaction
data ErrPostTx = ErrPostTxValidationError Text | ErrPostTxMempoolFull
data ErrPostTx
= ErrPostTxValidationError Text
| ErrPostTxMempoolFull
| ErrPostTxEraUnsupported AnyCardanoEra
deriving (Generic, Show, Eq)

instance ToText ErrPostTx where
toText = \case
ErrPostTxValidationError msg -> msg
ErrPostTxMempoolFull ->
"mempool was full and refused posted transaction"
ErrPostTxEraUnsupported unsupported ->
"Submitted transaction was in "
<> T.pack (show unsupported)
<> " era, which is not supported"

-- | Error while trying to retrieve a block
newtype ErrFetchBlock = ErrNoBlockAt Read.ChainPoint
Expand Down
18 changes: 11 additions & 7 deletions lib/network-layer/src/Cardano/Wallet/Network/Implementation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ import Cardano.Wallet.Primitive.Ledger.Byron
( byronCodecConfig
)
import Cardano.Wallet.Primitive.Ledger.Shelley
( nodeToClientVersions
( UnsealException (..)
, nodeToClientVersions
, toCardanoEra
, unsealShelleyTx
)
Expand Down Expand Up @@ -630,12 +631,15 @@ withNodeNetworkLayerBase
_postTx txSubmissionQueue readCurrentEra tx = do
liftIO $ traceWith tr $ MsgPostTx tx
preferredEra <- liftIO readCurrentEra
let cmd =
CmdSubmitTx . toConsensusGenTx
$ unsealShelleyTx preferredEra tx
liftIO (send txSubmissionQueue cmd) >>= \case
SubmitSuccess -> pure ()
SubmitFail e -> throwE $ ErrPostTxValidationError $ T.pack $ show e
case unsealShelleyTx preferredEra tx of
Left (UnsealedTxInUnsupportedEra era) ->
throwE $ ErrPostTxEraUnsupported era
Right tx' -> do
let cmd = CmdSubmitTx . toConsensusGenTx $ tx'
liftIO (send txSubmissionQueue cmd) >>= \case
SubmitSuccess -> pure ()
SubmitFail e ->
throwE $ ErrPostTxValidationError $ T.pack $ show e

_stakeDistribution queue coin = do
liftIO $ traceWith tr $ MsgWillQueryRewardsForStake coin
Expand Down
16 changes: 10 additions & 6 deletions lib/primitive/lib/Cardano/Wallet/Primitive/Ledger/Shelley.hs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ module Cardano.Wallet.Primitive.Ledger.Shelley
, interval0
, interval1
, numberOfTransactionsInBlock

-- * Errors
, UnsealException (..)
) where

import Prelude
Expand Down Expand Up @@ -1018,21 +1021,22 @@ rewardAccountFromAddress (W.Address bytes) = refToAccount . ref =<< parseAddr by
refToAccount (SL.StakeRefPtr _) = Nothing
refToAccount SL.StakeRefNull = Nothing

newtype UnsealException = UnsealedTxInUnsupportedEra AnyCardanoEra

-- | Converts 'SealedTx' to something that can be submitted with the
-- 'Cardano.Api' local tx submission client.
unsealShelleyTx
:: AnyCardanoEra
-- ^ Preferred latest era (see 'ideallyNoLaterThan')
-> W.SealedTx
-> TxInMode
-> Either UnsealException TxInMode
unsealShelleyTx era wtx = case W.cardanoTxIdeallyNoLaterThan era wtx of
Cardano.InAnyCardanoEra BabbageEra tx ->
TxInMode ShelleyBasedEraBabbage tx
Right $ TxInMode ShelleyBasedEraBabbage tx
Cardano.InAnyCardanoEra ConwayEra tx ->
TxInMode ShelleyBasedEraConway tx
_ -> error $
"unsealShelleyTx: Creating transactions in era " <> show era
<> " is not supported anymore."
Right $ TxInMode ShelleyBasedEraConway tx
Cardano.InAnyCardanoEra unsupportedEra _ ->
Left $ UnsealedTxInUnsupportedEra $ AnyCardanoEra unsupportedEra

instance (forall era. IsCardanoEra era => Show (thing era)) =>
Show (InAnyCardanoEra thing) where
Expand Down
5 changes: 5 additions & 0 deletions lib/unit/test/unit/Cardano/Wallet/Api/TypesSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ import Cardano.Wallet.Api.Types.Error
, ApiErrorNotEnoughMoneyShortfall (..)
, ApiErrorSharedWalletNoSuchCosigner (..)
, ApiErrorTxOutputLovelaceInsufficient (..)
, ApiErrorUnsupportedEra (..)
)
import Cardano.Wallet.Api.Types.RestorationMode
( ApiRestorationMode
Expand Down Expand Up @@ -2470,6 +2471,10 @@ instance Arbitrary ApiErrorMissingWitnessesInTransaction where
arbitrary = genericArbitrary
shrink = genericShrink

instance Arbitrary ApiErrorUnsupportedEra where
arbitrary = genericArbitrary
shrink = genericShrink

instance Arbitrary ApiErrorSharedWalletNoSuchCosigner where
arbitrary = genericArbitrary
shrink = genericShrink
Expand Down
21 changes: 21 additions & 0 deletions specifications/api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5557,6 +5557,26 @@ x-errBlockHeaderNotFound: &errBlockHeaderNotFound
type: string
enum: ['block_header_not_found']

x-errUnsupportedEra: &errUnsupportedEra
<<: *responsesErr
title: unsupported_era
properties:
message:
type: string
code:
type: string
enum: ['unsupported_era']
info:
type: object
required:
- unsupported_era
- supported_eras
properties:
unsupported_era: *ApiEra
supported_eras:
type: array
items: *ApiEra
paolino marked this conversation as resolved.
Show resolved Hide resolved

x-responsesErr400: &responsesErr400
400:
description: Bad Request
Expand Down Expand Up @@ -6015,6 +6035,7 @@ x-responsesPostTransaction: &responsesPostTransaction
- <<: *errTransactionIsTooBig
- <<: *errNoRootKey
- <<: *errWrongEncryptionPassphrase
- <<: *errUnsupportedEra
<<: *responsesErr404WalletNotFound
<<: *responsesErr406
<<: *responsesErr415UnsupportedMediaType
Expand Down
Loading