@@ -9,20 +9,20 @@ module Cardano.DbTool.Report.StakeReward.History
9
9
import Cardano.Db
10
10
import Cardano.DbTool.Report.Display
11
11
12
+ import Control.Monad (join )
12
13
import Control.Monad.IO.Class (MonadIO )
13
14
import Control.Monad.Trans.Reader (ReaderT )
14
15
15
16
import qualified Data.List as List
16
- import Data.Maybe (fromMaybe , mapMaybe )
17
17
import Data.Text (Text )
18
18
import qualified Data.Text as Text
19
19
import qualified Data.Text.IO as Text
20
20
import Data.Time.Clock (UTCTime )
21
21
import Data.Word (Word64 )
22
22
23
- import Database.Esqueleto.Experimental (SqlBackend , Value (.. ), asc , from , innerJoin ,
24
- max_ , on , orderBy , select , table , type (:& ) ((:&) ), val , where_ , (<=.) , (==.) ,
25
- (^.) )
23
+ import Database.Esqueleto.Experimental (SqlBackend , Value (.. ), asc , desc , from ,
24
+ innerJoin , max_ , on , orderBy , select , table , type (:& ) ((:&) ), unSqlBackendKey ,
25
+ val , where_ , (<=.) , (==.) , (^.) )
26
26
27
27
import Text.Printf (printf )
28
28
@@ -49,52 +49,63 @@ data EpochReward = EpochReward
49
49
, erEpochNo :: ! Word64
50
50
, erDate :: ! UTCTime
51
51
, erAddress :: ! Text
52
+ , erPoolId :: ! Word64
53
+ , erPoolTicker :: ! Text
52
54
, erReward :: ! Ada
53
55
, erDelegated :: ! Ada
54
56
, erPercent :: ! Double
55
57
}
56
-
57
58
queryHistoryStakeRewards :: MonadIO m => Text -> ReaderT SqlBackend m [EpochReward ]
58
59
queryHistoryStakeRewards address = do
59
- maxEpoch <- queryMaxEpochRewardNo
60
+ maxEpoch <- queryLatestMemberRewardEpochNo
60
61
mapM queryReward =<< queryDelegation maxEpoch
61
62
where
62
63
queryDelegation
63
64
:: MonadIO m
64
- => Word64 -> ReaderT SqlBackend m [(StakeAddressId , Word64 , UTCTime , DbLovelace )]
65
+ => Word64 -> ReaderT SqlBackend m [(StakeAddressId , Word64 , UTCTime , DbLovelace , PoolHashId )]
65
66
queryDelegation maxEpoch = do
66
67
res <- select $ do
67
- (epoch :& es :& saddr) <-
68
- from $ table @ Epoch
69
- `innerJoin` table @ EpochStake
70
- `on` (\ (epoch :& es) -> epoch ^. EpochNo ==. es ^. EpochStakeEpochNo )
71
- `innerJoin` table @ StakeAddress
72
- `on` (\ (_epoch :& es :& saddr) -> saddr ^. StakeAddressId ==. es ^. EpochStakeAddrId )
73
- where_ (saddr ^. StakeAddressView ==. val address)
74
- where_ (es ^. EpochStakeEpochNo <=. val maxEpoch)
75
- pure (es ^. EpochStakeAddrId , es ^. EpochStakeEpochNo , epoch ^. EpochEndTime , es ^. EpochStakeAmount )
76
- pure $ map unValue4 res
68
+ (ep :& es :& saddr) <-
69
+ from $ table @ Epoch
70
+ `innerJoin` table @ EpochStake
71
+ `on` (\ (ep :& es) -> ep ^. EpochNo ==. es ^. EpochStakeEpochNo )
72
+ `innerJoin` table @ StakeAddress
73
+ `on` (\ (_ep :& es :& saddr) -> saddr ^. StakeAddressId ==. es ^. EpochStakeAddrId )
74
+ where_ (saddr ^. StakeAddressView ==. val address)
75
+ where_ (es ^. EpochStakeEpochNo <=. val maxEpoch)
76
+ pure (es ^. EpochStakeAddrId , es ^. EpochStakeEpochNo , ep ^. EpochEndTime
77
+ , es ^. EpochStakeAmount , es ^. EpochStakePoolId )
78
+ pure $ map unValue5 res
77
79
78
80
queryReward
79
81
:: MonadIO m
80
- => (StakeAddressId , Word64 , UTCTime , DbLovelace )
82
+ => (StakeAddressId , Word64 , UTCTime , DbLovelace , PoolHashId )
81
83
-> ReaderT SqlBackend m EpochReward
82
- queryReward (saId, en, date, DbLovelace delegated) = do
84
+ queryReward (saId, en, date, DbLovelace delegated, poolId ) = do
83
85
res <- select $ do
84
- ( saddr :& reward :& epoch) <-
85
- from $ table @ StakeAddress
86
- `innerJoin` table @ Reward
87
- `on` (\ (saddr :& reward) -> saddr ^. StakeAddressId ==. reward ^. RewardAddrId )
88
- `innerJoin` table @ Epoch
89
- `on` (\ (_saddr :& reward :& epoch) -> epoch ^. EpochNo ==. reward ^. RewardEarnedEpoch )
90
- where_ (epoch ^. EpochNo ==. val en)
91
- where_ (saddr ^. StakeAddressId ==. val saId)
92
- orderBy [asc (epoch ^. EpochNo )]
93
- pure (reward ^. RewardAmount )
86
+ (saddr :& rwd :& ep) <-
87
+ from $ table @ StakeAddress
88
+ `innerJoin` table @ Reward
89
+ `on` (\ (saddr :& rwd) -> saddr ^. StakeAddressId ==. rwd ^. RewardAddrId )
90
+ `innerJoin` table @ Epoch
91
+ `on` (\ (_saddr :& rwd :& ep) -> ep ^. EpochNo ==. rwd ^. RewardEarnedEpoch )
92
+ where_ (ep ^. EpochNo ==. val en)
93
+ where_ (saddr ^. StakeAddressId ==. val saId)
94
+ orderBy [asc (ep ^. EpochNo )]
95
+ pure (rwd ^. RewardAmount )
96
+
97
+ mtn <- select $ do
98
+ pod <- from $ table @ PoolOfflineData
99
+ where_ (pod ^. PoolOfflineDataPoolId ==. val poolId)
100
+ -- Use the `id` column as a proxy for time where larger `id` means later time.
101
+ orderBy [desc (pod ^. PoolOfflineDataId )]
102
+ pure (pod ^. PoolOfflineDataTickerName )
94
103
95
104
let reward = maybe 0 (unDbLovelace . unValue) (listToMaybe res)
96
105
pure $ EpochReward
97
106
{ erAddressId = saId
107
+ , erPoolId = fromIntegral $ unSqlBackendKey (unPoolHashKey poolId)
108
+ , erPoolTicker = maybe " ???" unValue (listToMaybe mtn)
98
109
, erEpochNo = en
99
110
, erDate = date
100
111
, erAddress = address
@@ -103,20 +114,22 @@ queryHistoryStakeRewards address = do
103
114
, erPercent = rewardPercent reward (if delegated == 0 then Nothing else Just delegated)
104
115
}
105
116
106
- queryMaxEpochRewardNo
107
- :: MonadIO m
108
- => ReaderT SqlBackend m Word64
109
- queryMaxEpochRewardNo = do
117
+ -- Find the latest epoch where member rewards have been distributed.
118
+ -- Can't use the Reward table for this because that table may have been partially
119
+ -- populated for the next epcoh.
120
+ queryLatestMemberRewardEpochNo :: MonadIO m => ReaderT SqlBackend m Word64
121
+ queryLatestMemberRewardEpochNo = do
110
122
res <- select $ do
111
- reward <- from $ table @ Reward
112
- pure (max_ (reward ^. RewardEarnedEpoch ))
113
- pure $ fromMaybe 0 (listToMaybe $ mapMaybe unValue res)
123
+ blk <- from $ table @ Block
124
+ where_ (isJust $ blk ^. BlockEpochNo )
125
+ pure $ max_ (blk ^. BlockEpochNo )
126
+ pure $ maybe 0 (pred . pred ) (join $ unValue =<< listToMaybe res)
114
127
115
128
renderRewards :: Text -> [EpochReward ] -> IO ()
116
129
renderRewards saddr xs = do
117
130
Text. putStrLn $ mconcat [ " \n Rewards for: " , saddr, " \n " ]
118
- putStrLn " epoch | reward_date | delegated | reward | RoS (%pa)"
119
- putStrLn " -------+-------------------------+----------------+--------------+-----------"
131
+ putStrLn " epoch | reward_date | delegated | pool_id | ticker | reward | RoS (%pa)"
132
+ putStrLn " -------+-------------------------+----------------+---------+--------+--------- -----+-----------"
120
133
mapM_ renderReward xs
121
134
putStrLn " "
122
135
where
@@ -129,6 +142,10 @@ renderRewards saddr xs = do
129
142
, separator
130
143
, leftPad 14 (renderAda (erDelegated er))
131
144
, separator
145
+ , leftPad 7 (textShow $ erPoolId er)
146
+ , separator
147
+ , rightPad 6 (erPoolTicker er)
148
+ , separator
132
149
, leftPad 12 (specialRenderAda (erReward er))
133
150
, separator
134
151
, Text. pack (if erPercent er == 0.0 then " 0.0" else printf " %8.3f" (erPercent er))
0 commit comments