Skip to content

Commit

Permalink
Merge #2977
Browse files Browse the repository at this point in the history
2977: Display serialised tx endpoint r=Anviking a=paweljakubas

<!--
Detail in a few bullet points the work accomplished in this PR.

Before you submit, don't forget to:

* Make sure the GitHub PR fields are correct:
   ✓ Set a good Title for your PR.
   ✓ Assign yourself to the PR.
   ✓ Assign one or more reviewer(s).
   ✓ Link to a Jira issue, and/or other GitHub issues or PRs.
   ✓ In the PR description delete any empty sections
     and all text commented in <!--, so that this text does not appear
     in merge commit messages.

* Don't waste reviewers' time:
   ✓ If it's a draft, select the Create Draft PR option.
   ✓ Self-review your changes to make sure nothing unexpected slipped through.

* Try to make your intent clear:
   ✓ Write a good Description that explains what this PR is meant to do.
   ✓ Jira will detect and link to this PR once created, but you can also
     link this PR in the description of the corresponding Jira ticket.
   ✓ Highlight what Testing you have done.
   ✓ Acknowledge any changes required to the Documentation.
-->

adp-974

- [x] swagger update
- [x] adding types
- [x] adding `decodeTransaction` in Server
- [x] add `lookupTxIns` in Wallet
- [x] add `lookupTxOuts` in Wallet
- [x] adjust unit testing
- [x] add integration tests for inputs/outputs/withdrawals/metadata

The endpoint acts in the context of a given wallet and is able to detect the wallet's resources. In detail, the enpdoint detects:
- id of tx
- fee
- inputs, belonging to other wallets and the wallets - in that case it lookups utxo and give amount and derivation path
- outputs, belonging to other wallets or to the wallets - in that case it either see its output or change (here it looks ahead using gap) and enrich info by current amount and derivation path of address
- withdrawals, belonging to other wallet or the wallet
- metadata
- script validity

### Comments

<!-- Additional comments, links, or screenshots to attach, if any. -->

### Issue Number

<!-- Reference the Jira/GitHub issue that this PR relates to, and which requirements it tackles.
  Note: Jira issues of the form ADP- will be auto-linked. -->


Co-authored-by: Pawel Jakubas <[email protected]>
Co-authored-by: Johannes Lund <[email protected]>
  • Loading branch information
3 people authored Nov 2, 2021
2 parents b9d8007 + f7977b8 commit c8cbdb8
Show file tree
Hide file tree
Showing 17 changed files with 13,708 additions and 174 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ module Test.Integration.Framework.TestData
, errMsg403TemplateInvalidDuplicateXPub
, errMsg403TemplateInvalidScript
, errMsg403InvalidConstructTx
, errMsg403transactionAlreadyBalanced
) where

import Prelude
Expand Down Expand Up @@ -622,10 +621,6 @@ errMsg400ScriptNotUniformRoles :: String
errMsg400ScriptNotUniformRoles =
"All keys of a script must have the same role: either payment or delegation."

errMsg403transactionAlreadyBalanced :: String
errMsg403transactionAlreadyBalanced =
"The transaction is already balanced. Please send a transaction that requires more inputs/outputs to be picked to be balanced."

--------------------------------------------------------------------------------
-- Transaction metadata
--------------------------------------------------------------------------------
Expand Down

Large diffs are not rendered by default.

61 changes: 56 additions & 5 deletions lib/core/src/Cardano/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,12 @@ module Cardano.Wallet
, importRandomAddresses
, listAddresses
, normalizeDelegationAddress
, lookupTxIns
, lookupTxOuts
, ErrCreateRandomAddress(..)
, ErrImportRandomAddress(..)
, ErrImportAddress(..)
, ErrDecodeTx (..)

-- ** Payment
, getTxExpiry
Expand Down Expand Up @@ -457,7 +460,7 @@ import Control.Monad.Trans.Except
import Control.Monad.Trans.Maybe
( MaybeT (..), maybeToExceptT )
import Control.Monad.Trans.State
( runState, state )
( evalState, runState, state )
import Control.Tracer
( Tracer, contramap, traceWith )
import Crypto.Hash
Expand Down Expand Up @@ -559,7 +562,6 @@ import qualified Data.Set as Set
import qualified Data.Text as T
import qualified Data.Vector as V


