-
Notifications
You must be signed in to change notification settings - Fork 23
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
Add MuxError handling in FoldBlocksError #548
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,7 +43,9 @@ module Cardano.Api.LedgerState | |
, chainSyncClientPipelinedWithLedgerState | ||
|
||
-- * Ledger state conditions | ||
, LedgerStateCondition(..) | ||
, ConditionResult(..) | ||
, fromConditionResult | ||
, toConditionResult | ||
, foldEpochState | ||
|
||
-- * Errors | ||
|
@@ -166,6 +168,7 @@ import Ouroboros.Consensus.Storage.Serialisation | |
import Ouroboros.Consensus.TypeFamilyWrappers (WrapLedgerEvent (WrapLedgerEvent)) | ||
import Ouroboros.Network.Block (blockNo) | ||
import qualified Ouroboros.Network.Block | ||
import Ouroboros.Network.Mux (MuxError) | ||
import qualified Ouroboros.Network.Protocol.ChainSync.Client as CS | ||
import qualified Ouroboros.Network.Protocol.ChainSync.ClientPipelined as CSP | ||
import Ouroboros.Network.Protocol.ChainSync.PipelineDecision | ||
|
@@ -356,13 +359,15 @@ data FoldBlocksError | |
= FoldBlocksInitialLedgerStateError !InitialLedgerStateError | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also change the name of this type to something like |
||
| FoldBlocksApplyBlockError !LedgerStateError | ||
| FoldBlocksIOException !IOException | ||
| FoldBlocksMuxError !MuxError | ||
deriving Show | ||
|
||
instance Error FoldBlocksError where | ||
prettyError = \case | ||
FoldBlocksInitialLedgerStateError err -> prettyError err | ||
FoldBlocksApplyBlockError err -> "Failed when applying a block:" <+> prettyError err | ||
FoldBlocksIOException err -> "IOException:" <+> prettyException err | ||
FoldBlocksMuxError err -> "FoldBlocks error:" <+> prettyException err | ||
|
||
-- | Type that lets us decide whether to continue or stop | ||
-- the fold from within our accumulation function. | ||
|
@@ -406,7 +411,7 @@ foldBlocks | |
-- truncating the last k blocks before the node's tip. | ||
-> t m a | ||
-- ^ The final state | ||
foldBlocks nodeConfigFilePath socketPath validationMode state0 accumulate = handleIOExceptions $ do | ||
foldBlocks nodeConfigFilePath socketPath validationMode state0 accumulate = handleExceptions $ do | ||
-- NOTE this was originally implemented with a non-pipelined client then | ||
-- changed to a pipelined client for a modest speedup: | ||
-- * Non-pipelined: 1h 0m 19s | ||
|
@@ -1758,10 +1763,19 @@ constructGlobals sGen eInfo (Ledger.ProtVer majorPParamsVer _) = | |
|
||
-------------------------------------------------------------------------- | ||
|
||
data LedgerStateCondition | ||
= ConditionMet | ||
| ConditionNotMet | ||
deriving (Show, Eq) | ||
-- | Type isomorphic to bool, representing condition check result | ||
data ConditionResult | ||
= ConditionNotMet | ||
| ConditionMet | ||
deriving (Read, Show, Enum, Bounded, Ord, Eq) | ||
|
||
toConditionResult :: Bool -> ConditionResult | ||
toConditionResult False = ConditionNotMet | ||
toConditionResult True = ConditionMet | ||
|
||
fromConditionResult :: ConditionResult -> Bool | ||
fromConditionResult ConditionNotMet = False | ||
fromConditionResult ConditionMet = True | ||
|
||
data AnyNewEpochState where | ||
AnyNewEpochState | ||
|
@@ -1791,7 +1805,7 @@ foldEpochState | |
-> ( AnyNewEpochState | ||
-> SlotNo | ||
-> BlockNo | ||
-> StateT s IO LedgerStateCondition | ||
-> StateT s IO ConditionResult | ||
) | ||
-- ^ Condition you want to check against the new epoch state. | ||
-- | ||
|
@@ -1804,9 +1818,9 @@ foldEpochState | |
-- rollback. This is achieved by only calling the accumulator on states/blocks | ||
-- that are older than the security parameter, k. This has the side effect of | ||
-- truncating the last k blocks before the node's tip. | ||
-> t m (LedgerStateCondition, s) | ||
-> t m (ConditionResult, s) | ||
-- ^ The final state | ||
foldEpochState nodeConfigFilePath socketPath validationMode terminationEpoch initialResult checkCondition = handleIOExceptions $ do | ||
foldEpochState nodeConfigFilePath socketPath validationMode terminationEpoch initialResult checkCondition = handleExceptions $ do | ||
-- NOTE this was originally implemented with a non-pipelined client then | ||
-- changed to a pipelined client for a modest speedup: | ||
-- * Non-pipelined: 1h 0m 19s | ||
|
@@ -1858,7 +1872,7 @@ foldEpochState nodeConfigFilePath socketPath validationMode terminationEpoch ini | |
Nothing -> modifyError FoldBlocksIOException . liftIO $ readMVar stateMv | ||
where | ||
protocols :: () | ||
=> MVar (LedgerStateCondition, s) | ||
=> MVar (ConditionResult, s) | ||
-> IORef (Maybe LedgerStateError) | ||
-> Env | ||
-> LedgerState | ||
|
@@ -1874,7 +1888,7 @@ foldEpochState nodeConfigFilePath socketPath validationMode terminationEpoch ini | |
-- | Defines the client side of the chain sync protocol. | ||
chainSyncClient :: Word16 | ||
-- ^ The maximum number of concurrent requests. | ||
-> MVar (LedgerStateCondition, s) | ||
-> MVar (ConditionResult, s) | ||
-- ^ State accumulator. Written to on every block. | ||
-> IORef (Maybe LedgerStateError) | ||
-- ^ Resulting error if any. Written to once on protocol | ||
|
@@ -2002,5 +2016,11 @@ atTerminationEpoch terminationEpoch events = | |
, currentEpoch' >= terminationEpoch | ||
] | ||
|
||
handleIOExceptions :: MonadIOTransError FoldBlocksError t m => ExceptT FoldBlocksError IO a -> t m a | ||
handleIOExceptions = liftEither <=< liftIO . fmap (join . first FoldBlocksIOException) . try . runExceptT | ||
handleExceptions :: MonadIOTransError FoldBlocksError t m | ||
=> ExceptT FoldBlocksError IO a | ||
-> t m a | ||
handleExceptions = liftEither <=< liftIO . runExceptT . flip catches handlers | ||
where | ||
handlers = [ Handler $ throwError . FoldBlocksIOException | ||
, Handler $ throwError . FoldBlocksMuxError | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super satisfied with those names. Any suggestions are welcome here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For
fromConditionResult
you could call it:isConditionMet
orwasConditionMet
. FortoConditionResult
, I am not sure what could be better, one idea would be simplyconditionResult
, because it is kind of a smart constructor. OrconditionResultMet
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it doesn't look like it is being used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those names are fine to me. Explicit and not too long. I'd keep them 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're meant to be used in
cardano-testnet
if needed. Example usage:or
Not sure which one is more obvious. I think I'll stick to
toConditionResult
as it signals simple conversion.