Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit 66fe2e1

Browse files
committed
[CDEC-454] Remove usages of -fno-warn-orphans in update
Reunite orphan instances in update (where possible)
1 parent 4f9b394 commit 66fe2e1

File tree

8 files changed

+251
-308
lines changed

8 files changed

+251
-308
lines changed

core/src/Pos/Core/Update/SystemTag.hs

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ module Pos.Core.Update.SystemTag
1212
import Universum
1313

1414
import Control.Monad.Except (MonadError (throwError))
15+
import Data.Aeson (FromJSON (..))
16+
import Data.Aeson.Options (defaultOptions)
17+
import Data.Aeson.TH (deriveToJSON)
1518
import Data.Char (isAscii)
1619
import Data.SafeCopy (base, deriveSafeCopySimple)
1720
import qualified Data.Text as T
@@ -28,6 +31,11 @@ newtype SystemTag = SystemTag { getSystemTag :: Text }
2831

2932
instance NFData SystemTag
3033

34+
instance FromJSON SystemTag where
35+
parseJSON v = SystemTag <$> parseJSON v
36+
37+
deriveToJSON defaultOptions ''SystemTag
38+
3139
instance Bi SystemTag where
3240
encode = encode . getSystemTag
3341
decode = SystemTag <$> decode

update/cardano-sl-update.cabal

-5
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@ library
1717
exposed-modules:
1818
Pos.Update
1919

20-
-- Aeson
21-
Pos.Aeson.Update
22-
2320
Pos.Update.BlockVersion
2421

2522
-- Misc
@@ -38,9 +35,7 @@ library
3835
Pos.Update.Poll.Class
3936
Pos.Update.Poll.Modifier
4037
Pos.Update.Poll.PollState
41-
Pos.Update.Poll.Trans
4238
Pos.Update.Poll.Types
43-
Pos.Update.Poll.RollTrans
4439
Pos.Update.Poll.Failure
4540
Pos.Update.Poll.Pure
4641
Pos.Update.Poll.DBPoll

update/src/Pos/Aeson/Update.hs

-17
This file was deleted.

update/src/Pos/Update/Configuration.hs

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import Distribution.System (buildArch, buildOS)
2727

2828
-- For FromJSON instances.
2929
import Pos.Aeson.Core ()
30-
import Pos.Aeson.Update ()
3130
import Pos.Core (ApplicationName, BlockVersion (..),
3231
SoftwareVersion (..))
3332
import Pos.Core.Update (SystemTag (..), archHelper, osHelper)

update/src/Pos/Update/Poll.hs

-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ module Pos.Update.Poll
77
, module Pos.Update.Poll.Modifier
88
, module Pos.Update.Poll.PollState
99
, module Pos.Update.Poll.Pure
10-
, module Pos.Update.Poll.RollTrans
11-
, module Pos.Update.Poll.Trans
1210
, module Pos.Update.Poll.Types
1311
, module Pos.Update.Poll.Logic
1412
) where
@@ -20,6 +18,4 @@ import Pos.Update.Poll.Logic
2018
import Pos.Update.Poll.Modifier
2119
import Pos.Update.Poll.PollState
2220
import Pos.Update.Poll.Pure
23-
import Pos.Update.Poll.RollTrans
24-
import Pos.Update.Poll.Trans
2521
import Pos.Update.Poll.Types

update/src/Pos/Update/Poll/Class.hs

