Skip to content

Commit

Permalink
Attach signer information to tx(s) endpoints (#152)
Browse files Browse the repository at this point in the history
This PR adds the `_txDetail_signers :: [Signer]` field to the `TxDetail` served by the `GET /txs/tx` and `GET /txs/txs` endpoints.

Additionally:
* It implements the necessary `ToSchema` types for the OAS3 spec.
* Adds a schema migration that swaps the order of the primary key columns of the `signers` table so that the primary key index supports efficient signer lookups.

* Swap the signers_pkey column order

This will allow us to join from transactions to their signers

* Add ToSchema Signer and SigCapability

* Point chainweb-api dependency to branch

* Attach signer information to TxDetail responses

* Specify explicit order for signers
  • Loading branch information
enobayram authored Jul 19, 2023
1 parent 815af93 commit a815997
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 5 deletions.
4 changes: 2 additions & 2 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ source-repository-package
source-repository-package
type: git
location: https://github.com/kadena-io/chainweb-api.git
tag: b3e28d62c622ebda0d84e136ea6c995d5f97e46f
--sha256: sha256-8Kclw75I8Jg/NAExfauoPRVJId1wfLGnO2lXXotNPdU=
tag: 9a62ce26c5d71343bcad17b4ef0d7c27bb536791
--sha256: sha256-qzS6oIJaTzeIHrUnQrV3gBvy5SvWQc8rujxpRvoXC3s=

source-repository-package
type: git
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE signers DROP CONSTRAINT signers_pkey;
ALTER TABLE cwd.signers ADD CONSTRAINT signers_pkey PRIMARY KEY (requestkey, idx);
32 changes: 29 additions & 3 deletions haskell-src/exec/Chainweb/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Control.Monad.Except
import qualified Control.Monad.Managed as M
import Control.Retry
import Data.Aeson hiding (Error)
import qualified Data.Aeson as A
import qualified Data.ByteString as BS
import qualified Data.ByteString.Base64.URL as B64
import Data.ByteString.Lazy (ByteString)
Expand Down Expand Up @@ -59,6 +60,7 @@ import Text.Printf
------------------------------------------------------------------------------
import Chainweb.Api.Common (BlockHeight)
import Chainweb.Api.StringEncoded (StringEncoded(..))
import qualified Chainweb.Api.Signer as Api
import Chainweb.Coins
import ChainwebDb.Database
import ChainwebDb.Queries
Expand All @@ -77,6 +79,7 @@ import ChainwebData.TxSummary
import ChainwebDb.Types.Block
import ChainwebDb.Types.Common
import ChainwebDb.Types.DbHash
import ChainwebDb.Types.Signer
import ChainwebDb.Types.Transfer
import ChainwebDb.Types.Transaction
import ChainwebDb.Types.Event
Expand Down Expand Up @@ -342,8 +345,14 @@ throw404 msg = throwError $ err404 { errBody = msg }
throw400 :: MonadError ServerError m => ByteString -> m a
throw400 msg = throwError $ err400 { errBody = msg }

toApiTxDetail :: Transaction -> ContinuationHistory -> Block -> [Event] -> TxDetail
toApiTxDetail tx contHist blk evs = TxDetail
toApiTxDetail ::
Transaction ->
ContinuationHistory ->
Block ->
[Event] ->
[Api.Signer] ->
TxDetail
toApiTxDetail tx contHist blk evs signers = TxDetail
{ _txDetail_ttl = fromIntegral $ _tx_ttl tx
, _txDetail_gasLimit = fromIntegral $ _tx_gasLimit tx
, _txDetail_gasPrice = _tx_gasPrice tx
Expand Down Expand Up @@ -373,6 +382,7 @@ toApiTxDetail tx contHist blk evs = TxDetail
, _txDetail_events = map toTxEvent evs
, _txDetail_initialCode = chCode contHist
, _txDetail_previousSteps = V.toList (chSteps contHist) <$ chCode contHist
, _txDetail_signers = signers
}
where
unMaybeValue = maybe Null unPgJsonb
Expand Down Expand Up @@ -405,7 +415,23 @@ queryTxsByKey logger rk c =
ev <- all_ (_cddb_events database)
guard_ (_ev_requestkey ev ==. val_ (RKCB_RequestKey $ DbHash rk))
return ev
return $ (`fmap` r) $ \(tx,contHist, blk) -> toApiTxDetail tx contHist blk evs
dbSigners <- runSelectReturningList $ select $ orderBy_ (asc_ . _signer_idx) $ do
signer <- all_ (_cddb_signers database)
guard_ (_signer_requestkey signer ==. val_ (DbHash rk))
return signer
signers <- forM dbSigners $ \s -> do
caps <- forM (unPgJsonb $ _signer_caps s) $ \capJson -> case fromJSON capJson of
A.Success a -> return a
A.Error e -> liftIO $ throwIO $ userError $ "Failed to parse signer capabilities: " <> e
return $ Api.Signer
{ Api._signer_addr = _signer_addr s
, Api._signer_scheme = _signer_scheme s
, Api._signer_pubKey = _signer_pubkey s
, Api._signer_capList = caps
}

return $ (`fmap` r) $ \(tx,contHist, blk) ->
toApiTxDetail tx contHist blk evs signers

queryTxsByPactId :: LogFunctionIO Text -> Limit -> Text -> Connection -> IO [TxSummary]
queryTxsByPactId logger limit pactid c =
Expand Down
29 changes: 29 additions & 0 deletions haskell-src/lib/ChainwebData/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedLists #-}

module ChainwebData.Spec where


import Control.Lens
import ChainwebData.Api

import qualified Data.Text as T
import Data.Proxy

import Data.OpenApi.ParamSchema
import Data.OpenApi.Schema
import Servant.OpenApi
import ChainwebData.Pagination
import Chainweb.Api.ChainId
import Chainweb.Api.Signer
import ChainwebData.TxSummary
import Data.OpenApi

Expand Down Expand Up @@ -71,6 +74,32 @@ instance ToSchema ChainwebDataStats where
declareNamedSchema = genericDeclareNamedSchema
defaultSchemaOptions{ fieldLabelModifier = drop 5 }

instance ToSchema Signer where
declareNamedSchema _ = do
textSchema <- declareSchemaRef (Proxy :: Proxy T.Text)
sigCapabilitySchema <- declareSchemaRef (Proxy :: Proxy [SigCapability])
return $ NamedSchema (Just "Signer") $ mempty
& type_ ?~ OpenApiObject
& properties
.~ [ ("addr", textSchema)
, ("scheme", textSchema)
, ("pubKey", textSchema)
, ("clist", sigCapabilitySchema)
]
& required .~ ["pubKey", "clist"]

instance ToSchema SigCapability where
declareNamedSchema _ = do
textSchema <- declareSchemaRef (Proxy :: Proxy T.Text)
valueSchema <- declareSchemaRef (Proxy :: Proxy [A.Value])
return $ NamedSchema (Just "SigCapability") $ mempty
& type_ ?~ OpenApiObject
& properties
.~ [ ("name", textSchema)
, ("args", valueSchema)
]
& required .~ ["name", "args"]

instance ToSchema (StringEncoded Scientific) where
declareNamedSchema _ = pure $ NamedSchema (Just "StringEncodedNumber") $ mempty
& type_ ?~ OpenApiString
Expand Down

0 comments on commit a815997

Please sign in to comment.