Skip to content

Commit

Permalink
Return descriptive 503 when listing stake pools with uncomplete sync
Browse files Browse the repository at this point in the history
Wrt #1971
  • Loading branch information
hasufell committed Aug 31, 2020
1 parent ba42959 commit 543a44b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
10 changes: 10 additions & 0 deletions lib/core/src/Cardano/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ module Cardano.Wallet

-- * Logging
, WalletLog (..)

-- * Stake pool listing
, ErrListPools (..)
) where

import Prelude hiding
Expand Down Expand Up @@ -2316,6 +2319,13 @@ data ErrWithdrawalNotWorth
= ErrWithdrawalNotWorth
deriving (Generic, Eq, Show)

-- | Errors that can occur when trying to list stake pool.
data ErrListPools
= ErrListPoolsNetworkError ErrNetworkUnavailable
| ErrListPoolsPastHorizonException PastHorizonException
deriving (Show)


{-------------------------------------------------------------------------------
Utils
-------------------------------------------------------------------------------}
Expand Down
6 changes: 6 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ import Cardano.Wallet
, ErrImportAddress (..)
, ErrImportRandomAddress (..)
, ErrJoinStakePool (..)
, ErrListPools (..)
, ErrListTransactions (..)
, ErrListUTxOStatistics (..)
, ErrMkTx (..)
Expand Down Expand Up @@ -2480,6 +2481,11 @@ instance LiftHandler ErrWithdrawalNotWorth where
, "request."
]

instance LiftHandler ErrListPools where
handler = \case
ErrListPoolsNetworkError e -> handler e
ErrListPoolsPastHorizonException e -> handler e

instance LiftHandler (Request, ServerError) where
handler (req, err@(ServerError code _ body headers))
| not (isJSON body) = case code of
Expand Down
30 changes: 21 additions & 9 deletions lib/shelley/src/Cardano/Wallet/Shelley/Pools.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import Cardano.Pool.DB
( DBLayer (..), ErrPointAlreadyExists (..), readPoolLifeCycleStatus )
import Cardano.Pool.Metadata
( StakePoolMetadataFetchLog )
import Cardano.Wallet
( ErrListPools (..) )
import Cardano.Wallet.Api.Types
( ApiT (..) )
import Cardano.Wallet.Network
Expand All @@ -49,7 +51,7 @@ import Cardano.Wallet.Network
, follow
)
import Cardano.Wallet.Primitive.Slotting
( TimeInterpreter, firstSlotInEpoch, startTime )
( PastHorizonException (..), TimeInterpreter, firstSlotInEpoch, startTime )
import Cardano.Wallet.Primitive.Types
( ActiveSlotCoefficient (..)
, BlockHeader
Expand Down Expand Up @@ -84,16 +86,20 @@ import Cardano.Wallet.Unsafe
( unsafeMkPercentage )
import Control.Concurrent
( threadDelay )
import Control.Exception
( throwIO, try )
import Control.Monad
( forM, forM_, forever, when )
import Control.Monad.IO.Class
( liftIO )
import Control.Monad.Trans.Except
( ExceptT (..), runExceptT, withExceptT )
( ExceptT (..), mapExceptT, runExceptT, throwE, withExceptT )
import Control.Monad.Trans.State
( State, evalState, state )
import Control.Tracer
( Tracer, contramap, traceWith )
import Data.Bifunctor
( first )
import Data.Function
( (&) )
import Data.Generics.Internal.VL.Lens
Expand Down Expand Up @@ -155,7 +161,7 @@ data StakePoolLayer = StakePoolLayer
:: EpochNo
-- Exclude all pools that retired in or before this epoch.
-> Coin
-> ExceptT ErrNetworkUnavailable IO [Api.ApiStakePool]
-> ExceptT ErrListPools IO [Api.ApiStakePool]
}

newStakePoolLayer
Expand Down Expand Up @@ -184,17 +190,18 @@ newStakePoolLayer nl db@DBLayer {..} =
:: EpochNo
-- Exclude all pools that retired in or before this epoch.
-> Coin
-> ExceptT ErrNetworkUnavailable IO [Api.ApiStakePool]
-> ExceptT ErrListPools IO [Api.ApiStakePool]
_listPools currentEpoch userStake = do
tip <- withExceptT fromErrCurrentNodeTip $ currentNodeTip nl
rawLsqData <- stakeDistribution nl tip userStake
rawLsqData <- mapExceptT (fmap (first ErrListPoolsNetworkError))
$ stakeDistribution nl tip userStake
let lsqData = combineLsqData rawLsqData
dbData <- liftIO $ readPoolDbData db
seed <- liftIO $ atomically readSystemSeed
-- TODO:
-- Use a more efficient way of filtering out retired pools.
-- See: https://jira.iohk.io/projects/ADP/issues/ADP-383
liftIO $
r <- liftIO $ try $
sortByReward seed
. filter (not . poolIsRetired)
. map snd
Expand All @@ -204,11 +211,16 @@ newStakePoolLayer nl db@DBLayer {..} =
(nOpt rawLsqData)
lsqData
dbData
case r of
Left e@(PastHorizon{}) -> throwE (ErrListPoolsPastHorizonException e)
Right r' -> pure r'

where
fromErrCurrentNodeTip :: ErrCurrentNodeTip -> ErrNetworkUnavailable

fromErrCurrentNodeTip :: ErrCurrentNodeTip -> ErrListPools
fromErrCurrentNodeTip = \case
ErrCurrentNodeTipNetworkUnreachable e -> e
ErrCurrentNodeTipNotFound -> ErrNetworkUnreachable "tip not found"
ErrCurrentNodeTipNetworkUnreachable e -> ErrListPoolsNetworkError e
ErrCurrentNodeTipNotFound -> ErrListPoolsNetworkError $ ErrNetworkUnreachable "tip not found"

epochIsInFuture :: EpochNo -> Bool
epochIsInFuture = (> currentEpoch)
Expand Down

0 comments on commit 543a44b

Please sign in to comment.