+243-6
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,55 @@
1+
{-# LANGUAGE Rank2Types #-}
12
{-# LANGUAGE TypeFamilies #-}
23

34
-- | Type classes for Poll abstraction.
45

56
module Pos.Update.Poll.Class
67
( MonadPollRead (..)
78
, MonadPoll (..)
9+
10+
-- Roll Transformer
11+
, RollT
12+
, runRollT
13+
, execRollT
14+
15+
-- Poll Transformer
16+
, PollT
17+
, runPollT
18+
, evalPollT
19+
, execPollT
820
) where
921

10-
import Universum
22+
import Universum hiding (id)
1123

24+
import Control.Lens (uses, (%=), (.=))
1225
import Control.Monad.Trans (MonadTrans)
13-
import System.Wlog (WithLogger)
26+
import Data.Default (def)
27+
import qualified Data.HashMap.Strict as HM
28+
import qualified Data.HashSet as HS
29+
import qualified Data.List as List (find)
30+
import qualified Ether
31+
import System.Wlog (WithLogger, logWarning)
1432

1533
import Pos.Core (ApplicationName, BlockVersion, BlockVersionData,
1634
ChainDifficulty, Coin, EpochIndex, NumSoftwareVersion,
17-
SlotId, SoftwareVersion, StakeholderId)
35+
SlotId, SoftwareVersion, StakeholderId, addressHash)
1836
import Pos.Core.Slotting (SlottingData)
19-
import Pos.Core.Update (UpId)
37+
import Pos.Core.Update (SoftwareVersion (..), UpId,
38+
UpdateProposal (..))
39+
import Pos.Crypto (hash)
40+
import Pos.Update.BlockVersion (applyBVM)
41+
import Pos.Update.Poll.Modifier (PollModifier (..), pmActivePropsL,
42+
pmAdoptedBVFullL, pmBVsL, pmConfirmedL, pmConfirmedPropsL,
43+
pmEpochProposersL, pmSlottingDataL)
2044
import Pos.Update.Poll.Types (BlockVersionState,
21-
ConfirmedProposalState, DecidedProposalState,
22-
ProposalState, UndecidedProposalState)
45+
BlockVersionState (..), ConfirmedProposalState,
46+
DecidedProposalState (..), PrevValue, ProposalState (..),
47+
USUndo (..), UndecidedProposalState (..), bvsIsConfirmed,
48+
cpsSoftwareVersion, maybeToPrev, psProposal, unChangedBVL,
49+
unChangedConfPropsL, unChangedPropsL, unChangedSVL,
50+
unLastAdoptedBVL, unPrevProposersL, unSlottingDataL)
51+
import qualified Pos.Util.Modifier as MM
52+
import Pos.Util.Util (ether)
2353