-- $Development
-- __Naming Conventions__
--
Expand Down Expand Up @@ -1169,6 +1171,52 @@ manageRewardBalance _ ctx wid = db & \DBLayer{..} -> do
Address
-------------------------------------------------------------------------------}

lookupTxIns
:: forall ctx s k .
( HasDBLayer IO s k ctx
, IsOurs s Address
)
=> ctx
-> WalletId
-> [TxIn]
-> ExceptT ErrDecodeTx IO [(TxIn, Maybe (TxOut, NonEmpty DerivationIndex))]
lookupTxIns ctx wid txins = db & \DBLayer{..} -> do
cp <- mapExceptT atomically
$ withExceptT ErrDecodeTxNoSuchWallet
$ withNoSuchWallet wid
$ readCheckpoint wid
pure $ map (\i -> (i, lookupTxIn cp i)) txins
where
db = ctx ^. dbLayer @IO @s @k
lookupTxIn :: Wallet s -> TxIn -> Maybe (TxOut, NonEmpty DerivationIndex)
lookupTxIn cp txIn = do
out@(TxOut addr _) <- UTxO.lookup txIn (totalUTxO mempty cp)
path <- fst $ isOurs addr (getState cp)
return (out, path)

lookupTxOuts
:: forall ctx s k .
( HasDBLayer IO s k ctx
, IsOurs s Address
)
=> ctx
-> WalletId
-> [TxOut]
-> ExceptT ErrDecodeTx IO [(TxOut, Maybe (NonEmpty DerivationIndex))]
lookupTxOuts ctx wid txouts = db & \DBLayer{..} -> do
cp <- mapExceptT atomically
$ withExceptT ErrDecodeTxNoSuchWallet
$ withNoSuchWallet wid
$ readCheckpoint wid
-- NOTE: We evolve the state (in practice an address pool) as we loop
-- through the outputs, but we don't consider pending transactions.
-- /Theoretically/ the outputs might only be discoverable after discovering
-- outputs other pending transactions.
pure $ flip evalState (getState cp) $ forM txouts $ \out@(TxOut addr _) -> do
(out,) <$> state (isOurs addr)
where
db = ctx ^. dbLayer @IO @s @k

-- | List all addresses of a wallet with their metadata. Addresses
-- are ordered from the most-recently-discovered to the oldest known.
listAddresses
Expand Down Expand Up @@ -2794,11 +2842,9 @@ data ErrSignPayment

-- | Errors that can occur when balancing transaction.
data ErrBalanceTx
= ErrBalanceTxTxAlreadyBalanced
| ErrBalanceTxUpdateError ErrUpdateSealedTx
= ErrBalanceTxUpdateError ErrUpdateSealedTx
| ErrBalanceTxSelectAssets ErrSelectAssets
| ErrBalanceTxAssignRedeemers ErrAssignRedeemers
| ErrBalanceTxNotImplemented
deriving (Show, Eq)

-- | Errors that can occur when constructing an unsigned transaction.
Expand All @@ -2825,6 +2871,11 @@ data ErrWitnessTx
| ErrWitnessTxIncorrectTTL PastHorizonException
deriving (Show, Eq)

-- | Errors that can occur when decoding a transaction.
newtype ErrDecodeTx
= ErrDecodeTxNoSuchWallet ErrNoSuchWallet
deriving (Show, Eq)

-- | Errors that can occur when submitting a signed transaction to the network.
data ErrSubmitTx
= ErrSubmitTxNetwork ErrPostTx
Expand Down
10 changes: 10 additions & 0 deletions lib/core/src/Cardano/Wallet/Api.hs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ module Cardano.Wallet.Api
, CreateTransactionOld
, PostTransactionFeeOld
, BalanceTransaction
, DecodeTransaction

, StakePools
, ListStakePools
Expand Down Expand Up @@ -177,6 +178,7 @@ import Cardano.Wallet.Api.Types
, ApiCoinSelectionT
, ApiConstructTransactionDataT
, ApiConstructTransactionT
, ApiDecodedTransactionT
, ApiFee
, ApiHealthCheck
, ApiMaintenanceAction
Expand Down Expand Up @@ -528,6 +530,7 @@ type ShelleyTransactions n =
:<|> CreateTransactionOld n
:<|> PostTransactionFeeOld n
:<|> BalanceTransaction n
:<|> DecodeTransaction n

