Skip to content

Commit

Permalink
PLT-8474: fix rest of new endpoints (#231)
Browse files Browse the repository at this point in the history
Signed-off-by: Ana Pantilie <[email protected]>
  • Loading branch information
ana-pantilie authored Nov 6, 2023
1 parent 22fa9a4 commit e5004fd
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 54 deletions.
1 change: 1 addition & 0 deletions marconi-chain-index/marconi-chain-index.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ library
build-depends:
, cardano-api ^>=8.20
, cardano-binary
, cardano-crypto-class
, cardano-ledger-alonzo >=1.3.1.1
, cardano-ledger-api
, cardano-ledger-babbage >=1.4.0.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ module Marconi.ChainIndex.Api.JsonRpc.Endpoint.EpochState (
RpcEpochActiveStakePoolDelegationMethod,
RpcEpochNonceMethod,
ActiveSDDResult (..),
EpochNonceResult (..),
getEpochNonceHandler,
getEpochStakePoolDelegationHandler,
nonceToMaybe,
) where

import Cardano.Api qualified as C
import Cardano.Api.Shelley qualified as C
import Cardano.Crypto.Hash qualified as Crypto
import Cardano.Ledger.Shelley.API qualified as Ledger
import Control.Lens.Getter qualified as Lens
import Data.Aeson.TH (defaultOptions, deriveJSON, fieldLabelModifier)
import Data.Char (toLower)
Expand Down Expand Up @@ -61,9 +65,28 @@ $( deriveJSON
type RpcEpochNonceMethod =
JsonRpc
"getNonceByEpoch"
EpochState.NonceByEpochNoQuery
Word64
String
(Core.Result EpochState.NonceByEpochNoQuery)
EpochNonceResult

data EpochNonceResult = EpochNonceResult
{ epochNonceBlockHeaderHash :: !(Maybe (C.Hash C.BlockHeader))
, epochNonceBlockNo :: !(Maybe C.BlockNo)
, epochNonceEpochNo :: !(Maybe C.EpochNo)
, epochNonceSlotNo :: !(Maybe C.SlotNo)
, epochNonceNonce :: !(Maybe (Crypto.Hash Crypto.Blake2b_256 Ledger.Nonce))
}
deriving stock (Eq, Ord, Show)

$( deriveJSON
defaultOptions
{ fieldLabelModifier = \str ->
case drop 10 str of
c : rest -> toLower c : rest
_ -> error "Malformed label in JSON type EpochNonceResult."
}
''EpochNonceResult
)

--------------
-- Handlers --
Expand Down Expand Up @@ -104,8 +127,34 @@ getEpochStakePoolDelegationHandler epochNo

-- | Return an epoch nonce
getEpochNonceHandler
:: EpochState.NonceByEpochNoQuery
:: Word64
-> ReaderHandler
HttpServerConfig
(Either (JsonRpcErr String) (Core.Result EpochState.NonceByEpochNoQuery))
getEpochNonceHandler = queryHttpReaderHandler (configQueryables . queryableEpochState)
(Either (JsonRpcErr String) EpochNonceResult)
getEpochNonceHandler epochNo
| epochNo < 0 =
return . Left . mkJsonRpcInvalidParamsErr . Just $
"The 'epochNo' param value must be a natural number."
| otherwise =
dimapHandler
toNonceByEpochNoQuery
toEpochNonceResult
(queryHttpReaderHandler (configQueryables . queryableEpochState))
epochNo
where
toNonceByEpochNoQuery :: Word64 -> EpochState.NonceByEpochNoQuery
toNonceByEpochNoQuery = EpochState.NonceByEpochNoQuery . C.EpochNo

toEpochNonceResult :: Core.Result EpochState.NonceByEpochNoQuery -> EpochNonceResult
toEpochNonceResult Nothing = EpochNonceResult Nothing Nothing Nothing Nothing Nothing
toEpochNonceResult (Just (Core.Timed chainPoint epochNonce)) =
EpochNonceResult
(Util.chainPointToHash chainPoint)
(Just $ Lens.view EpochState.nonceBlockNo epochNonce)
(Just $ Lens.view EpochState.nonceEpochNo epochNonce)
(Util.chainPointToSlotNo chainPoint)
(nonceToMaybe $ Lens.view EpochState.nonceNonce epochNonce)

nonceToMaybe :: Ledger.Nonce -> Maybe (Crypto.Hash Crypto.Blake2b_256 Ledger.Nonce)
nonceToMaybe Ledger.NeutralNonce = Nothing
nonceToMaybe (Ledger.Nonce hash) = Just hash
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module Marconi.ChainIndex.Indexers.EpochState (

-- * Queries
ActiveSDDByEpochNoQuery (..),
NonceByEpochNoQuery,
NonceByEpochNoQuery (..),
) where

import Cardano.Api qualified as C
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"blockHeaderHash": null,
"blockNo": null,
"epochNo": null,
"nonce": null,
"slotNo": null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"blockHeaderHash": "578f3cb70f4153e1622db792fea9005c80ff80f83df028210c7a914fb780a6f6",
"blockNo": 21645,
"epochNo": 2,
"nonce": null,
"slotNo": 1382422
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"_nonceBlockNo": 21645,
"_nonceEpochNo": 2,
"_nonceNonce": {
"contents": "ce4a80f49c44c21d7114d93fe5f992a2f9de6bad4a03a5df7e7403004ebe16fc",
"tag": "Nonce"
}
"blockHeaderHash": "578f3cb70f4153e1622db792fea9005c80ff80f83df028210c7a914fb780a6f6",
"blockNo": 21645,
"epochNo": 2,
"nonce": "ce4a80f49c44c21d7114d93fe5f992a2f9de6bad4a03a5df7e7403004ebe16fc",
"slotNo": 1382422
}
109 changes: 67 additions & 42 deletions marconi-chain-index/test/Spec/Marconi/ChainIndex/Api/Routes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Data.Aeson qualified as Aeson
import Data.Aeson.Encode.Pretty qualified as Aeson
import Data.ByteString.Lazy (ByteString)
import Data.Proxy (Proxy (Proxy))
import Data.Text (Text)
import Hedgehog (
Property,
forAll,
Expand All @@ -26,12 +27,13 @@ import Marconi.ChainIndex.Api.JsonRpc.Endpoint.CurrentSyncedBlock (
import Marconi.ChainIndex.Api.JsonRpc.Endpoint.CurrentSyncedBlock.Tip (Tip (Tip))
import Marconi.ChainIndex.Api.JsonRpc.Endpoint.EpochState (
ActiveSDDResult (ActiveSDDResult),
EpochNonceResult (EpochNonceResult),
nonceToMaybe,
)
import Marconi.ChainIndex.Api.JsonRpc.Endpoint.MintBurnToken (
BurnTokenEventResult (BurnTokenEventResult),
GetBurnTokenEventsResult (GetBurnTokenEventsResult),
)
import Marconi.ChainIndex.Indexers.EpochState (EpochNonce (EpochNonce))
import Spec.Marconi.ChainIndex.Api.Gen (
genBurnTokenEventResult,
genGetBurnTokenEventsParams,
Expand Down Expand Up @@ -88,6 +90,16 @@ tests =
(\expected actual -> ["diff", "--color=always", expected, actual])
"test/Spec/Golden/Routes/epoch-nonce-response.json"
goldenEpochNonceResult
, goldenVsStringDiff
"Golden test for EpochNonResult in JSON format"
(\expected actual -> ["diff", "--color=always", expected, actual])
"test/Spec/Golden/Routes/epoch-nonce-byron-response.json"
goldenEpochNonceByronResult
, goldenVsStringDiff
"Golden test for EpochNonResult in JSON format"
(\expected actual -> ["diff", "--color=always", expected, actual])
"test/Spec/Golden/Routes/epoch-nonce-at-genesis-response.json"
goldenEpochNonceAtGenesisResult
]
]

Expand Down Expand Up @@ -116,13 +128,7 @@ goldenCurrentChainPointResult = do
epochNo = C.EpochNo 6
blockNo = C.BlockNo 64903
blockTimestamp = 0
blockHeaderHash <-
either
(error . show)
pure
$ C.deserialiseFromRawBytesHex
(C.AsHash (C.proxyToAsType $ Proxy @C.BlockHeader))
blockHeaderHashRawBytes
blockHeaderHash <- getBlockHeaderHash blockHeaderHashRawBytes

pure $
Aeson.encodePretty $
Expand All @@ -138,20 +144,10 @@ goldenMintingPolicyHashTxResult :: IO ByteString
goldenMintingPolicyHashTxResult = do
let redeemerData = C.ScriptDataNumber 34
let txIdRawBytes = "ec7d3bd7c6a3a31368093b077af0db46ceac77956999eb842373e08c6420f000"
txId <-
either
(error . show)
pure
$ C.deserialiseFromRawBytesHex C.AsTxId txIdRawBytes
txId <- getTxIdHash txIdRawBytes

let blockHeaderHashRawBytes = "6161616161616161616161616161616161616161616161616161616161616161"
blockHeaderHash <-
either
(error . show)
pure
$ C.deserialiseFromRawBytesHex
(C.AsHash (C.proxyToAsType $ Proxy @C.BlockHeader))
blockHeaderHashRawBytes
blockHeaderHash <- getBlockHeaderHash blockHeaderHashRawBytes

let mints =
[ BurnTokenEventResult
Expand All @@ -171,24 +167,14 @@ goldenMintingPolicyHashTxResult = do
goldenEpochStakePoolDelegationResult :: IO ByteString
goldenEpochStakePoolDelegationResult = do
let blockHeaderHashRawBytes = "578f3cb70f4153e1622db792fea9005c80ff80f83df028210c7a914fb780a6f6"
blockHeaderHash <-
either
(error . show)
pure
$ C.deserialiseFromRawBytesHex
(C.AsHash (C.proxyToAsType $ Proxy @C.BlockHeader))
blockHeaderHashRawBytes
blockHeaderHash <- getBlockHeaderHash blockHeaderHashRawBytes

let poolIdsBech32 =
[ "pool1z22x50lqsrwent6en0llzzs9e577rx7n3mv9kfw7udwa2rf42fa"
, "pool1547tew8vmuj0g6vj3k5jfddudextcw6hsk2hwgg6pkhk7lwphe6"
, "pool174mw7e20768e8vj4fn8y6p536n8rkzswsapwtwn354dckpjqzr8"
]
poolIds <- forM poolIdsBech32 $ \poolIdBech32 -> do
either
(error . show)
pure
$ C.deserialiseFromBech32 (C.AsHash (C.proxyToAsType $ Proxy @CS.StakePoolKey)) poolIdBech32
poolIds <- getStakePoolHashes poolIdsBech32

let lovelace = C.Lovelace 100000000000000
slotNo = Just $ C.SlotNo 1382422
Expand All @@ -206,11 +192,7 @@ goldenEpochStakePoolDelegationAtGenesisResult = do
let poolIdsBech32 =
[ "pool1z22x50lqsrwent6en0llzzs9e577rx7n3mv9kfw7udwa2rf42fa"
]
poolIds <- forM poolIdsBech32 $ \poolIdBech32 -> do
either
(error . show)
pure
$ C.deserialiseFromBech32 (C.AsHash (C.proxyToAsType $ Proxy @CS.StakePoolKey)) poolIdBech32
poolIds <- getStakePoolHashes poolIdsBech32

let lovelace = C.Lovelace 100000000000000
slotNo = Nothing
Expand All @@ -230,11 +212,54 @@ goldenEpochNonceResult = do
Ledger.Nonce $
Crypto.castHash $
Crypto.hashWith id "162d29c4e1cf6b8a84f2d692e67a3ac6bc7851bc3e6e4afe64d15778bed8bd86"
epochNo = Just $ C.EpochNo 2
blockNo = Just $ C.BlockNo 21645
slotNo = Just $ C.SlotNo 1382422
blockHeaderHashRawBytes = "578f3cb70f4153e1622db792fea9005c80ff80f83df028210c7a914fb780a6f6"
blockHeaderHash <- getBlockHeaderHash blockHeaderHashRawBytes

let result =
EpochNonceResult (Just blockHeaderHash) blockNo epochNo slotNo (nonceToMaybe nonce)
pure $ Aeson.encodePretty result

goldenEpochNonceByronResult :: IO ByteString
goldenEpochNonceByronResult = do
let epochNo = Just $ C.EpochNo 2
blockNo = Just $ C.BlockNo 21645
slotNo = Just $ C.SlotNo 1382422
blockHeaderHashRawBytes = "578f3cb70f4153e1622db792fea9005c80ff80f83df028210c7a914fb780a6f6"
blockHeaderHash <- getBlockHeaderHash blockHeaderHashRawBytes

let result =
EpochNonceResult (Just blockHeaderHash) blockNo epochNo slotNo (nonceToMaybe Ledger.NeutralNonce)
pure $ Aeson.encodePretty result

goldenEpochNonceAtGenesisResult :: IO ByteString
goldenEpochNonceAtGenesisResult = do
let result =
Just $
EpochNonce
(C.EpochNo 2)
nonce
(C.BlockNo 21645)
EpochNonceResult Nothing Nothing Nothing Nothing (nonceToMaybe Ledger.NeutralNonce)
pure $ Aeson.encodePretty result

getBlockHeaderHash :: (Applicative f) => Crypto.ByteString -> f (CS.Hash CS.BlockHeader)
getBlockHeaderHash rawBytes =
either
(error . show)
pure
$ C.deserialiseFromRawBytesHex
(C.AsHash (C.proxyToAsType $ Proxy @C.BlockHeader))
rawBytes

getTxIdHash :: (Applicative f) => Crypto.ByteString -> f CS.TxId
getTxIdHash rawBytes =
either
(error . show)
pure
$ C.deserialiseFromRawBytesHex C.AsTxId rawBytes

getStakePoolHashes :: (Traversable t, Monad m) => t Text -> m (t (CS.Hash CS.StakePoolKey))
getStakePoolHashes poolIdsBech32 =
forM poolIdsBech32 $ \poolIdBech32 -> do
either
(error . show)
pure
$ C.deserialiseFromBech32 (C.AsHash (C.proxyToAsType $ Proxy @CS.StakePoolKey)) poolIdBech32

0 comments on commit e5004fd

Please sign in to comment.