Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,21 @@ changes.

### Removed

## [v2.0.18](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.18) 2025-03-20

## [v2.0.18](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.18) 2025-03-25

### Added

- Add redirection to outcomes when proposal is not found [Issue 3230](https://github.com/IntersectMBO/govtool/issues/3230)
- Add drep voting power list endpoint [Issue 3263](https://github.com/IntersectMBO/govtool/issues/3263)

### Fixed

- Fix post-vote navigation to governance action list [Issue 3242](https://github.com/IntersectMBO/govtool/issues/3242)

### Changed

- Bump CSL to v14 [Issue 3037](https://github.com/IntersectMBO/govtool/issues/3037)

### Removed

## [v2.0.17](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.17) 2025-03-18
Expand Down
2 changes: 2 additions & 0 deletions govtool/backend/app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ startApp vvaConfig sentryService = do
networkMetricsCache <- newCache
networkInfoCache <- newCache
networkTotalStakeCache <- newCache
dRepVotingPowerListCache <- newCache
return $ CacheEnv
{ proposalListCache
, getProposalCache
Expand All @@ -137,6 +138,7 @@ startApp vvaConfig sentryService = do
, networkMetricsCache
, networkInfoCache
, networkTotalStakeCache
, dRepVotingPowerListCache
}

let connectionString = encodeUtf8 (dbSyncConnectionString $ getter vvaConfig)
Expand Down
6 changes: 6 additions & 0 deletions govtool/backend/sql/get-dreps-voting-power-list.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
SELECT DISTINCT ON (raw)
view,
encode(raw, 'hex') AS hash_raw,
COALESCE(dd.amount, 0) AS voting_power
FROM drep_hash dh
LEFT JOIN drep_distr dd ON dh.id = dd.hash_id AND dd.epoch_no = (SELECT MAX(no) from epoch)
7 changes: 7 additions & 0 deletions govtool/backend/sql/get-filtered-dreps-voting-power.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
SELECT DISTINCT ON (raw)
view,
encode(raw, 'hex') AS hash_raw,
COALESCE(dd.amount, 0) AS voting_power
FROM drep_hash dh
LEFT JOIN drep_distr dd ON dh.id = dd.hash_id AND dd.epoch_no = (SELECT MAX(no) from epoch)
WHERE view = ? OR encode(raw, 'hex') = ?
24 changes: 23 additions & 1 deletion govtool/backend/src/VVA/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Control.Monad.Reader

import Data.Aeson (Value(..), Array, decode, encode, ToJSON, toJSON)
import Data.Bool (Bool)
import Data.List (sortOn)
import Data.List (sortOn, sort)
import qualified Data.Map as Map
import Data.Maybe (Maybe (Nothing), catMaybes, fromMaybe, mapMaybe)
import Data.Ord (Down (..))
Expand Down Expand Up @@ -64,6 +64,9 @@ type VVAApi =
:> QueryParam "search" Text
:> Get '[JSON] [VoteResponse]
:<|> "drep" :> "info" :> Capture "drepId" HexText :> Get '[JSON] DRepInfoResponse
:<|> "drep" :> "voting-power-list"
:> QueryParams "identifiers" Text
:> Get '[JSON] [DRepVotingPowerListResponse]
:<|> "ada-holder" :> "get-current-delegation" :> Capture "stakeKey" HexText :> Get '[JSON] (Maybe DelegationResponse)
:<|> "ada-holder" :> "get-voting-power" :> Capture "stakeKey" HexText :> Get '[JSON] Integer
:<|> "proposal" :> "list"
Expand All @@ -87,6 +90,7 @@ server = drepList
:<|> getVotingPower
:<|> getVotes
:<|> drepInfo
:<|> drepVotingPowerList
:<|> getCurrentDelegation
:<|> getStakeKeyVotingPower
:<|> listProposals
Expand Down Expand Up @@ -326,6 +330,24 @@ drepInfo (unHexText -> dRepId) = do
, dRepInfoResponseImageHash = HexText <$> dRepInfoImageHash
}

drepVotingPowerList :: App m => [Text] -> m [DRepVotingPowerListResponse]
drepVotingPowerList identifiers = do
CacheEnv {dRepVotingPowerListCache} <- asks vvaCache

let cacheKey = Text.intercalate "," (sort identifiers)

results <- cacheRequest dRepVotingPowerListCache cacheKey $
DRep.getDRepsVotingPowerList identifiers

return $ map toDRepVotingPowerListResponse results
where
toDRepVotingPowerListResponse Types.DRepVotingPowerList{..} =
DRepVotingPowerListResponse
{ drepVotingPowerListResponseView = drepView
, drepVotingPowerListResponseHashRaw = HexText drepHashRaw
, drepVotingPowerListResponseVotingPower = drepVotingPower
}

getCurrentDelegation :: App m => HexText -> m (Maybe DelegationResponse)
getCurrentDelegation (unHexText -> stakeKey) = do
CacheEnv {adaHolderGetCurrentDelegationCache} <- asks vvaCache
Expand Down
29 changes: 29 additions & 0 deletions govtool/backend/src/VVA/API/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,35 @@ instance ToSchema DRepInfoResponse where
& example
?~ toJSON exampleDRepInfoResponse

data DRepVotingPowerListResponse
= DRepVotingPowerListResponse
{ drepVotingPowerListResponseView :: Text
, drepVotingPowerListResponseHashRaw :: HexText
, drepVotingPowerListResponseVotingPower :: Integer
}
deriving (Generic, Show)

deriveJSON (jsonOptions "drepVotingPowerListResponse") ''DRepVotingPowerListResponse

exampleDRepVotingPowerListResponse :: Text
exampleDRepVotingPowerListResponse =
"{\"view\": \"drep1qq5n7k0r0ff6lf4qvndw9t7vmdqa9y3q9qtjq879rrk9vcjcdy8a4xf92mqsajf9u3nrsh3r6zrp29kuydmfq45fz88qpzmjkc\","
<> "\"hashRaw\": \"9af10e89979e51b8cdc827c963124a1ef4920d1253eef34a1d5cfe76438e3f11\","
<> "\"votingPower\": 1000000}"

instance ToSchema DRepVotingPowerListResponse where
declareNamedSchema proxy = do
NamedSchema name_ schema_ <-
genericDeclareNamedSchema
( fromAesonOptions $ jsonOptions "drepVotingPowerListResponse" )
proxy
return $
NamedSchema name_ $
schema_
& description ?~ "DRep Voting Power List Response"
& example
?~ toJSON exampleDRepVotingPowerListResponse

data GetProposalResponse
= GetProposalResponse
{ getProposalResponseVote :: Maybe VoteParams
Expand Down
62 changes: 45 additions & 17 deletions govtool/backend/src/VVA/DRep.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,33 @@

module VVA.DRep where

import Control.Monad.Except (MonadError)
import Control.Monad.Except (MonadError)
import Control.Monad.Reader

import Crypto.Hash

import Data.ByteString (ByteString)
import qualified Data.ByteString.Base16 as Base16
import qualified Data.ByteString.Char8 as C
import Data.FileEmbed (embedFile)
import Data.Foldable (Foldable (sum))
import Data.Has (Has)
import qualified Data.Map as M
import Data.Maybe (fromMaybe, isJust, isNothing)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Base16 as Base16
import qualified Data.ByteString.Char8 as C
import Data.FileEmbed (embedFile)
import Data.Foldable (Foldable (sum))
import Data.Has (Has)
import qualified Data.Map as M
import Data.Maybe (fromMaybe, isJust, isNothing)
import Data.Scientific
import Data.String (fromString)
import Data.Text (Text, pack, unpack)
import qualified Data.Text.Encoding as Text
import Data.String (fromString)
import Data.Text (Text, pack, unpack, intercalate)
import qualified Data.Text.Encoding as Text
import Data.Time

import qualified Database.PostgreSQL.Simple as SQL
import qualified Database.PostgreSQL.Simple as SQL
import Database.PostgreSQL.Simple.Types (In(..))

import VVA.Config
import VVA.Pool (ConnectionPool, withPool)
import qualified VVA.Proposal as Proposal
import VVA.Types (AppError, DRepInfo (..), DRepRegistration (..), DRepStatus (..),
DRepType (..), Proposal (..), Vote (..))
import VVA.Pool (ConnectionPool, withPool)
import qualified VVA.Proposal as Proposal
import VVA.Types (AppError, DRepInfo (..), DRepRegistration (..), DRepStatus (..),
DRepType (..), Proposal (..), Vote (..), DRepVotingPowerList (..))

sqlFrom :: ByteString -> SQL.Query
sqlFrom bs = fromString $ unpack $ Text.decodeUtf8 bs
Expand Down Expand Up @@ -198,3 +200,29 @@ getDRepInfo drepId = withPool $ \conn -> do
}
[] -> return $ DRepInfo False False False False False Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
_ -> error "Unexpected result from database query in getDRepInfo"

getAllDRepsVotingPowerSql :: SQL.Query
getAllDRepsVotingPowerSql = sqlFrom $(embedFile "sql/get-dreps-voting-power-list.sql")

getFilteredDRepVotingPowerSql :: SQL.Query
getFilteredDRepVotingPowerSql = sqlFrom $(embedFile "sql/get-filtered-dreps-voting-power.sql")

getDRepsVotingPowerList ::
(Has ConnectionPool r, Has VVAConfig r, MonadReader r m, MonadIO m) =>
[Text] ->
m [DRepVotingPowerList]
getDRepsVotingPowerList identifiers = withPool $ \conn -> do
results <- if null identifiers
then do
liftIO $ SQL.query_ conn getAllDRepsVotingPowerSql
else do
resultsPerIdentifier <- forM identifiers $ \identifier -> do
liftIO $ SQL.query conn getFilteredDRepVotingPowerSql (identifier, identifier)

return $ concat resultsPerIdentifier

return
[ DRepVotingPowerList view hashRaw votingPower
| (view, hashRaw, votingPower') <- results
, let votingPower = floor @Scientific votingPower'
]
9 changes: 9 additions & 0 deletions govtool/backend/src/VVA/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ data DRepInfo
, dRepInfoImageHash :: Maybe Text
}

data DRepVotingPowerList
= DRepVotingPowerList
{ drepView :: Text
, drepHashRaw :: Text
, drepVotingPower :: Integer
}
deriving (Show, Eq)

data DRepStatus = Active | Inactive | Retired deriving (Show, Eq, Ord)

data DRepType = DRep | SoleVoter deriving (Show, Eq)
Expand Down Expand Up @@ -216,6 +224,7 @@ data CacheEnv
, networkMetricsCache :: Cache.Cache () NetworkMetrics
, networkInfoCache :: Cache.Cache () NetworkInfo
, networkTotalStakeCache :: Cache.Cache () NetworkTotalStake
, dRepVotingPowerListCache :: Cache.Cache Text [DRepVotingPowerList]
}

data NetworkInfo
Expand Down
2 changes: 2 additions & 0 deletions govtool/backend/vva-be.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ extra-source-files:
sql/get-network-metrics.sql
sql/get-network-info.sql
sql/get-network-total-stake.sql
sql/get-dreps-voting-power-list.sql
sql/get-filtered-dreps-voting-power.sql
executable vva-be
main-is: Main.hs

Expand Down
36 changes: 23 additions & 13 deletions govtool/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions govtool/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@emurgo/cardano-serialization-lib-asmjs": "^12.1.1",
"@emurgo/cardano-serialization-lib-asmjs": "^14.1.1",
"@hookform/resolvers": "^3.3.1",
"@intersect.mbo/govtool-outcomes-pillar-ui": "1.2.5",
"@intersect.mbo/govtool-outcomes-pillar-ui": "1.3.0",
"@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8",
"@intersect.mbo/pdf-ui": "0.6.4",
"@mui/icons-material": "^5.14.3",
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/context/wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ const CardanoProvider = (props: Props) => {
.max_value_size(epochParams.max_val_size)
.max_tx_size(epochParams.max_tx_size)
.prefer_pure_change(true)
.do_not_burn_extra_change(true)
.ex_unit_prices(
ExUnitPrices.new(
UnitInterval.new(
Expand Down
Loading