Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conclude new tx workflow #3449

Merged
merged 15 commits into from
Sep 7, 2022
Merged

Conversation

paweljakubas
Copy link
Contributor

  • Removing byron things
  • Cleaning ApiAddressDestination
  • Foreign withdrawals not supported hence test removed
  • added support in constructTx, signTx and balanceTx for producing serialized tx in either hex or base64 (this one is default)
    We accept in decodeTx, signTx, balanceTx and submitTx both format and for the sake of comparison and interoperability
    (with for example cardano-cli) it seems like a good idea. The consequence: in each POST we have OPTIONAL
    "hex_output" field which is set to true means requesting hex-encoded output.
  • regenerated golden tests
  • added proof of operability in integration testing
  • updated swagger

Comments

Issue Number

adp-2083


instance ToJSON ApiSealedTxEncoding where
toJSON HexEncoded = Bool True
toJSON Base64Encoded = Bool False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
toJSON Base64Encoded = Bool False
toJSON Base64Encoded = Bool False

Comment on lines 1071 to 1086
newtype ApiSerialisedTransaction = ApiSerialisedTransaction
{ transaction :: ApiT SealedTx
{ transaction :: (ApiT SealedTx, ApiSealedTxEncoding)
} deriving stock (Eq, Generic, Show)
deriving anyclass (NFData)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data ApiSerialisedTransaction = ApiSerialisedTransaction
    { serialisedTxSealed :: ApiT SealedTx
    , serialisedTxEncoding :: ApiSealedTxEncoding
    } deriving stock (Eq, Generic, Show)
      deriving anyclass (NFData)

I find this representation more readable at call sites because of the names of the accessor functions, as opposed to meaningless fst / snd, example:
this line is less readable:

let bytes = serialisedTx $ getApiT $ fst $ (tx ^. #transaction)

than this one:

let bytes = serialisedTx $ getApiT $ serialisedTxSealed $ tx ^. #transaction

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds reasonable - done

@@ -1033,6 +1046,7 @@ data ApiValidityBound
data ApiSignTransactionPostData = ApiSignTransactionPostData
{ transaction :: !(ApiT SealedTx)
, passphrase :: !(ApiT (Passphrase "lenient"))
, hexOutput :: !(Maybe Bool)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

:-)

Suggested change
, hexOutput :: !(Maybe Bool)
, hexOutput :: !(Maybe !Bool)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the Just of the Maybe is another arrow if we care about this:

import Data.Maybe.Strict (StrictMaybe (..))
:set -XStrictData
data Foo f = Foo { foo :: f Int }
λ> let !a = foo $ Foo $ Just $ undefined
λ> let !a = foo $ Foo $ SJust $ undefined
*** Exception: Prelude.undefined
CallStack (from HasCallStack):
  error, called at libraries/base/GHC/Err.hs:79:14 in base:GHC.Err
  undefined, called at <interactive>:76:30 in interactive:Ghci18

Copy link
Member

@Anviking Anviking Aug 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this might be the same thing as what you said, except that hexOutput :: !(Maybe !Bool) isn't allowed?

λ> data Foo = Foo { foo :: !(Maybe (!Int)) }

<interactive>:83:34: error:
     Unexpected strictness annotation: !Int
      strictness annotation cannot appear nested inside a type
     In the first argument of Maybe, namely (!Int)
      In the type (Maybe (!Int))
      In the definition of data constructor Foo

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, your example demonstrates my point. StrictMaybe is the way.
https://hackage.haskell.org/package/strict-wrapper-0.0.0.0/docs/Data-Strict-Wrapper.html is interesting lib.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alas, I don't think that we need strict fields for our Api* data types, because these are intermediate types only used for carrying data across an interface.

If we want to control space usage, it does make sense to maintain space invariants on data types that are long-lived (such as UTxO), but that is not the case here.

@@ -1033,6 +1046,7 @@ data ApiValidityBound
data ApiSignTransactionPostData = ApiSignTransactionPostData
{ transaction :: !(ApiT SealedTx)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, ApiT isn't a strict container, so !(ApiT !SealedTx) makes more sense.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @HeinrichApfelmus explained, ApiT is declared as a newtype and those guys are strict by their nature. So my comment doesn't apply.

Comment on lines 982 to 984
parseJSON = withBool "ApiSealedTxEncoding" $ \b -> case b of
True -> pure HexEncoded
False -> pure Base64Encoded
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
parseJSON = withBool "ApiSealedTxEncoding" $ \b -> case b of
True -> pure HexEncoded
False -> pure Base64Encoded
parseJSON = withBool "ApiSealedTxEncoding" $
pure . bool Base64Encoded HexEncoded

?

Copy link
Contributor

@HeinrichApfelmus HeinrichApfelmus Aug 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to call the boolice on bool. 👮‍♂️

If you really want to get rid of the intermediate name b, I would prefer

parseJSON = withBool "ApiSealedTxEncoding" . pure $ \case
    True -> HexEncoded
    False -> Base64Encoded

The explicit True and False is useful as this is about converting a flag into a more value with more meaning attached to it, and it's not obvious which case is which.

Comment on lines 978 to 980
instance ToJSON ApiSealedTxEncoding where
toJSON HexEncoded = Bool True
toJSON Base64Encoded = Bool False
Copy link
Contributor

@Unisay Unisay Aug 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This instance means that ApiSealedTxEncoding is represented as Bool in the JSON.
I'd suggest to represent it as String with 2 possible values "base16" and "base64".
OpenAPI supports enum which is convenient in case like this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds like a good idea - done

Comment on lines 3568 to 3570
hex_output:
type: boolean
default: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hex_output:
type: boolean
default: false
encoding:
type: string
enum: ["base16", "base64"]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would agree with making this an enum.

@@ -2366,7 +2366,7 @@ submitTx
-> [(HTTP.Status, Either RequestException ApiTxId) -> m ()]
-> m ApiTxId
submitTx ctx tx expectations = do
let bytes = serialisedTx $ getApiT (tx ^. #transaction)
let bytes = serialisedTx $ getApiT $ fst $ (tx ^. #transaction)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let bytes = serialisedTx $ getApiT $ fst $ (tx ^. #transaction)
let bytes = serialisedTx $ getApiT $ fst $ tx ^. #transaction

and also fst is not telling me anything :(

@@ -317,7 +317,7 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do
Just m

let era = fromApiEra $ _mainEra ctx
let tx = cardanoTxIdeallyNoLaterThan era $ getApiT (signedTx ^. #transaction)
let tx = cardanoTxIdeallyNoLaterThan era $ getApiT (fst $ signedTx ^. #transaction)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let tx = cardanoTxIdeallyNoLaterThan era $ getApiT (fst $ signedTx ^. #transaction)
let tx = cardanoTxIdeallyNoLaterThan era $ getApiT $ fst $ signedTx ^. #transaction

@@ -384,7 +384,7 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do
Just m

let era = fromApiEra $ _mainEra ctx
let tx = cardanoTxIdeallyNoLaterThan era $ getApiT (signedTx ^. #transaction)
let tx = cardanoTxIdeallyNoLaterThan era $ getApiT (fst $ signedTx ^. #transaction)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let tx = cardanoTxIdeallyNoLaterThan era $ getApiT (fst $ signedTx ^. #transaction)
let tx = cardanoTxIdeallyNoLaterThan era $ getApiT $ fst $ signedTx ^. #transaction

@@ -2034,8 +2035,10 @@ signTransaction ctx (ApiT wid) body = do
-- TODO: The body+witnesses seem redundant with the sealedTx already. What's
-- the use-case for having them provided separately? In the end, the client
-- should be able to decouple them if they need to.
pure $ Api.ApiSerialisedTransaction
{ transaction = ApiT sealedTx'
pure $ ApiSerialisedTransaction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pure $ ApiSerialisedTransaction
pure ApiSerialisedTransaction

Copy link
Contributor

@HeinrichApfelmus HeinrichApfelmus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Pawel! 😊 Two main points:

  • Complete removal of the possibility to withdraw from external wallets (maybe in a follow-up pull request?)
  • Result type ApiConstructTransaction — I agree with Yura's suggestion of removing the pair in favor of an additional field. Choosing a short field name would limit the impact on integration tests.

Comment on lines -113 to -114
, ConstructByronTransaction
, SignByronTransaction
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@@ -540,58 +540,6 @@ spec = describe "NEW_SHELLEY_TRANSACTIONS" $ do
, expectField #withdrawals (`shouldSatisfy` (withdrawalWith External))
]

it "TRANS_NEW_CREATE_03b - Withdrawal from external wallet" $ \ctx -> runResourceT $ do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the end of this pull request, there seems to be a mismatch between implementation and documentation: 🤔 The swagger excludes the external withdrawals from the endpoint, but the ApiConstructTransactionData type still uses ApiWithdrawalPostData, which means that it will happily parse withdrawals to an external wallet.

Maybe going all the way of removing support is out of scope for this pull request, but I recommend doing it in a follow-up pull request, then.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I introduced ApiSelfWithdrawalPostData to address this in the current PR and adjusted all code and testing

data ApiConstructTransaction (n :: NetworkDiscriminant) = ApiConstructTransaction
{ transaction :: !(ApiT SealedTx)
{ transaction :: !(ApiT SealedTx, ApiSealedTxEncoding)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{ transaction :: !(ApiT SealedTx, ApiSealedTxEncoding)
{ transaction :: ApiSerialisedTransaction

I agree with Yura's comment on ApiSerialisedTransaction here.

The many pattern matches

         let (txCbor,_) = getFromResponse #transaction rTx

can be avoided in favor of extracting a subfield,

         let txCbor = getFromResponse (#transaction . #sealedTx) rTx

or something like that. One could even use Quantity, but I don't want to drag that type into this.

Comment on lines 3568 to 3570
hex_output:
type: boolean
default: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would agree with making this an enum.

@@ -1033,6 +1046,7 @@ data ApiValidityBound
data ApiSignTransactionPostData = ApiSignTransactionPostData
{ transaction :: !(ApiT SealedTx)
, passphrase :: !(ApiT (Passphrase "lenient"))
, hexOutput :: !(Maybe Bool)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alas, I don't think that we need strict fields for our Api* data types, because these are intermediate types only used for carrying data across an interface.

If we want to control space usage, it does make sense to maintain space invariants on data types that are long-lived (such as UTxO), but that is not the case here.

@paweljakubas paweljakubas force-pushed the paweljakubas/adp-2083/txflow-conclude branch from 752b5de to c52d97c Compare September 6, 2022 17:21
@paweljakubas paweljakubas force-pushed the paweljakubas/adp-2083/txflow-conclude branch from c52d97c to 3918890 Compare September 7, 2022 12:38
@paweljakubas
Copy link
Contributor Author

bors r+

iohk-bors bot added a commit that referenced this pull request Sep 7, 2022
3449: Conclude new tx workflow r=paweljakubas 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.
-->

- [x] Removing byron things
- [x] Cleaning ApiAddressDestination
- [x] Foreign withdrawals not supported hence test removed
- [x] added support in constructTx, signTx and balanceTx for producing serialized tx in either hex or base64 (this one is default)
       We accept in decodeTx, signTx, balanceTx and submitTx both format and for the sake of comparison and interoperability 
       (with for example cardano-cli) it seems like a good idea. The consequence: in each POST we have OPTIONAL 
       "hex_output" field which is set to true means requesting hex-encoded output. 
- [x] regenerated golden tests
- [x] added proof of operability in integration testing
- [x] updated swagger   

### Comments

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

### Issue Number
adp-2083

<!-- 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]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Sep 7, 2022

Build failed:

#expected hlint

@paweljakubas
Copy link
Contributor Author

bors r+

iohk-bors bot added a commit that referenced this pull request Sep 7, 2022
3449: Conclude new tx workflow r=paweljakubas 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.
-->

- [x] Removing byron things
- [x] Cleaning ApiAddressDestination
- [x] Foreign withdrawals not supported hence test removed
- [x] added support in constructTx, signTx and balanceTx for producing serialized tx in either hex or base64 (this one is default)
       We accept in decodeTx, signTx, balanceTx and submitTx both format and for the sake of comparison and interoperability 
       (with for example cardano-cli) it seems like a good idea. The consequence: in each POST we have OPTIONAL 
       "hex_output" field which is set to true means requesting hex-encoded output. 
- [x] regenerated golden tests
- [x] added proof of operability in integration testing
- [x] updated swagger   

### Comments

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

### Issue Number
adp-2083

<!-- 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]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Sep 7, 2022

Build failed:

                 ( Object
                     ( fromList
                         [
                             ( "code"
                             , String "bad_request"
                             )
                         ,
                             ( "message"
                             , String "Error in $: parsing ApiSerialisedTransaction object failed, expected Object, but encountered String"
                             )
                         ]
                     )
                 )
             )
         )
       expected: Status {
                   statusCode = 202,
                   statusMessage = "Accepted"
                 }
        but got: Status {
                   statusCode = 400,
                   statusMessage = "Bad Request"
                 }

  To rerun use: --match "/API Specifications/NEW_SHELLEY_TRANSACTIONS/Plutus scenarios/mint-burn/"

@paweljakubas
Copy link
Contributor Author

bors r+

iohk-bors bot added a commit that referenced this pull request Sep 7, 2022
3449: Conclude new tx workflow r=paweljakubas 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.
-->

- [x] Removing byron things
- [x] Cleaning ApiAddressDestination
- [x] Foreign withdrawals not supported hence test removed
- [x] added support in constructTx, signTx and balanceTx for producing serialized tx in either hex or base64 (this one is default)
       We accept in decodeTx, signTx, balanceTx and submitTx both format and for the sake of comparison and interoperability 
       (with for example cardano-cli) it seems like a good idea. The consequence: in each POST we have OPTIONAL 
       "hex_output" field which is set to true means requesting hex-encoded output. 
- [x] regenerated golden tests
- [x] added proof of operability in integration testing
- [x] updated swagger   

### Comments

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

### Issue Number
adp-2083

<!-- 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]>
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Sep 7, 2022

Build failed:

  src/Test/Integration/Scenario/CLI/Shelley/HWWallets.hs:100:5: 
  182) CLI Specifications, SHELLEY_CLI_HW_WALLETS, HW_WALLETS_01x - Restoration from account public key preserves funds
       uncaught exception: IOException of type UserError
       user error (No more faucet wallets of type shelley! You may need to manually add entries to the relevant list in lib/core-integration/src/Test/Integration/Faucet.hs)

  To rerun use: --match "/CLI Specifications/SHELLEY_CLI_HW_WALLETS/HW_WALLETS_01x - Restoration from account public key preserves funds/"

  src/Test/Integration/Scenario/CLI/Shelley/HWWallets.hs:158:9: 
  183) CLI Specifications, SHELLEY_CLI_HW_WALLETS, HW_WALLETS_03 - Cannot do operations requiring private key, Cannot send tx
       uncaught exception: IOException of type UserError
       user error (No more faucet wallets of type shelley! You may need to manually add entries to the relevant list in lib/core-integration/src/Test/Integration/Faucet.hs)

  To rerun use: --match "/CLI Specifications/SHELLEY_CLI_HW_WALLETS/HW_WALLETS_03 - Cannot do operations requiring private key/Cannot send tx/"

  src/Test/Integration/Scenario/CLI/Shelley/HWWallets.hs:223:9: 
  184) CLI Specifications, SHELLEY_CLI_HW_WALLETS, HW_WALLETS_04 - Can manage HW wallet the same way as others, Can get tx fee
       uncaught exception: IOException of type UserError
       user error (No more faucet wallets of type shelley! You may need to manually add entries to the relevant list in lib/core-integration/src/Test/Integration/Faucet.hs)

  To rerun use: --match "/CLI Specifications/SHELLEY_CLI_HW_WALLETS/HW_WALLETS_04 - Can manage HW wallet the same way as others/Can get tx fee/"

  src/Test/Integration/Scenario/CLI/Network.hs:60:18: 
  185) CLI Specifications, COMMON_CLI_NETWORK, CLI_NETWORK - cardano-wallet network information
       uncaught exception: ErrorCall
       Maybe.fromJust: Nothing
       CallStack (from HasCallStack):
         error, called at libraries/base/Data/Maybe.hs:148:21 in base:Data.Maybe
         fromJust, called at src/Test/Integration/Scenario/CLI/Network.hs:60:18 in cardano-wallet-core-integration-2022.8.16-9Nc58BLxxeemxV55PKwgZ:Test.Integration.Scenario.CLI.Network

  To rerun use: --match "/CLI Specifications/COMMON_CLI_NETWORK/CLI_NETWORK - cardano-wallet network information/"

Randomized with seed 955355607

Finished in 8011.4222 seconds, used 563.8291 seconds of CPU time
953 examples, 185 failures, 14 pending

Interesting...

Searching for "Applied {1,0}" it seems the pool worker saw blocks, but no wallet? 🥴

#3461

@paweljakubas
Copy link
Contributor Author

bors retry

@iohk-bors
Copy link
Contributor

iohk-bors bot commented Sep 7, 2022

Build succeeded:

@iohk-bors iohk-bors bot merged commit 583b6b3 into master Sep 7, 2022
@iohk-bors iohk-bors bot deleted the paweljakubas/adp-2083/txflow-conclude branch September 7, 2022 19:28
WilliamKingNoel-Bot pushed a commit that referenced this pull request Sep 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants