content: -- | Issuers part of LRC DB.
  
  module Pos.DB.Lrc.Issuers
         ( IssuersStakes
           -- * Getters
         , getIssuersStakes
  
           -- * Operations
         , putIssuersStakes
  
           -- * Initialization
         , prepareLrcIssuers
         ) where
  
  import           Universum
  
  import           Pos.Binary.Class (serialize')
  import           Pos.Core.Common (Coin, StakeholderId)
  import           Pos.Core.Slotting (EpochIndex (..))
  import           Pos.DB.Class (MonadDB, MonadDBRead)
  import           Pos.DB.Error (DBError (DBMalformed))
  import           Pos.DB.Lrc.Common (getBi, putBi)
  import           Pos.Util.Util (maybeThrow)
  
  -- | The first value here is epoch for which this stake distribution is valid.
  -- The second one is total stake corresponding to that epoch.
  -- The third one is map which stores stake belonging to issuer of some block as
  -- per epoch from the first value.
  type IssuersStakes = HashMap StakeholderId Coin
  
  getIssuersStakes :: MonadDBRead m => EpochIndex -> m IssuersStakes
  getIssuersStakes epoch =
      maybeThrow (DBMalformed "Issuers part of LRC DB is not initialized") =<<
      getBi (issuersKey epoch)
  
  putIssuersStakes :: MonadDB m => EpochIndex -> IssuersStakes -> m ()
  putIssuersStakes epoch = putBi (issuersKey epoch)
  
  prepareLrcIssuers :: MonadDB m => Coin -> m ()
  prepareLrcIssuers _ =
      unlessM isInitialized $ putIssuersStakes (EpochIndex 0) mempty
  
  isInitialized :: MonadDB m => m Bool
  isInitialized = (isJust @IssuersStakes) <$> getBi (issuersKey $ EpochIndex 0)
  
  ----------------------------------------------------------------------------
  -- Keys
  ----------------------------------------------------------------------------
  
  issuersKey :: EpochIndex -> ByteString
  issuersKey = mappend "i/" . serialize'
  