2454
----------------------------------------------------------------------------
2555
-- Read-only
@@ -137,3 +167,210 @@ instance {-# OVERLAPPABLE #-}
137167
deactivateProposal = lift . deactivateProposal
138168
setSlottingData = lift . setSlottingData
139169
setEpochProposers = lift . setEpochProposers
170+
171+
----------------------------------------------------------------------------
172+
-- Roll Transformer
173+
----------------------------------------------------------------------------
174+
175+
type RollT m = Ether.LazyStateT' USUndo m
176+
177+
-- | Monad transformer which stores USUndo and implements writable
178+
-- MonadPoll. Its purpose is to collect data necessary for rollback.
179+
--
180+
-- [WARNING] This transformer uses StateT and is intended for
181+
-- single-threaded usage only.
182+
instance (MonadPoll m) => MonadPoll (RollT m) where
183+
putBVState bv sv = ether $ do
184+
insertIfNotExist bv unChangedBVL getBVState
185+
putBVState bv sv
186+
187+
delBVState bv = ether $ do
188+
insertIfNotExist bv unChangedBVL getBVState
189+
delBVState bv
190+
191+
setAdoptedBV = setValueWrapper unLastAdoptedBVL getAdoptedBV setAdoptedBV
192+
193+
setLastConfirmedSV sv@SoftwareVersion{..} = ether $ do
194+
insertIfNotExist svAppName unChangedSVL getLastConfirmedSV
195+
setLastConfirmedSV sv
196+
197+
-- can't be called during apply
198+
delConfirmedSV = lift . delConfirmedSV
199+
200+
addConfirmedProposal cps = ether $ do
201+
confProps <- getConfirmedProposals
202+
insertIfNotExist (cpsSoftwareVersion cps) unChangedConfPropsL (getter confProps)
203+
addConfirmedProposal cps
204+
where
205+
getter confs sv = pure $ List.find (\x -> cpsSoftwareVersion x == sv) confs
206+
207+
-- can't be called during apply
208+
delConfirmedProposal = lift . delConfirmedProposal
209+
210+
insertActiveProposal ps = ether $ do
211+
whenNothingM_ (use unPrevProposersL) $ do
212+
prev <- getEpochProposers
213+
unPrevProposersL .= Just prev
214+
insertIfNotExist (hash $ psProposal $ ps) unChangedPropsL getProposal
215+
insertActiveProposal ps
216+
217+
deactivateProposal id = ether $ do
218+
-- Proposer still can't propose new updates in the current epoch
219+
-- even if his update was deactivated in the same epoch
220+
insertIfNotExist id unChangedPropsL getProposal
221+
deactivateProposal id
222+
223+
setSlottingData =
224+
setValueWrapper unSlottingDataL getSlottingData setSlottingData
225+
setEpochProposers =
226+
setValueWrapper unPrevProposersL getEpochProposers setEpochProposers
227+
228+
-- This is a convenient wrapper for functions which should set some
229+
-- value and this change should be recorded in USUndo. If change of
230+
-- such kind is already recorded in 'USUndo', then we don't record it
231+
-- and just propagate the new value to the underlying 'MonadPoll'. If
232+
-- it is not recorded, we put old value into 'USUndo' before
233+
-- propagating the new value.
234+
setValueWrapper ::
235+
MonadPoll m
236+
=> Lens' USUndo (Maybe a)
237+
-> m a
238+
-> (a -> m ())
239+
-> a
240+
-> RollT m ()
241+
setValueWrapper lens getAction setAction value = ether $ do
242+
whenNothingM_ (use lens) $ do
243+
prev <- lift getAction
244+
lens .= Just prev
245+
lift (setAction value)
246+
247+
insertIfNotExist
248+
:: (Eq a, Hashable a, MonadState USUndo m)
249+
=> a
250+
-> Lens' USUndo (HashMap a (PrevValue b))
251+
-> (a -> m (Maybe b))
252+
-> m ()
253+
insertIfNotExist id setter getter = do
254+
whenNothingM_ (HM.lookup id <$> use setter) $ do
255+
prev <- getter id
256+
setter %= HM.insert id (maybeToPrev prev)
257+
258+
runRollT :: RollT m a -> m (a, USUndo)
259+
runRollT = flip Ether.runLazyStateT def
260+
261+
execRollT :: Monad m => RollT m a -> m USUndo
262+
execRollT = flip Ether.execLazyStateT def
263+
264+
----------------------------------------------------------------------------
265+
-- PollT Transformer
266+
----------------------------------------------------------------------------
267+
268+
-- | Monad transformer which stores PollModifier and implements
269+
-- writable MonadPoll.
270+
--
271+
-- [WARNING] This transformer uses StateT and is intended for
272+
-- single-threaded usage only.
273+
type PollT = Ether.LazyStateT' PollModifier
274+
275+
runPollT :: PollModifier -> PollT m a -> m (a, PollModifier)
276+
runPollT = flip Ether.runLazyStateT
277+
278+
evalPollT :: Monad m => PollModifier -> PollT m a -> m a
279+
evalPollT = flip Ether.evalLazyStateT
280+
281+
execPollT :: Monad m => PollModifier -> PollT m a -> m PollModifier
282+
execPollT = flip Ether.execLazyStateT
283+
284+
instance (MonadPollRead m) =>
285+
MonadPollRead (PollT m) where
286+
getBVState pv = ether $
287+
MM.lookupM getBVState pv =<< use pmBVsL
288+
getProposedBVs = ether $
289+
MM.keysM getProposedBVs =<< use pmBVsL
290+
getEpochProposers = ether $ do
291+
new <- use pmEpochProposersL
292+
maybe getEpochProposers pure new
293+
getCompetingBVStates = ether $
294+
filter (bvsIsConfirmed . snd) <$>
295+
(MM.toListM getCompetingBVStates =<< use pmBVsL)
296+
getAdoptedBVFull = ether $
297+
maybe getAdoptedBVFull pure =<< use pmAdoptedBVFullL
298+
getLastConfirmedSV appName = ether $
299+
MM.lookupM getLastConfirmedSV appName =<< use pmConfirmedL
300+
getProposal upId = ether $
301+
MM.lookupM getProposal upId =<< use pmActivePropsL
302+
getProposalsByApp app = ether $ do
303+
let eqApp = (== app) . svAppName . upSoftwareVersion . psProposal . snd
304+
props <- uses pmActivePropsL (filter eqApp . MM.insertions)
305+
dbProps <- map (first (hash . psProposal) . join (,)) <$> getProposalsByApp app
306+
pure . toList . HM.fromList $ dbProps ++ props -- squash props with same upId
307+
getConfirmedProposals = ether $
308+
MM.valuesM
309+
(map (first cpsSoftwareVersion . join (,)) <$> getConfirmedProposals) =<<
310+
use pmConfirmedPropsL
311+
getEpochTotalStake = lift . getEpochTotalStake
312+
getRichmanStake e = lift . getRichmanStake e
313+
getOldProposals sl = ether $
314+
map snd <$>
315+
(MM.mapMaybeM getOldProposalPairs extractOld =<< use pmActivePropsL)
316+
where
317+
extractOld (PSUndecided ups)
318+
| upsSlot ups <= sl = Just ups
319+
| otherwise = Nothing
320+
extractOld (PSDecided _) = Nothing
321+
getOldProposalPairs =
322+
map (\ups -> (hash $ upsProposal ups, ups)) <$> getOldProposals sl
323+
getDeepProposals cd = ether $
324+
map snd <$>
325+
(MM.mapMaybeM getDeepProposalPairs extractDeep =<< use pmActivePropsL)
326+
where
327+
extractDeep (PSDecided dps)
328+
| Just propDifficulty <- dpsDifficulty dps
329+
, propDifficulty <= cd = Just dps
330+
| otherwise = Nothing
331+
extractDeep (PSUndecided _) = Nothing
332+
getDeepProposalPairs =
333+
map (\dps -> (hash $ upsProposal $ dpsUndecided dps, dps)) <$>
334+
getDeepProposals cd
335+
getBlockIssuerStake e = lift . getBlockIssuerStake e
336+
getSlottingData = ether $ do
337+
new <- gets pmSlottingData
338+
maybe getSlottingData pure new
339+
340+
{-# ANN module ("HLint: ignore Reduce duplication" :: Text) #-}
341+
342+
instance (MonadPollRead m) =>
343+
MonadPoll (PollT m) where
344+
putBVState bv st = ether $ pmBVsL %= MM.insert bv st
345+
delBVState bv = ether $ pmBVsL %= MM.delete bv
346+
setAdoptedBV bv = ether $ do
347+
bvs <- getBVState bv
348+
adoptedBVD <- getAdoptedBVData
349+
case bvs of
350+
Nothing ->
351+
logWarning $ "setAdoptedBV: unknown version " <> pretty bv -- can't happen actually
352+
Just (bvsModifier -> bvm) ->
353+
pmAdoptedBVFullL .= Just (bv, applyBVM bvm adoptedBVD)
354+
setLastConfirmedSV SoftwareVersion {..} = ether $
355+
pmConfirmedL %= MM.insert svAppName svNumber
356+
delConfirmedSV appName = ether $
357+
pmConfirmedL %= MM.delete appName
358+
addConfirmedProposal cps = ether $
359+
pmConfirmedPropsL %= MM.insert (cpsSoftwareVersion cps) cps
360+
delConfirmedProposal sv = ether $
361+
pmConfirmedPropsL %= MM.delete sv
362+
insertActiveProposal ps = do
363+
let up@UnsafeUpdateProposal{..} = psProposal ps
364+
upId = hash up
365+
whenNothingM_ (getProposal upId) $
366+
setEpochProposers =<< (HS.insert (addressHash upFrom) <$> getEpochProposers)
367+
ether $ pmActivePropsL %= MM.insert upId ps
368+
-- Deactivate proposal doesn't change epoch proposers.
369+
deactivateProposal id = do
370+
prop <- getProposal id
371+
whenJust prop $ \ps -> ether $ do
372+
let up = psProposal ps
373+
upId = hash up
374+
pmActivePropsL %= MM.delete upId
375+
setSlottingData sd = ether $ pmSlottingDataL .= Just sd
376+
setEpochProposers ep = ether $ pmEpochProposersL .= Just ep

0 commit comments

Comments
 (0)