Skip to content

Commit

Permalink
Merge pull request #2433 from IntersectMBO/fix/1713-bug-inconsistent-…
Browse files Browse the repository at this point in the history
…voting-status-causing-re-vote-on-governance-actions

fix(#1713): fix inconsistent voting status
  • Loading branch information
MSzalowski authored Nov 29, 2024
2 parents 437cd48 + e68c943 commit 5d433b7
Show file tree
Hide file tree
Showing 15 changed files with 5,067 additions and 6,990 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ changes.
### Fixed

- Fix fetching voting power of newly registerd DRep [Issue 2407](https://github.com/IntersectMBO/govtool/issues/2407)
- Fix inconsistent voting status [Issue 1713](https://github.com/IntersectMBO/govtool/issues/1713)

### Changed

Expand Down
2 changes: 1 addition & 1 deletion govtool/backend/sql/get-network-metrics.sql
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ SELECT
total_gov_action_proposals.count as total_gov_action_proposals,
total_drep_votes.count as total_drep_votes,
total_registered_dreps.unique_registrations as total_registered_dreps,
total_stake_controlled_by_dreps.total as total_stake_controlled_by_dreps,
COALESCE(total_stake_controlled_by_dreps.total, 0) as total_stake_controlled_by_dreps,
total_active_dreps.unique_active_drep_registrations as total_active_dreps,
total_inactive_dreps.total_inactive_dreps as total_inactive_dreps,
total_active_cip119_compliant_dreps.unique_active_cip119_compliant_drep_registrations as total_active_cip119_compliant_dreps,
Expand Down
10 changes: 9 additions & 1 deletion govtool/backend/sql/get-transaction-status.sql
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
select exists (select * from tx where tx.hash = decode(?, 'hex'))
SELECT
EXISTS (SELECT 1 FROM tx WHERE tx.hash = decode(?, 'hex')) AS tx_exists,
COALESCE(
(SELECT json_agg(voting_procedure.*)
FROM voting_procedure
JOIN tx ON voting_procedure.tx_id = tx.id
WHERE tx.hash = decode(?, 'hex')
), '[]'::json
) AS voting_procedures;
12 changes: 6 additions & 6 deletions govtool/backend/src/VVA/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Control.Exception (throw, throwIO)
import Control.Monad.Except (runExceptT, throwError)
import Control.Monad.Reader

import Data.Aeson (Value(..), Array, decode, encode, FromJSON, ToJSON)
import Data.Aeson (Value(..), Array, decode, encode, FromJSON, ToJSON, toJSON)
import Data.Bool (Bool)
import Data.List (sortOn)
import qualified Data.Map as Map
Expand Down Expand Up @@ -416,11 +416,11 @@ getCurrentEpochParams = do

getTransactionStatus :: App m => HexText -> m GetTransactionStatusResponse
getTransactionStatus (unHexText -> transactionId) = do
x <- Transaction.getTransactionStatus transactionId
case x of
Types.TransactionConfirmed -> return $ GetTransactionStatusResponse True
Types.TransactionUnconfirmed -> return $ GetTransactionStatusResponse False

status <- Transaction.getTransactionStatus transactionId
return $ GetTransactionStatusResponse $ case status of
Just value -> Just $ toJSON value
Nothing -> Nothing
throw500 :: App m => m ()
throw500 = throwError $ CriticalError "intentional system break for testing purposes"

Expand Down
32 changes: 14 additions & 18 deletions govtool/backend/src/VVA/API/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -651,29 +651,26 @@ instance ToSchema GetProposalResponse where
?~ toJSON exampleGetProposalResponse

newtype GetTransactionStatusResponse
= GetTransactionStatusResponse { getTransactionstatusResponseTransactionConfirmed :: Bool }
deriving (Generic, Show)
= GetTransactionStatusResponse { getTransactionStatusResponse :: Maybe Value }
deriving newtype (Show)

instance FromJSON GetTransactionStatusResponse where
parseJSON = pure . GetTransactionStatusResponse . Just

deriveJSON (jsonOptions "getTransactionstatusResponse") ''GetTransactionStatusResponse
instance ToJSON GetTransactionStatusResponse where
toJSON (GetTransactionStatusResponse Nothing) = Null
toJSON (GetTransactionStatusResponse (Just status)) = toJSON status

exampleGetTransactionStatusResponse :: Text
exampleGetTransactionStatusResponse = "{ \"transactionConfirmed\": True }"
exampleGetTransactionStatusResponse =
"{ \"transactionConfirmed\": True, \"votingProcedure\": {\"vote\": \"yes\"}}"

instance ToSchema GetTransactionStatusResponse where
declareNamedSchema proxy = do
NamedSchema name_ schema_ <-
genericDeclareNamedSchema
( fromAesonOptions $
jsonOptions "getTransactionstatusResponse"
)
proxy
return $
NamedSchema name_ $
schema_
& description ?~ "GetTransactionStatus Response"
& example
?~ toJSON exampleGetTransactionStatusResponse
declareNamedSchema _ = pure $ NamedSchema (Just "GetTransactionStatusResponse") $ mempty
& type_ ?~ OpenApiObject
& description ?~ "Transaction status encoded as JSON"
& example
?~ toJSON exampleGetTransactionStatusResponse

newtype DRepHash
= DRepHash Text
Expand Down Expand Up @@ -923,4 +920,3 @@ instance ToSchema GetNetworkMetricsResponse where
& description ?~ "GetNetworkMetricsResponse"
& example
?~ toJSON exampleGetNetworkMetricsResponse

12 changes: 7 additions & 5 deletions govtool/backend/src/VVA/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import Data.Has (Has)
import Data.String (fromString)
import Data.Text (Text, pack, unpack)
import qualified Data.Text.Encoding as Text
import qualified Data.Text.IO as Text
import Data.Maybe (fromMaybe)

import qualified Database.PostgreSQL.Simple as SQL

Expand All @@ -31,10 +33,10 @@ getTransactionStatusSql = sqlFrom $(embedFile "sql/get-transaction-status.sql")
getTransactionStatus ::
(Has ConnectionPool r, Has VVAConfig r, MonadReader r m, MonadIO m, MonadError AppError m)
=> Text
-> m TransactionStatus
-> m (Maybe TransactionStatus)
getTransactionStatus transactionId = withPool $ \conn -> do
result <- liftIO $ SQL.query conn getTransactionStatusSql (SQL.Only transactionId)
result <- liftIO $ SQL.query conn getTransactionStatusSql (transactionId, transactionId)
case result of
[SQL.Only True] -> return TransactionConfirmed
[SQL.Only False] -> return TransactionUnconfirmed
x -> throwError $ CriticalError ("Expected exactly one result from get-transaction-status.sql but got " <> pack (show (length x)) <> " of them. This should never happen")
[(transactionConfirmed, votingProcedure)] -> do
return $ Just $ TransactionStatus transactionConfirmed votingProcedure
_ -> return Nothing
18 changes: 16 additions & 2 deletions govtool/backend/src/VVA/Types.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
Expand All @@ -14,7 +15,7 @@ import Control.Monad.Fail (MonadFail)
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Reader (MonadReader)

import Data.Aeson (Value)
import Data.Aeson (Value, ToJSON (..), object, (.=))
import qualified Data.Cache as Cache
import Data.Has
import Data.Pool (Pool)
Expand Down Expand Up @@ -184,7 +185,20 @@ instance FromRow Proposal where
<*> field
<*> field

data TransactionStatus = TransactionConfirmed | TransactionUnconfirmed
data TransactionStatus = TransactionStatus
{ transactionConfirmed :: Bool
, votingProcedure :: Maybe Value
}

instance FromRow TransactionStatus where
fromRow = TransactionStatus <$> field <*> field

instance ToJSON TransactionStatus where
toJSON TransactionStatus {transactionConfirmed, votingProcedure} =
object
[ "transactionConfirmed" .= transactionConfirmed
, "votingProcedure" .= votingProcedure
]

data CacheEnv
= CacheEnv
Expand Down
Loading

0 comments on commit 5d433b7

Please sign in to comment.