-- | https://input-output-hk.github.io/cardano-wallet/api/#operation/constructTransaction
type ConstructTransaction n = "wallets"
Expand Down Expand Up @@ -588,6 +591,13 @@ type BalanceTransaction n = "wallets"
:> ReqBody '[JSON] (ApiBalanceTransactionPostDataT n)
:> PostAccepted '[JSON] ApiSerialisedTransaction

-- | https://input-output-hk.github.io/cardano-wallet/api/#operation/decodeTransaction
type DecodeTransaction n = "wallets"
:> Capture "walletId" (ApiT WalletId)
:> "transactions-decode"
:> ReqBody '[JSON] ApiSerialisedTransaction
:> PostAccepted '[JSON] (ApiDecodedTransactionT n)

{-------------------------------------------------------------------------------
Shelley Migrations
Expand Down
9 changes: 9 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import Cardano.Wallet.Api.Types
, ApiCoinSelectionT
, ApiConstructTransactionDataT
, ApiConstructTransactionT
, ApiDecodedTransactionT
, ApiFee
, ApiNetworkClock
, ApiNetworkInformation (..)
Expand Down Expand Up @@ -194,6 +195,10 @@ data TransactionClient = TransactionClient
:: ApiT WalletId
-> ApiBalanceTransactionPostDataT Aeson.Value
-> ClientM ApiSerialisedTransaction
, decodeTransaction
:: ApiT WalletId
-> ApiSerialisedTransaction
-> ClientM (ApiDecodedTransactionT Aeson.Value)
}

data AddressClient = AddressClient
Expand Down Expand Up @@ -310,6 +315,7 @@ transactionClient =
:<|> _postTransaction
:<|> _postTransactionFee
:<|> _balanceTransaction
:<|> _decodeTransaction
= client (Proxy @("v2" :> (ShelleyTransactions Aeson.Value)))

_postExternalTransaction
Expand All @@ -325,6 +331,7 @@ transactionClient =
, getTransaction = _getTransaction
, constructTransaction = _constructTransaction
, balanceTransaction = _balanceTransaction
, decodeTransaction = _decodeTransaction
}

fromSerialisedTx :: ApiBytesT base SerialisedTx -> ApiT SealedTx
Expand Down Expand Up @@ -357,6 +364,7 @@ byronTransactionClient =
, getTransaction = _getTransaction
, constructTransaction = _constructTransaction
, balanceTransaction = error "balance transaction endpoint not supported for byron"
, decodeTransaction = error "decode transaction endpoint not supported for byron"
}

-- | Produces an 'AddressClient n' working against the /wallets API
Expand Down Expand Up @@ -458,3 +466,4 @@ type instance PostTransactionOldDataT Aeson.Value = Aeson.Value
type instance PostTransactionFeeOldDataT Aeson.Value = Aeson.Value
type instance ApiPutAddressesDataT Aeson.Value = Aeson.Value
type instance ApiBalanceTransactionPostDataT Aeson.Value = Aeson.Value
type instance ApiDecodedTransactionT Aeson.Value = Aeson.Value
16 changes: 16 additions & 0 deletions lib/core/src/Cardano/Wallet/Api/Link.hs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ module Cardano.Wallet.Api.Link
, createUnsignedTransaction
, signTransaction
, balanceTransaction
, decodeTransaction

-- * StakePools
, listStakePools
Expand Down Expand Up @@ -681,6 +682,21 @@ balanceTransaction w = discriminate @style
where
wid = w ^. typed @(ApiT WalletId)

decodeTransaction
:: forall style w.
( HasCallStack
, HasType (ApiT WalletId) w
, Discriminate style
)
=> w
-> (Method, Text)
decodeTransaction w = discriminate @style
(endpoint @(Api.DecodeTransaction Net) (wid &))
(notSupported "Byron")
(notSupported "Shared")
where
wid = w ^. typed @(ApiT WalletId)

--
-- Stake Pools
--
Expand Down
Loading

0 comments on commit c8cbdb8

Please sign in to comment.